DataDog setup with Spring Boot (Kotlin)
The following article shows and explains how to setup DataDog for custom metrics in Spring Boot, using Gradle and Kotlin.
Dependencies
First we need to add dependencies to our Gradle build file:
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("io.micrometer:micrometer-registry-statsd:latest.release")
implementation("org.springframework:spring-aspects")
Why we need each dependency:
Spring Boot Actuator provides dependency management and auto-configuration for Micrometer, which is an application metrics facade
Micrometer dependency to get the metrics to DataDog through StatsD
Spring Aspects to enable @Timed
, @Counted
, @MeterTag
and @NewSpan
annotations
- https://docs.micrometer.io/micrometer/reference/concepts/counters.html
- https://docs.micrometer.io/micrometer/reference/concepts/timers.html#_the_timed_annotation
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.observability.annotations
Local setup (for macOS)
- Open https://<yourdomain>.datadoghq.com/account/settings/agent/latest?platform=macos
- Create API key if one is not created for your product
- Follow instructions to install the DataDog agent locally.
It is useful to have it running locally when you are setting it up, and also when developing new application (custom) metrics
Configuration
Everything is configured by automatically by Spring Boot, we only need to do few things to make life easier.
Enable annotations
In your application.properties
or application.yml
, enable the annotations (e.g. @Counted
, @Timed
).
management.observations.annotations.enabled=true
Provide Spring config
Now we need to configure the beans to add custom tags to each metric.
import io.micrometer.core.aop.TimedAspect
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics
import io.micrometer.core.instrument.config.NamingConvention
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.env.Environment
@Configuration(proxyBeanMethods = false)
class MetricsConfig {
@Bean
fun metricsCommonTags(env: Environment): MeterRegistryCustomizer<MeterRegistry> {
val currentEnvironment = env.getProperty("spring.profiles.active")
return MeterRegistryCustomizer { registry ->
registry
.config()
.commonTags(
Tags.of(
Tag.of("env", currentEnvironment ?: "local"),
Tag.of("appId", "123"),
Tag.of("appName", "my-service"),
)
)
.namingConvention(NamingConvention.dot)
}
}
@Bean
fun timedAspect(registry: MeterRegistry): TimedAspect {
val timedAspect = TimedAspect(registry)
return timedAspect
}
}
If you want to track JVM Thread Metrics, add the following bean to the config above:
@Bean
fun threadMetrics(): JvmThreadMetrics {
return JvmThreadMetrics()
}
Creating and using custom application metrics (examples)
Here is an example of using @Counted
and @Timed
annotations on a method.
@Counted(value = "name.of.my.metrics.count")
@Timed(value = "name.of.my.metrics.time")
fun doIt() {
// ...
}
Here is a service that encapsulates Gauge metrics (it helps to keep metrics on one place and avoids pollution of code with random metrics):
import io.micrometer.core.instrument.Metrics
import org.springframework.stereotype.Component
import java.util.concurrent.atomic.AtomicInteger
@Component
class AppMetrics {
private var itemsQueueSizeGauge = AtomicInteger(0)
// ...
init {
Metrics.gauge("items.queue.size", itemsQueueSizeGauge)
// ...
}
fun reportItemsQueueSize(size: Int) {
itemsQueueSizeGauge.set(size)
}
// ...
}
Resources
Micrometer guides
- https://docs.micrometer.io/micrometer/reference/
- https://docs.micrometer.io/micrometer/reference/implementations/datadog.html
- https://docs.micrometer.io/micrometer/reference/concepts/counters.html
- https://docs.micrometer.io/micrometer/reference/concepts/gauges.html
- https://docs.micrometer.io/micrometer/reference/concepts/timers.html
Spring guides
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.metrics.export.datadog
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.enabling
- https://docs.spring.io/spring-batch/reference/monitoring-and-metrics.html
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.metrics.supported.spring-mvc