- Prerequisites
- Set Up a WavefrontSender
- Send Data to Wavefront
- Close the WavefrontSender
- Monitor the SDK
- License
- How to Contribute
Wavefront by VMware Java SDK lets you send raw data from your Java application to Wavefront using a WavefrontSender
interface. The data is then stored as metrics, histograms, and trace data. This SDK is also referred to as the Wavefront Sender SDK for Java.
Although this library is mostly used by the other Wavefront Java SDKs to send data to Wavefront, you can also use this SDK directly. For example, you can send data directly from a data store or CSV file to Wavefront.
- Java 8 or above.
- Add dependencies:
-
Maven
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. -
Gradle
If you are using Gradle, add the following dependency:compile group: 'com.wavefront', name: 'wavefront-sdk-java', version: '$releaseVersion'
Replace
$releaseVersion
with the latest version available on maven.
-
You can send metrics, histograms, or trace data from your application to the Wavefront service using a Wavefront proxy or direct ingestions.
- 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.
- Use direct ingestion to send the data directly to the Wavefront service. This is the simplest way to get up and running quickly.
Let's create a WavefrontClient
to send data to Wavefront either via Wavefront proxy or directly over HTTP.
Deprecated implementations:
WavefrontDirectIngestionClient
andWavefrontProxyClient
are deprecated from proxy version 7.0 onwards. We recommend all new applications to use theWavefrontClient
.
Use WavefrontClientFactory
to create a WavefrontClient
instance, which can send data directly to a Wavefront service or send data using a Wavefront Proxy.
The WavefrontClientFactory
supports multiple client bindings. If more than one client configuration is specified, you can create a WavefrontMultiClient
to send multiple Wavefront services.
- Sending data via Wavefront proxy?
Before your application can use aWavefrontClient
you must set up and start a Wavefront proxy. - Sending data via direct ingestion?
- Verify that you have the Direct Data Ingestion permission. For details, see Examine Groups, Roles, and Permissions.
- The HTTP URL of your Wavefront instance. This is the URL you connect to when you log in to Wavefront, typically something like
http://<domain>.wavefront.com
.
You can also use HTTP client with Wavefront Proxy version 7.0 or newer. Example:http://proxy.acme.corp:2878
. - Obtain the API token.
You initialize a WavefrontClient
by building it with the information you obtained in the Prerequisites section.
Optionally, you can call factory methods to tune the following ingestion properties:
- Max queue size - Internal buffer capacity of the
WavefrontSender
. Data that exceeds 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
. Override the defaults only to set higher values.
Example: Use a factory class to create a WavefrontClient and send data to Wavefront via Wavefront Proxy.
// Add a client with the following URL format: "proxy://<your.proxy.load.balancer.com>:<somePort>"
// to send data to proxies
WavefrontClientFactory wavefrontClientFactory = new WavefrontClientFactory();
wavefrontClientFactory.addClient(wavefrontURL);
WavefrontSender wavefrontSender = wavefrontClientFactory.getClient();
Example: Use a builder to create a WavefrontClient and send data to Wavefront via Wavefront Proxy.
// Using the WavefrontClient.Builder directly with a url in the form of "http://your.proxy.load.blanacer:port"
// to send data to proxies.
WavefrontClient.Builder wfClientBuilder = new WavefrontClient.Builder(proxyURL);
//The maximum message size in bytes that is pushed with on each flush interval
wfClientBuilder.messageSizeBytes(120);
// This is the size of internal buffer beyond which data is dropped
// Optional: Set this to override the default max queue size of 500,000
wfClientBuilder.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
wfClientBuilder.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
wfClientBuilder.flushIntervalSeconds(2);
WavefrontSender wavefrontSender = wfClientBuilder.build();
Example: Use a factory class to create a WavefrontClient and send data to Wavefront via direct ingestion.
// Create a factory and add a client with the following URL format: "http://[email protected]"
// and a Wavefront API token with direct ingestion permission
WavefrontClientFactory wavefrontClientFactory = new WavefrontClientFactory();
// Add a new client that sends data directly to Wavefront services
wavefrontClientFactory.addClient(wavefrontURL,
20_000, // This is the max batch of data sent per flush interval
100_000, // This is the size of internal buffer beyond which data is dropped
2, // Together with the batch size controls the max theoretical throughput of the sender
Integer.MAX_VALUE // The maximum message size in bytes we will push with on each flush interval
);
WavefrontSender wavefrontSender = wavefrontClientFactory.getClient();
Example: Use a builder to create a WavefrontClient and send data to Wavefront via direct ingestion.
// Using the WavefrontClient.Builder directly with a url in the form of "https://DOMAIN.wavefront.com"
// and a Wavefront API token with direct ingestion permission
WavefrontClient.Builder wfClientBuilder = new WavefrontClient.Builder(wavefrontURL, token);
//The maximum message size in bytes that is pushed with on each flush interval
wfClientBuilder.messageSizeBytes(120);
// 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
wfClientBuilder.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
wfClientBuilder.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
wfClientBuilder.flushIntervalSeconds(2);
WavefrontSender wavefrontSender = wfClientBuilder.build();
Use WavefrontMultiClient
to send data to multiple Wavefront services so you handle the data traffic.
The addClient()
supports null for batch size, queue size, and push interval. The defaults values are used if nothing is specified.
Example: Creating a WavefrontMultiClient
to send data to multiple Wavefront services.
// Add multiple URLs to the Factory to obtain a multi-sender
WavefrontClientFactory wavefrontClientFactory = new WavefrontClientFactory();
wavefrontClientFactory.addClient("https://[email protected]");
wavefrontClientFactory.addClient("proxy://our.proxy.lb.com:2878");
// Send traces and spans to the tracing port. If you are directly using the sender SDK to send spans without using any other SDK, use the same port as the customTracingListenerPorts configured in the wavefront proxy. Assume you have installed and started the proxy on <proxyHostname>.
wavefrontClientFactory.addClient("http://<proxy_hostname>:30000/");
WavefrontSender wavefrontSender = wavefrontClientFactory.getClient();
Wavefront supports different metric types, such as gauges, counters, delta counters, histograms, traces, and spans. See Metrics for details. To send data to Wavefront using the WavefrontSender
you need to instantiate the following:
// 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());
Note: If your metricName
has a bad character, that character is replaced with a -
.
// 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());
// Using the WavefrontClient.Builder directly with a url in the form of "http://your.proxy.load.blanacer:port"
// to send data to proxies.
WavefrontClient.Builder wfClientBuilder = new WavefrontClient.Builder(proxyURL);
// Now send distributed tracing spans as below
// 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
// 1552949776000 343"
wavefrontSender.sendSpan("getAllUsers", 1552949776000L, 343, "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<>("service", "istio")).
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();
See the diagnostic metrics documentation for details on the internal metrics that the SDK collects and reports to Wavefront.
- Reach out to us on our public Slack channel.
- If you run into any issues, let us know by creating a GitHub issue.