Skip to content

Instrumenting with OpenCensus

In my last post, I talked about the OpenCensus Service. In this post, I would like to discuss how to instrument your application with the OpenCensus client libraries. Read on to learn more!

Before We Begin

Before you start adding instrumentation you should answer some questions about your library and application. For this post, I will cover an example in Java (the answers I will be using are in bold below).

  • Which context propagation format do you use (B3, W3C, other)?
  • How do you add dependencies today (Bazle, Gradle, Maven)?
  • What framework and what versions (DropWizard, Spring Boot, Spring Sleuth)?
  • What RPCs do you use (REST, gRPC, Thrift, etc)?
  • Do you run HTTP on Java and if so which ones (Jetty, Servlet, Tomcat)?
  • Do you make DB calls and if so which DBs (Cassandra, MongoDB, MySQL)

Goal: Create a span (either root or child) for a given service

Java Application

Here is my example Java application:

Creating a Root Span

Here is what my code looks like after I add instrumentation to create a root span:

OK, let’s walk through these changes. First, we import what we need for OpenCensus:

Then we instantiate our tracer:

Then we register our exporter:

Then we adjust our sampling policy. By default, OpenCensus samples 1:10,000 spans. We will change this to sample everything:

Then we will add a sleep. By default, OpenCensus exports traces every five seconds, so we need to be sure to wait at least that long:

With OpenCensus configured, we can now create our root span:

Creating A Child Span Of A Function Call

Next, let’s add child spans of function calls:

There are actually a couple ways to create spans so for this example I demonstrate the two most common. The first one is the same as the root, but this time creates a child span:

The second option makes use of a scoped span and requires an additional import:

Now we can wrap our calls instead of explicitly ending them. This works whether the wrapped calls are successful or not.

Creating Child Spans in Spring

If you are using Spring then adding spans is even easier. We start by adding the beans:

Then to create spans for functions we can do:

As you can see, adding spans is as easy as starting each function with:

Adding Span Metadata

Once you have spans for service-to-service communication calls you will next want to add metadata to enrich your spans. OpenCensus provides two facilities for this:

  • Attributes: key/value pairs
  • Annotations: strings (e.g. log message)

Let’s enrich our example application:

OK, so what changed? This time, we added a host.name key on the child span of the doMoreWork function call. To do this, we added the following import:

Then we added the attribute as follows:

In addition, we added a string to the child span of the doSomeOtherWork function call:

Summary

As you can see, it is really easy to get started with the OpenCensus Client Libraries. You provide some initial configuration based on your requirements including things like context propagation format, exporter, and sampling policy. Then, you create root and child spans. Finally, you enrich spans with metadata. This basic flow is the same no matter what language you are instrumenting.

© 2019, Steve Flanders. All rights reserved.

Published inCloud Native

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *