Instrument Your Java App In Minutes with the Honeycomb Beeline for Java

5 Min. Read

We are excited to announce automatic instrumentation for your Java apps through our new Honeycomb Beeline for Java!

This new Beeline streamlines instrumentation of HTTP events in Java Spring Boot 2 apps, and supports tracing out of the box. If you don’t have a Spring Boot app, there’s still good news! Through the Beeline, we expose a tracing API that will get you started quickly.

With Spring Boot, the Beeline will automagically send Honeycomb everything you need to start visualizing complex questions right away, like

  • “what’s the 99th percentile latency of each endpoint?” or
  • “what endpoints are being hit most often?”

If you want to slice and dice additional app context, you can add a custom event field with just one line of code.

What you’ll need

  • Java 8+ for the beeline-core and beeline-spring-boot-starter modules
  • Spring Boot 2 for the beeline-spring-boot-starter module
  • A Honeycomb API key, found on your Honeycomb Team Settings page. (Sign up for free if you haven’t already!)

Setup

For Spring Boot 2 apps, add the beeline-spring-boot-starter module to your Maven build’s pom.xml:

<dependency>
  <groupId>io.honeycomb.beeline</groupId>
  <artifactId>beeline-spring-boot-starter</artifactId>
  <version>1.0.0</version>
</dependency>

For other Java apps, add the beeline-core module instead:

<dependency>
  <groupId>io.honeycomb.beeline</groupId>
  <artifactId>beeline-core</artifactId>
  <version>1.0.0</version>
</dependency>

Instrument

For Spring Boot 2 apps, add the following configuration to your application.properties file in src/main/resources:

    # (Required) Give your application a name to identify the origin of your Honeycomb Events/Spans
    honeycomb.beeline.service-name           :<service_name>
    
    # (Required) Dataset to send the Events/Spans to
    honeycomb.beeline.dataset                :<dataset_name>
    
    # (Required) Your honeycomb account API key
    honeycomb.beeline.write-key              :<Honeycomb API key>

These are the required configuration fields. Additional fields are optional and include honeycomb.beeline.sample-rate to set the sample rate, honeycomb.beeline.log-honeycomb-responses to enable debug logging, and more. Once you build and run your app, HTTP events will automatically be sent to your new dataset in Honeycomb with fields specific to Spring Boot such as method name, dispatcher type, handler type, and matched pattern.

For other Java apps, first set up the Beeline and its collaborator classes:

import io.honeycomb.beeline.tracing.Beeline;
import io.honeycomb.beeline.tracing.Span;
import io.honeycomb.beeline.tracing.SpanBuilderFactory;
import io.honeycomb.beeline.tracing.SpanPostProcessor;
import io.honeycomb.beeline.tracing.Tracer;
import io.honeycomb.beeline.tracing.Tracing;
import io.honeycomb.beeline.tracing.sampling.Sampling;
import io.honeycomb.libhoney.HoneyClient;
import io.honeycomb.libhoney.LibHoney;

public class TracerSpans {
private static final String WRITE_KEY = "test-write-key";
private static final String DATASET = "test-dataset";

private static final HoneyClient client;
private static final Beeline beeline;

static {
    client                          = LibHoney.create(LibHoney.options().setDataset(DATASET).setWriteKey(WRITE_KEY).build());
    SpanPostProcessor postProcessor = Tracing.createSpanProcessor(client, Sampling.alwaysSampler());
    SpanBuilderFactory factory      = Tracing.createSpanBuilderFactory(postProcessor, Sampling.alwaysSampler());
    Tracer tracer                   = Tracing.createTracer(factory);
    beeline                         = Tracing.createBeeline(tracer, factory);
    }

From here, you can start adding context to your events by adding custom fields to spans, and add child spans to create traces. Both of these actions are supported for both Spring Boot and other Java apps. Here are some examples with Spring Boot:

import io.honeycomb.beeline.tracing.Beeline;
import io.honeycomb.beeline.spring.beans.aspects.ChildSpan;

@Controller
class OwnerController {

    private final Beeline beeline;
    private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
    private final OwnerRepository owners;
    
    public OwnerController(OwnerRepository clinicService, Beeline beeline) {
        this.owners = clinicService;
        this.beeline = beeline;
    }
        
    @GetMapping("/owners/new")
    public String initCreationForm(Map<String, Object> model) {
        Owner owner = new Owner();
        this.beeline.getActiveSpan().addField("new_owner", owner);
        model.put("owner", owner);
        return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
    }

    @ChildSpan("find an owner")
    @GetMapping("/owners/find")
    public String initFindForm(Map<String, Object> model) {
        model.put("owner", new Owner());
        return "owners/findOwners";
    }
}

Explore!

Now that your app is instrumented, you can start asking questions about your data in Honeycomb! For example, you can find out which endpoints are being hit most often. When you log into Honeycomb and click on your new dataset, you’ll be taken to our query page. In the sidebar on the right, you’ll see the schema from events that the Java Beeline has sent to Honeycomb. Break down by request spring.request.handler_method and request.path to get an overview of your app’s endpoints, and add COUNT to the calculate box to find out how many times each endpoint was used.

That’s all you need to start visualizing and investigating your app behavior in Honeycomb! Learn more here about exploring your data and constructing queries in Honeycomb.

Want to go further?

If you want to customize your Beeline beyond what the Quickstart has to offer, you can find the Javadocs here.


Haven’t tried Honeycomb before? Sign up for free!

Don’t forget to share!
Alaina Valenzuela

Alaina Valenzuela

Senior Software Engineer

Alaina is a software engineer.

Related posts