Java StatsD Client Library

Overview Copied

The Java StatsD client library is used for recording custom application metrics and JVM metrics.

It is intended to be used with the Collection Agent and the StatsD plug-in. The workflow is as follows:

  1. The StatsD client sends metrics via UDP or TCP to the agent.
  2. The agent aggregates and reports the metrics every 10 seconds by default.

Specification Copied

The StatsD client is based on the StatsD protocol with the following enhancements:

Custom application metrics Copied

Usage Copied

To add as a Maven dependency:

  1. Define the ITRS Maven repository in pom.xml or ~/.m2/settings.xml.
<repositories>
  <repository>
    <id>itrsgroup-collection</id>
    <url>https://maven.itrsgroup.com/repository/public</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
</repositories>

Note

You can access the repository at Maven Repository.
  1. Add the dependency in pom.xml.
<dependency>
  <groupId>com.itrsgroup.collection</groupId>
  <artifactId>statsd-client</artifactId>
  <version>VERSION</version>
</dependency>

Note

You can also find the installation files at ITRS Downloads.

A single StatsD client instance can be shared throughout an application. It is safe for concurrent use by multiple threads.

After constructing an instance, the client does not throw any exceptions, and none of its methods will block. Any exceptions that are caught internally are reported through an optional error callback.

Creating a client:

// Create a client builder:
final StatsdClientBuilder builder = new StatsdClientBuilder();

// By default, UDP is used. To use TCP instead:
builder.channelType(ChannelType.TCP);

// Use a server and port different from the default of localhost:8125:
builder.server(InetAddress.getByName("host.domain.com"));
builder.port(9000);

// Set an optional error callback:
builder.errorCallback(ex -> logger.error("statsd error", ex));

// Add dimension(s) to all metrics:
builder.defaultDimension("region", "Americas");

// Build the client:
final StatsdClient statsd = builder.build();

Recording metrics:

// Increment a counter
statsd.increment("failed_logins");

// Decrement a counter
statsd.decrement("thread_count");

// Adjust a counter
statsd.count("items_processed", 5);

// Set a gauge with an absolute value
statsd.gauge("cache_size", 123.5);

// Set a gauge with a unit of measure
statsd.gauge("cache_size", 52.5, Unit.MEGABYTES);

// Adjust a gauge
statsd.gauge("tank", -5.0);

// Register periodic gauge sampling.
// The given DoubleSupplier will be polled at the client's configured interval.  This should
// only be called once per name/dimension combination - duplicate registrations are ignored.
statsd.gauge("cache_size", () -> this::getCacheSize);

// Count unique values in a bucket
statsd.unique("unique_logins", "alice");

// Record a timer in millseconds
statsd.timer("db_query_time", 56L);

// Record a timer with a different unit
statsd.timer("db_query_time", 56L, TimeUnit.MICROSECONDS);

// Include dimensions with a metric (to reduce garbage, it is recommended to create the dimensions once and reuse)
statsd.increment("failed_logins", Collections.singleton(Dimension.of("region", "Europe")));

// Send an event
statsd.event("custom_event", "event description", Severity.INFO);

// Send a static attribute.
statsd.attribute("app_version", "1.5"); 

// Close the client when no longer needed
statsd.close();

StatsD server Copied

If the server/port of the StatsD server are not explicitly provided when building a client (see example in Usage), the builder looks for the STATSD_SERVER and STATSD_PORT environment variables. If these are not present, the client defaults to localhost:8125.

Add dimensions Copied

There are three ways to add dimensions to a metric:

statsd.increment("failed_logins", Dimension.of("region", "europe"));

Sampling rate Copied

When sampling high-frequency operations, it is possible to flood the StatsD server with a large number of messages.

To mitigate this problem, some operations can use a sampling rate which causes the client to send a message for only a specified percentage of all invocations.

Example:

void frequentlyInvokedMethod() {
  statsd.increment("metric", 0.5);
}

The client sends the increment message for approximately half of the times it is invoked. In those instances, the client includes the sampling rate in the message: metric:1|c|@0.5. This instructs the server to multiply the value 1 by 2 to approximate the actual value.

Note

This feature is only available for counters and timers.

Sets Copied

To count the number of unique items in a bucket or set, follow this example:

void login(String username) {
  statsd.unique("unique_logins", username, Collections.singleton(Dimension.of("region", "europe")));
}

The StatsD server tracks the number of unique values per reporting interval and publishes them as a counter metric.

Collect JVM metrics Copied

The JvmMetrics class collects metrics about the JVM itself. By default, collection occurs every 10 seconds and the metrics are reported through a StatsD client.

Custom collectors can be created as needed. See the JvmMetricsCollector interface and the usage example.

There are two ways in which you can instrument an application:

Create a metrics collector Copied

You can create the metrics collector by adding the following code to the application:

final JvmMetricsBuilder builder = new JvmMetricsBuilder();
  
// Create a statsd client (see previous section for details)
final MetricsClient client = new StatsdClientBuilder().build();
builder.client(client);
   
// By default, exceptions will be silently swallowed.  Optionally provide a way to log them.
builder.errorCallback(Throwable::printStackTrace);
    
// By default, all categories of metrics will be collected.  If only specific categories are desired:
builder.collectMemoryMetrics();
builder.collectOperatingSystemMetrics();
builder.collectRuntimeMetrics();
builder.collectThreadMetrics();
   
// Add a custom collector
builder.addCollector(new MyCollector());

// Override the default number of worker threads (this should never exceed the number of collectors)
builder.workerThreads(5);

// Finish building
final JvmMetrics metrics = builder.build();
   
// If/when the metrics are no longer needed
metrics.close();

Once the collector is instantiated, the metrics collection begins and no further interaction with this class is required. The collector reports exceptions through an optionally provided callback.

Note

Only one JvmMetrics instance can be created per JVM.

Invoke a metrics collector Copied

You can invoke the collector with the -javaagent JVM runtime argument. This allows metrics collection to be enabled on any existing application without the need to modify code.

The agent creates its own StatsD client used to deliver metrics to the Collection Agent. The client’s default destination is localhost:8125. This can be overridden via the STATSD_SERVER and STATSD_PORT environment variables.

Example:

java -javaagent:statsd-client-VERSION.jar[=option=val,option=val,...] -jar myapplication.jar

The following options are available:

Collected metrics Copied

Metrics collected for memory Copied

Metric name Type Unit Dimensions
jvm_memory_heap_used gauge bytes
jvm_memory_heap_committed gauge bytes
jvm_memory_heap_max gauge bytes
jvm_memory_non_heap_used gauge bytes
jvm_memory_non_heap_committed gauge bytes
jvm_memory_non_heap_max gauge bytes
jvm_memory_pool_heap_used gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_pool_heap_committed gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_pool_heap_max gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_pool_non_heap_used gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_pool_non_heap_committed gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_pool_non_heap_max gauge bytes jvm_memory_pool_name=pool_name
jvm_memory_gc_collection_count gauge none jvm_memory_gc_name=collector_name
jvm_memory_gc_collection_time gauge milliseconds jvm_memory_gc_name=collector_name

Metrics collected for threads Copied

Metric name Type Unit Dimensions
jvm_threads gauge none
jvm_threads_daemon gauge none
jvm_threads_peak gauge none
jvm_threads_started gauge none
jvm_threads_states gauge none thread_state=[NEW,RUNNABLE,etc…]
jvm_threads_monitor_deadlock gauge none

Metrics collected for runtime Copied

Metric name Type Unit
jvm_runtime_start_time gauge milliseconds
jvm_runtime_uptime gauge milliseconds
jvm_runtime_name attribute none
jvm_runtime_vm_vendor attribute none
jvm_runtime_vm_version attribute none
jvm_runtime_spec_name attribute none
jvm_runtime_spec_vendor attribute none
jvm_runtime_spec_version attribute none
jvm_runtime_class_path attribute none
jvm_runtime_library_path attribute none

Metrics collected for operating system Copied

Metric name Type Unit
jvm_os_system_load_average attribute none
jvm_os_name attribute none
jvm_os_arch attribute none
jvm_os_version attribute none
jvm_os_available_processors attribute none
["Geneos"] ["Geneos > Netprobe"] ["User Guide"]

Was this topic helpful?