Libhoney for Java is Honeycomb’s structured logging library for Java applications. It is a low-level library that helps you send structured events to Honeycomb’s Events API.
The SDK is available from Maven Central Repository. To get started, add the SDK to your dependencies:
compile group: 'io.honeycomb.libhoney', name: 'libhoney-java', version: '1.5.4'
<dependency>
<groupId>io.honeycomb.libhoney</groupId>
<artifactId>libhoney-java</artifactId>
<version>1.5.4</version>
</dependency>
The LibHoney
class is the entry point to the Honeycomb client library, and is used to create a HoneyClient
.
The HoneyClient
class provides functionality to construct and send events.
The typical application will only have one HoneyClient
instance.
Use LibHoney
’s static methods to construct and configure an instance of HoneyClient
, passing in your Team API key and the default dataset name to which it should send events.
public class Initialization {
private HoneyClient honeyClient;
public Initialization() {
honeyClient = create(
options()
.setWriteKey("myTeamWriteKey")
.setDataset("Cluster Dataset")
.setSampleRate(2)
.build()
);
}
}
To reach the Honeycomb API through a proxy server, you need to specify alternative TransportOptions
when calling create
, and provide the proxy address.
For example, if your proxy is at https://myproxy.example.com
:
public class Initialization {
private HoneyClient honeyClient;
public Initialization() {
honeyClient = create(
options()
.setWriteKey("myTeamWriteKey")
.setDataset("Cluster Dataset")
.setSampleRate(2)
.build(),
transportOptions().setProxy(HttpHost.create("https://myproxy.example.com")).build()
);
}
}
Important notes on Libhoney:
HoneyClient
instance across threads is thread safe.Once initialized, HoneyClient
is ready to send events.
In many cases, an event should be first customized with relevant data from its runtime context.
For example, try putting a timer around a section of code, adding per-user information, or details about what it took to craft a response.
You can add fields when and where you need to, or for some events but not others.
(Error handlers are a good example of this.)
createEvent()
creates such a customizable Event
.
You can add fields to the event with .addField()
and then submit to the Honeycomb server via Event.send()
.
Sending an event is an asynchronous action and will avoid blocking by default.
public static void main(String... args) {
try (HoneyClient honeyClient = initializeClient()) {
honeyClient
.createEvent()
.addField("userName", "Bob")
.addField("userId", UUID.randomUUID().toString())
.setTimestamp(System.currentTimeMillis())
.send();
}
}
Alternatively, an EventFactory
is useful when a grouping of events being sent shares common properties.
This can be created through the buildEventFactory()
method.
You can use an EventFactory
to create many similar events as follows:
static class UserService {
private final EventFactory localBuilder;
UserService(HoneyClient libHoney) {
int serviceLevelSampleRate = 2;
localBuilder = libHoney.buildEventFactory()
.addField("serviceName", "userService")
.setSampleRate(serviceLevelSampleRate)
.build();
}
void sendEvent(String username) {
localBuilder
.createEvent()
.addField("userName", username)
.addField("userId", UUID.randomUUID().toString())
.setTimestamp(System.currentTimeMillis())
.send();
}
}
All libraries set defaults that will allow your application to function as smoothly as possible during error conditions. When creating events faster than they can be sent, overflowed events will be dropped instead of backing up and slowing down your application. If you add the same key multiple times, only the last value added will be kept.
For situations in which you would like to disable sending events to Honeycomb, such as a test environment or in unit tests, use HoneyClient
’s constructor in which the Transport
can be overridden.
Create a mock Transport
to substitute in that implements the Transport
interface.
One similar example can be seen here.
Sending an event is an asynchronous action and will avoid blocking by default.
.send()
will enqueue the event to be sent as soon as possible, meaning the return value of that method does not indicate that the event was successfully sent.
To see whether events are being successfully received by Honeycomb’s servers, register a ResponseObserver
interface with HoneyClient
.
The ResponseObserver
interface has four methods which are notified in different circumstances depending on the outcome of the sending of the event:
onServerAccepted
will be notified for any event that was accepted on the server sideonServerRejected
will be notified for any event that was rejected on the server sideonClientRejected
will be notified for any event that was rejected on the client sideonUnknown
will be notified for any event where the outcome was not clearAll responses have methods to extract the original event metadata, metrics collected during the event, and a message explaining the response from Honeycomb:
getEventMetadata
: Get the event metadata that was originally passed in with the event.
The metadata is not modified by the client and not sent to the Honeycomb server.getMessage
: Get a human readable message explaining the response.getMetrics
: Get any metrics that may have been collected during the lifetime of the event.
These metrics will only be complete if a response from the Honeycomb server was received.For responses to events either accepted by or rejected by the server, it is also possible to extract the event status code and raw HTTP response body.
getEventStatusCode
: Get the event-specific status code, if it is available, otherwise -1.
For batched events this is the status code contained in the batch response body.getRawHttpResponseBody
: Get a byte array of the raw response body.In the case of responses to events rejected by the client, the exception and rejection reason are accessible.
getException
: Get the exception that may have caused the rejection (returns null
if no exception was the cause).getReason
: Get the reason for the event having been rejected.Before sending an event, you have the option to attach metadata to that event.
This metadata is not sent to Honeycomb; instead, it is used to help you match individual responses with sent events.
When sending an event, HoneyClient
will take the metadata from the event and attach it to the response for you to consume.
Add metadata by calling .addMetadata(k, v)
or addMetadata(Map<String,?> metadata)
on an event.
You do not have to process responses if you are not interested in them—simply ignoring them is perfectly safe. Unread responses will be dropped.
Refer to Common Issues with Sending Data in Honeycomb.
Features, bug fixes and other changes to libhoney
are gladly accepted.
Please open issues or a pull request with your change.
Remember to add your name to the CONTRIBUTORS file!
All contributions will be released under the Apache License 2.0.