Skip to content

Commit de6de79

Browse files
jakubjanecekmergify[bot]
authored andcommitted
feat: micrometer-statsd (#43)
* WIP * feat: Implement micrometer-statsd module with PureConfig interop refactor: Make micrometer-jmx more configurable * refactor: Remove custom and unneeded datatypes that were just mirroring original types
1 parent bff1dda commit de6de79

File tree

8 files changed

+130
-8
lines changed

8 files changed

+130
-8
lines changed

build.sbt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ lazy val root = project
3232
jvmPureConfig,
3333
micrometerJmx,
3434
micrometerJmxPureConfig,
35+
micrometerStatsD,
3536
pureConfig
3637
)
3738
.settings(
@@ -171,6 +172,23 @@ lazy val micrometerJmxPureConfig = project
171172
.settings(commonSettings)
172173
.settings(name := "sst-micrometer-jmx-pureconfig")
173174

175+
lazy val micrometerStatsD = project
176+
.in(file("micrometer-statsd"))
177+
.settings(commonSettings)
178+
.settings(
179+
name := "sst-micrometer-statsd",
180+
libraryDependencies ++= Seq(
181+
Dependencies.micrometerStatsD,
182+
Dependencies.jsr305 // required because of Scala compiler
183+
)
184+
)
185+
186+
lazy val micrometerStatsDPureConfig = project
187+
.in(file("micrometer-statsd-pureconfig"))
188+
.dependsOn(micrometerStatsD, pureConfig)
189+
.settings(commonSettings)
190+
.settings(name := "sst-micrometer-statsd-pureconfig")
191+
174192
lazy val pureConfig = project
175193
.in(file("pureconfig"))
176194
.settings(commonSettings)
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
package com.avast.sst.micrometer.jmx
22

3-
final case class MicrometerJmxConfig(domain: String, enableTypeScopeNameHierarchy: Boolean = false)
3+
import java.util.concurrent.TimeUnit
4+
5+
import scala.concurrent.duration.Duration
6+
7+
final case class MicrometerJmxConfig(domain: String,
8+
enableTypeScopeNameHierarchy: Boolean = false,
9+
step: Duration = Duration(1, TimeUnit.MINUTES))

micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/MicrometerJmxModule.scala

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.avast.sst.micrometer.jmx
22

3+
import java.time.Duration
4+
35
import cats.effect.{Resource, Sync}
46
import com.codahale.metrics.MetricRegistry
57
import com.codahale.metrics.jmx.JmxReporter
@@ -14,23 +16,25 @@ object MicrometerJmxModule {
1416

1517
/** Makes configured [[io.micrometer.jmx.JmxMeterRegistry]]. */
1618
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
17-
def make[F[_]: Sync](config: MicrometerJmxConfig): Resource[F, JmxMeterRegistry] = {
19+
def make[F[_]: Sync](config: MicrometerJmxConfig,
20+
clock: Clock = Clock.SYSTEM,
21+
nameMapper: HierarchicalNameMapper = HierarchicalNameMapper.DEFAULT): Resource[F, JmxMeterRegistry] = {
1822
Resource
1923
.make {
2024
Sync[F].delay {
2125
if (config.enableTypeScopeNameHierarchy) {
2226
val dropwizardRegistry = new MetricRegistry
2327
val registry = new JmxMeterRegistry(
24-
new DomainJmxConfig(config.domain),
25-
Clock.SYSTEM,
26-
HierarchicalNameMapper.DEFAULT,
28+
new CustomJmxConfig(config),
29+
clock,
30+
nameMapper,
2731
dropwizardRegistry,
2832
makeJmxReporter(dropwizardRegistry, config.domain)
2933
)
3034
registry.config.namingConvention(NamingConvention.dot)
3135
registry
3236
} else {
33-
new JmxMeterRegistry(new DomainJmxConfig(config.domain), Clock.SYSTEM)
37+
new JmxMeterRegistry(new CustomJmxConfig(config), clock, nameMapper)
3438
}
3539
}
3640
}(registry => Sync[F].delay(registry.close()))
@@ -44,9 +48,12 @@ object MicrometerJmxModule {
4448
.build
4549
}
4650

47-
private class DomainJmxConfig(override val domain: String) extends JmxConfig {
51+
private class CustomJmxConfig(c: MicrometerJmxConfig) extends JmxConfig {
52+
53+
override val domain: String = c.domain
54+
override val step: Duration = Duration.ofMillis(c.step.toMillis)
4855

49-
// implements MeterRegistryConfig.get which can return null according to JavaDoc and @Nullable annotation
56+
// the method is @Nullable and we don't need to implement it here
5057
@SuppressWarnings(Array("org.wartremover.warts.Null"))
5158
override def get(key: String): String = null
5259

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.avast.sst.micrometer.statsd.pureconfig
2+
3+
import com.avast.sst.micrometer.statsd.MicrometerStatsDConfig
4+
import pureconfig.ConfigReader
5+
import pureconfig.generic.semiauto.deriveReader
6+
7+
trait ConfigReaders {
8+
9+
implicit val micrometerStatsDConfigReader: ConfigReader[MicrometerStatsDConfig] = deriveReader
10+
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.avast.sst.micrometer.statsd.pureconfig
2+
3+
object implicits extends ConfigReaders
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.avast.sst.micrometer.statsd
2+
3+
import java.util.concurrent.TimeUnit
4+
5+
import io.micrometer.statsd.{StatsdFlavor, StatsdProtocol}
6+
7+
import scala.concurrent.duration.Duration
8+
9+
final case class MicrometerStatsDConfig(host: String,
10+
port: Int = 8125,
11+
flavor: StatsdFlavor = StatsdFlavor.ETSY,
12+
enabled: Boolean = true,
13+
protocol: StatsdProtocol = StatsdProtocol.UDP,
14+
maxPacketLength: Int = 1400,
15+
pollingFrequency: Duration = Duration(10, TimeUnit.SECONDS),
16+
step: Duration = Duration(1, TimeUnit.MINUTES),
17+
publishUnchangedMeters: Boolean = true,
18+
buffered: Boolean = true)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.avast.sst.micrometer.statsd
2+
3+
import java.time.Duration
4+
5+
import cats.effect.{Resource, Sync}
6+
import io.micrometer.core.instrument.Clock
7+
import io.micrometer.core.instrument.util.HierarchicalNameMapper
8+
import io.micrometer.statsd.{StatsdConfig, StatsdFlavor, StatsdMeterRegistry, StatsdProtocol}
9+
10+
import scala.language.higherKinds
11+
12+
object MicrometerStatsDModule {
13+
14+
/** Makes configured [[io.micrometer.statsd.StatsdMeterRegistry]]. */
15+
def make[F[_]: Sync](config: MicrometerStatsDConfig,
16+
clock: Clock = Clock.SYSTEM,
17+
nameMapper: HierarchicalNameMapper = HierarchicalNameMapper.DEFAULT): Resource[F, StatsdMeterRegistry] = {
18+
Resource
19+
.make {
20+
Sync[F].delay {
21+
StatsdMeterRegistry
22+
.builder(new CustomStatsdConfig(config))
23+
.clock(clock)
24+
.nameMapper(nameMapper)
25+
.build
26+
}
27+
}(registry => Sync[F].delay(registry.close()))
28+
}
29+
30+
private class CustomStatsdConfig(c: MicrometerStatsDConfig) extends StatsdConfig {
31+
32+
override val flavor: StatsdFlavor = c.flavor
33+
34+
override val enabled: Boolean = c.enabled
35+
36+
override val host: String = c.host
37+
38+
override val port: Int = c.port
39+
40+
override val protocol: StatsdProtocol = c.protocol
41+
42+
override val maxPacketLength: Int = c.maxPacketLength
43+
44+
override val pollingFrequency: Duration = java.time.Duration.ofMillis(c.pollingFrequency.toMillis)
45+
46+
override val step: Duration = java.time.Duration.ofMillis(c.step.toMillis)
47+
48+
override val publishUnchangedMeters: Boolean = c.publishUnchangedMeters
49+
50+
override val buffered: Boolean = c.buffered
51+
52+
// the method is @Nullable and we don't need to implement it here
53+
@SuppressWarnings(Array("org.wartremover.warts.Null"))
54+
override def get(key: String): String = null
55+
56+
}
57+
58+
}

project/Dependencies.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ object Dependencies {
1212
val logbackClassic = "ch.qos.logback" % "logback-classic" % "1.2.3"
1313
val micrometerCore = "io.micrometer" % "micrometer-core" % Versions.micrometer
1414
val micrometerJmx = "io.micrometer" % "micrometer-registry-jmx" % Versions.micrometer
15+
val micrometerStatsD = "io.micrometer" % "micrometer-registry-statsd" % Versions.micrometer
1516
val monixEval = "io.monix" %% "monix-eval" % "3.0.0"
1617
val pureConfig = "com.github.pureconfig" %% "pureconfig" % "0.12.1"
1718
val scalaTest = "org.scalatest" %% "scalatest" % "3.0.8"

0 commit comments

Comments
 (0)