Announcing Honeycomb’s Java SDK

4 Min. Read

Now Java developers can leverage Honeycomb to gain insight into the behavior of their apps and services by using an SDK similar to the ones we’ve already released for Go, Python, Javascript and Ruby.

Installation

The SDK is available from Maven Central Repository. To get started, add this to your Maven build’s pom.xml:

<dependency>
    <groupId>io.honeycomb.libhoney</groupId>
    <artifactId>libhoney-java</artifactId>
    <version>1.0.0</version>
</dependency>

For Gradle builds, add the following to your build.gradle dependencies:

compile group: 'io.honeycomb.libhoney', name: 'libhoney-java', version: '1.0.0'

API structure

The Java API shares a similar structure with our other SDKs, with objects representing:

  • An instance of the client
  • Events that are sent to Honeycomb
  • Builders for generating events that share common fields
  • Responses

Initializing the Honeycomb client

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.

import io.honeycomb.libhoney.HoneyClient;

import static io.honeycomb.libhoney.LibHoney.create;
import static io.honeycomb.libhoney.LibHoney.options;

public class Initialization {
    private HoneyClient honeyClient;

    public Initialization() {
        honeyClient = create(
            options()
                .setWriteKey("myTeamWriteKey")
                .setDataset("Cluster Dataset")
                .setSampleRate(2)
                .build()
        );
    }
}

Sending events

The quickest way to send an event is to use the send(Map) method, which will send it with the settings and fields of the HoneyClient instance.

public class SendImmediately {
    public static HoneyClient initializeClient() {
        return create(options()
            .setWriteKey("myTeamWriteKey")
            .setDataset("Cluster Dataset")
            .build()
        );
    }

    public static void main(String... args) throws UnknownHostException {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("randomString", UUID.randomUUID().toString());
        dataMap.put("cpuCores", Runtime.getRuntime().availableProcessors());
        dataMap.put("hostname", InetAddress.getLocalHost().getHostName());

        try (HoneyClient honeyClient = initializeClient()) {
            honeyClient.send(dataMap);
        }
    }
}

However, in many cases an event should be first customized with relevant data from its runtime context. createEvent() creates such a customizable Event, which can then be submitted to the Honeycomb server via Event.send().

Alternatively, an EventFactory is useful when a grouping of events being sent shares common properties. This can be created through the buildEventFactory() method.

Using an EventFactory

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();
        }
    }

Responses

If registered with HoneyClient.addResponseObserver(ResponseObserver), the ResponseObserver interface will be notified regarding the outcome of events being sent through the client. This can be useful to track if there is any issue with events being sent.

public class UsingResponseObserver {

    public static HoneyClient initializeClient() {
        return create(
            options()
                .setWriteKey("myTeamWriteKey")
                .setDataset("Cluster Dataset")
                .build()
        );
    }

    public static void main(String... args) throws UnknownHostException {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("randomString", UUID.randomUUID().toString());
        dataMap.put("cpuCores", Runtime.getRuntime().availableProcessors());
        dataMap.put("hostname", InetAddress.getLocalHost().getHostName());

        try (HoneyClient honeyClient = initializeClient()) {
            honeyClient.addResponseObserver(new LoggingObserver());
            honeyClient.send(dataMap);
        }
    }

    private static class LoggingObserver implements ResponseObserver {
        private static final Logger LOG = LoggerFactory.getLogger(LoggingObserver.class);

        @Override
        public void onServerAccepted(ServerAccepted acceptedEvent) {
            LOG.debug("Server accepted the event: {}", acceptedEvent);
        }

        @Override
        public void onServerRejected(ServerRejected rejectedEvent) {
            LOG.error("Server rejected the event with batch level status code {} and event level status code {}",
                rejectedEvent.getBatchData().getBatchStatusCode(),
                rejectedEvent.getEventStatusCode());
        }

        @Override
        public void onClientRejected(ClientRejected rejectedEvent) {
            if (rejectedEvent.getReason() == ClientRejected.RejectionReason.NOT_SAMPLED) {
                LOG.trace("Event was not sampled {}", rejectedEvent);
            }
            LOG.info("Event rejected on the client side due to {}",
                rejectedEvent.getReason(),
                rejectedEvent.getException());
        }

        @Override
        public void onUnknown(Unknown unknown) {
            LOG.error("Unknown state due to unexpected error: {}", unknown);
        }
    }
}

You can also associate metadata with an individual event (Event.addMetadata(k, v) and it will be communicated back through the response.

Enjoy! We look forward to your feedback and contributions back to the SDK!

For thorough API documentation, visit the Javadocs.
For higher-level documentation, head to our docs.

Want to try Honeycomb out with no strings attached? Check out our live data demo!

Don’t forget to share!
Alaina Valenzuela

Alaina Valenzuela

Senior Platform Engineer

Alaina is a software engineer.

Related posts