Sending Metrics to Datadog with Java

In my previous post I drew an idea of sending PostgreSQL metrics to Datadog using Java code. This post will reveal implementation details of the Send action described previously.

How does Datadog collect metrics?

There are two basic ways of collecting and sending data:

  1. Use Datadog agent
  2. Collect and send manually

Use Datadog agent

Datadog agent consists of three components: the collector, DogStatsD and the forwarder. All run on a host – a server, local machine etc. The collector collects metrics from the host and the forwarder sends them to Datadog. What is important for a custom integration is the DogStatsD, which is a backend server capable of receiving custom metrics from an application. For more information about those components visit the agent page.

Collect and send manually

Alternatively, data can be collected manually (as opposed to using collector) and sent to Datadog API directly. This can be useful if Datadog agent cannot or shouldn’t be installed on a host.

Utilising the two methods

Datadog offers a number of libraries that can be used for integration. I chose two of them:

  1. java-dogstatsd-client – a statsd client library. This will be used to demonstrate communication with the agent installed on a host.
  2. metrics-datadog – written by Coursera, Datadog API client that creates a bridge between Dropwizard metrics and Datadog. This method can be used to demonstrate direct communication with the API.

An example solution contains the following interfaces and classes:

  1. CustomGauge models a gauge
  2. MetricsProvider gathers desired metrics
  3. MetricsBroker sends data to Datadog
  4. MetricsReporter ties MetricsProvider and MetricsBroker together
  5. ReporterApp is a placeholder scheduler application that uses MetricsReporter and ScheduledExecutorService to report periodically

The following diagram demonstrates structure of classes:

Metrics Structure

The repository can be downloaded from Github: datadog-example. Gradle application plugin has been used for ease of execution. The example consists of the following modules:

  • datadog-example-core
  • datadog-example-reporter
  • datadog-example-statsd


Contains all contracts, the DatadogFakeMetricsReporter, FakeMetricsProvider and the CustomGauge classes.


Dropwizard project with the DatadogMetricsBroker implementation. Set your own apiKey in the server.yml file and run from the module folder:

./gradlew run

In order to send data, DatadogReporter has been used:

DatadogReporter datadogReporter = DatadogReporter.forRegistry(new MetricRegistry())
    .withTransport(new HttpTransport.Builder().withApiKey(configuration.getApiKey()).build())

The report method is called to send metrics.

Method definition

public void report(
    SortedMap<String, Gauge> gauges,
    SortedMap<String, Counter> counters,
    SortedMap<String, Histogram> histograms,
    SortedMap<String, Meter> meters,
    SortedMap<String, Timer> timers)

Method invocation

Since I use only particular gauge as an example, the rest of the metrics are empty.


A console application with the StatsDMetricsBroker implementation. To run it, type the same command as above from the module folder:

./gradlew run

NonBlockingStatsDClient is used to communicate with the statsd server.

StatsDClient statsDClient = new NonBlockingStatsDClient(

If your binding address is different than the one used in this example, change hardcoded values of the host and port bindings in the DatadogStatsDApp class:

private static final String BIND_HOSTNAME = "localhost";
private static final int PORT = 8125;

The metrics should now be received by Datadog. How to observe them will be described in a next post.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s