Wavefront by VMware SDK for Java is the core library for sending metrics, histograms and trace data from your Java application to Wavefront using a WavefrontSender
interface.
If you are using Maven, add the following maven dependency to your pom.xml:
<dependency>
<groupId>com.wavefront</groupId>
<artifactId>wavefront-sdk-java</artifactId>
<version>$releaseVersion</version>
</dependency>
Replace $releaseVersion
with the latest version available on maven.
If you are using Gradle, add the following to dependencies:
compile group: 'com.wavefront', name: 'wavefront-sdk-java', version: '$releaseVersion'
Replace $releaseVersion
with the latest version available on maven.
You can choose to send metrics, histograms, or trace data from your application to the Wavefront service using one of the following techniques:
- Use direct ingestion to send the data directly to the Wavefront service. This is the simplest way to get up and running quickly.
- Use a Wavefront proxy, which then forwards the data to the Wavefront service. This is the recommended choice for a large-scale deployment that needs resilience to internet outages, control over data queuing and filtering, and more.
The WavefrontSender
interface has two implementations. Instantiate the implementation that corresponds to your choice:
- Option 1: Create a
WavefrontDirectIngestionClient
to send data directly to a Wavefront service. - Option 2: Create a
WavefrontProxyClient
to send data to a Wavefront proxy.
To create a WavefrontDirectIngestionClient
, you build it with the information it needs to send data directly to Wavefront.
Gather the following access information:
- Identify the URL of your Wavefront instance. This is the URL you connect to when you log in to Wavefront, typically something like
https://<domain>.wavefront.com
. - In Wavefront, verify that you have Direct Data Ingestion permission, and obtain an API token.
You initialize a WavefrontDirectIngestionClient
by building it with the access information you obtained in Step 1.
You can optionally call builder methods to tune the following ingestion properties:
- Max queue size - Internal buffer capacity of the
WavefrontSender
. Any data in excess of this size is dropped. - Flush interval - Interval for flushing data from the
WavefrontSender
directly to Wavefront. - Batch size - Amount of data to send to Wavefront in each flush interval.
Together, the batch size and flush interval control the maximum theoretical throughput of the WavefrontSender
. You should override the defaults only to set higher values.
// Create a builder with the URL of the form "https://DOMAIN.wavefront.com"
// and a Wavefront API token with direct ingestion permission
WavefrontDirectIngestionClient.Builder wfDirectIngestionClientBuilder =
new WavefrontDirectIngestionClient.Builder(wavefrontURL, token);
// Optional configuration properties.
// Only override the defaults to set higher values.
// This is the size of internal buffer beyond which data is dropped
// Optional: Set this to override the default max queue size of 50,000
wfDirectIngestionClientBuilder.maxQueueSize(100_000);
// This is the max batch of data sent per flush interval
// Optional: Set this to override the default batch size of 10,000
wfDirectIngestionClientBuilder.batchSize(20_000);
// Together with batch size controls the max theoretical throughput of the sender
// Optional: Set this to override the default flush interval value of 1 second
wfDirectIngestionClientBuilder.flushIntervalSeconds(2);
// Finally create a WavefrontDirectIngestionClient
WavefrontSender wavefrontSender = wfDirectIngestionClientBuilder.build();
Note: Before your application can use a WavefrontProxyClient
, you must set up and start a Wavefront proxy.
To create a WavefrontProxyClient
, you build it with the information it needs to send data to the Wavefront proxy, including:
- The name of the host that will run the Wavefront proxy.
- One or more proxy listening ports to send data to. The ports you specify depend on the kinds of data you want to send (metrics, histograms, and/or trace data). You must specify at least one listener port.
- Optional settings for tuning communication with the proxy.
// Create the builder with the proxy hostname or address
WavefrontProxyClient.Builder wfProxyClientBuilder = new WavefrontProxyClient.Builder(proxyHostName);
// Set the proxy port to send metrics to. Default: 2878
wfProxyClientBuilder.metricsPort(2878);
// Set a proxy port to send histograms to. Recommended: 40000
wfProxyClientBuilder.distributionPort(40_000);
// Set a proxy port to send trace data to. Recommended: 30000
wfProxyClientBuilder.tracingPort(30_000);
// Optional: Set a custom socketFactory to override the default SocketFactory
wfProxyClientBuilder.socketFactory(<SocketFactory>);
// Optional: Set a nondefault interval (in seconds) for flushing data from the sender to the proxy. Default: 5 seconds
wfProxyClientBuilder.flushIntervalSeconds(2);
// Create the WavefrontProxyClient
WavefrontSender wavefrontSender = wfProxyClientBuilder.build();
Note: When you set up a Wavefront proxy on the specified proxy host, you specify the port it will listen to for each type of data to be sent. The WavefrontProxyClient
must send data to the same ports that the Wavefront proxy listens to. Consequently, the port-related builder methods must specify the same port numbers as the corresponding proxy configuration properties:
WavefrontProxyClient builder method |
Corresponding property in wavefront.conf |
---|---|
metricsPort() |
pushListenerPorts= |
distributionPort() |
histogramDistListenerPorts= |
tracingPort() |
traceListenerPorts= |
To send data to Wavefront using the WavefrontSender
you instantiated:
// Wavefront Metrics Data format
// <metricName> <metricValue> [<timestamp>] source=<source> [pointTags]
// Example: "new-york.power.usage 42422 1533529977 source=localhost datacenter=dc1"
wavefrontSender.sendMetric("new-york.power.usage", 42422.0, 1533529977L,
"localhost", ImmutableMap.<String, String>builder().put("datacenter", "dc1").build());
// Wavefront Delta Counter format
// <metricName> <metricValue> source=<source> [pointTags]
// Example: "lambda.thumbnail.generate 10 source=lambda_thumbnail_service image-format=jpeg"
wavefrontSender.sendDeltaCounter("lambda.thumbnail.generate", 10,
"lambda_thumbnail_service",
ImmutableMap.<String, String>builder().put("image-format", "jpeg").build());
// Wavefront Histogram Data format
// {!M | !H | !D} [<timestamp>] #<count> <mean> [centroids] <histogramName> source=<source>
// [pointTags]
// Example: You can choose to send to at most 3 bins: Minute, Hour, Day
// "!M 1533529977 #20 30.0 #10 5.1 request.latency source=appServer1 region=us-west"
// "!H 1533529977 #20 30.0 #10 5.1 request.latency source=appServer1 region=us-west"
// "!D 1533529977 #20 30.0 #10 5.1 request.latency source=appServer1 region=us-west"
wavefrontSender.sendDistribution("request.latency",
ImmutableList.<Pair<Double, Integer>>builder().add(new Pair<>(30.0, 20)).
add(new Pair<>(5.1, 10)).build(),
ImmutableSet.<HistogramGranularity>builder().add(HistogramGranularity.MINUTE).
add(HistogramGranularity.HOUR).
add(HistogramGranularity.DAY).build(),
1533529977L, "appServer1",
ImmutableMap.<String, String>builder().put("region", "us-west").build());
// Wavefront Tracing Span Data format
// <tracingSpanName> source=<source> [pointTags] <start_millis> <duration_milliseconds>
// Example: "getAllUsers source=localhost
// traceId=7b3bf470-9456-11e8-9eb6-529269fb1459
// spanId=0313bafe-9457-11e8-9eb6-529269fb1459
// parent=2f64e538-9457-11e8-9eb6-529269fb1459
// application=Wavefront http.method=GET
// 1533529977 343500"
wavefrontSender.sendSpan("getAllUsers",1533529977L, 343500L, "localhost",
UUID.fromString("7b3bf470-9456-11e8-9eb6-529269fb1459"),
UUID.fromString("0313bafe-9457-11e8-9eb6-529269fb1459"),
ImmutableList.<UUID>builder().add(UUID.fromString(
"2f64e538-9457-11e8-9eb6-529269fb1459")).build(), null,
ImmutableList.<Pair<String, String>>builder().
add(new Pair<>("application", "Wavefront")).
add(new Pair<>("http.method", "GET")).build(), null);
Remember to flush the buffer and close the sender before shutting down your application.
// If there are any failures observed while sending metrics/histograms/tracing-spans above,
// you get the total failure count using the below API
int totalFailures = wavefrontSender.getFailureCount();
// on-demand buffer flush (may want to do this if you are shutting down your application)
wavefrontSender.flush();
// close the sender connection before shutting down application
// this will flush in-flight buffer and close connection
wavefrontSender.close();