Micrometer Datadog

Datadog is a dimensional time-series SaaS with built-in dashboarding and alerting.

1. Installation and Configuration

Micrometer supports shipping metrics to Datadog directly by using its HTTP API or by using DogStatsD through the StatsD registry. If you can choose between the two, the API approach is far more efficient.

1.1. Direct to Datadog API Approach

For Gradle, add the following implementation:

implementation 'io.micrometer:micrometer-registry-datadog:latest.release'

For Maven, add the following dependency:

<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-datadog</artifactId>
  <version>${micrometer.version}</version>
</dependency>

Metrics are rate-aggregated and pushed to datadoghq on a periodic interval. Rate aggregation performed by the registry yields datasets that are similar to those produced by dogstatsd.

DatadogConfig config = new DatadogConfig() {
    @Override
    public Duration step() {
        return Duration.ofSeconds(10);
    }

    @Override
    public String get(String k) {
        return null; // accept the rest of the defaults
    }
};
MeterRegistry registry = new DatadogMeterRegistry(config, Clock.SYSTEM);

DatadogConfig is an interface with a set of default methods. If, in the implementation of get(String k), rather than returning null, you instead bind it to a property source, you can override the default configuration through properties. For example, Spring Boot’s Micrometer support binds properties directly to the DatadogConfig. See the Datadog section in the Spring Boot reference documentation.

DatadogConfig.hostTag() specifies a tag key that is mapped to the host field when shipping metrics to Datadog. For example, if DatadogConfig.hostTag() returns host, the tag having host as its key is used. You can set the tag by using common tags, as follows:

registry.config().commonTags("host", "my-host");

uri is an important property to configure. The default value is api.datadoghq.com. Depending on the Datadog site (region), the api endpoint will be different. To find your the correct uri for your account, do the following:

  1. Read about the Datadog site.

  2. Go to the Metrics API reference and select your own option from the "DATADOG SITE" dropdown.

  3. Check any API request’s endpoint.

For example, for the US5 site, the correct API endpoint is api.us5.datadoghq.com. For the US3 site, it is api.us3.datadoghq.com.

1.2. Through DogStatsD Approach

For Gradle, add the following implementation:

implementation 'io.micrometer:micrometer-registry-statsd:latest.release'

For Maven, add the following dependency:

<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-statsd</artifactId>
  <version>${micrometer.version}</version>
</dependency>

Metrics are immediately shipped to DogStatsD using Datadog’s flavor of the StatsD line protocol. java-dogstatsd-client is not needed on the classpath for this to work, as Micrometer uses its own implementation.

StatsdConfig config = new StatsdConfig() {
    @Override
    public String get(String k) {
        return null;
    }

    @Override
    public StatsdFlavor flavor() {
        return StatsdFlavor.DATADOG;
    }
};

MeterRegistry registry = new StatsdMeterRegistry(config, Clock.SYSTEM);

If the DD_ENTITY_ID environment variable is properly set, Micrometer supports DogStatsD’s origin detection over UDP feature on Kubernetes.

Micrometer, by default, publishes Timer meters to DogStatsD as the StatsD “timing” metric type, ms. These meters are sent to Datadog as histogram type metrics. Also, by default, Micrometer publishes DistributionSummary meters as histogram type metrics.

When percentileHistogram is enabled for the meter, Micrometer sends Timer and DistributionSummary meters as Datadog Distributions to DogStatsD. You can make a DistributionSummary with percentileHistogram enabled, as follows:

DistributionSummary responseSizeSummary = DistributionSummary.builder("http.server.response.size")
        .baseUnit("bytes")
        .publishPercentileHistogram()
        .register(registry);