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:
- The StatsD client sends metrics via UDP or TCP to the agent.
- 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 event reporting.
- Custom attribute message type for sending static non-metric information.
- Dimensions (tags) can be added to all metrics or to specific metrics.
- Unit of measure can be specified per metric.
Custom application metrics Copied
Usage Copied
To add as a Maven dependency:
- 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.
- 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:
- Default dimensions — these are custom dimensions applied to every metric. They can be defined one of two ways:
- Via code:
builder.defaultDimension("region", "Americas");
- Via environment variables:
export STATSD_DIMENSION_region=Americas
- Per-metric dimensions — these are custom dimensions specified for one metric, for example:
statsd.increment("failed_logins", Dimension.of("region", "europe"));
- Platform dimensions — the StatsD client creates dimensions from specific environment variables based on the deployment platform. This feature can be disabled by building the client with
.disablePlatformDimensions()
or by setting theSTATSD_DISABLE_PLATFORM_DIMENSIONS
environment variable totrue
.-
The variables for Kubernetes and OpenShift are:
Variable Dimension HOSTNAME hostname POD_NAME pod_name CONTAINER_NAME container_name NAMESPACE namespace -
Default variables are (if no other platform type is selected):
Variable Dimension APP_NAME app_name HOSTNAME hostname
-
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 by adding code to the application.
- Invoke the collector through the -javaagent JVM runtime argument.
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 oneJvmMetrics
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:
protocol=[udp|tcp]
— transport protocol (defaults to UDP).collect=[memory|os|runtime|threading]
— enables collection of a metric category. By default, all categories are enabled. Setting at least one collect option overrides the default. It can be specified multiple times.dimension=key:val
— adds a default dimension. It can be specified multiple times.reportingInterval=10000
— specifies the reporting interval in milliseconds.maxMessageSize=1432
— specifies the maximum StatsD message size in bytes.workerThreads=2
— specifies a number of collector threads.log
— enables error logging. Exceptions will be printed to stderr. If you specify invalid arguments, the agent exits the JVM with an exit code of1
.
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 |