This blog post is part of our series about Open Source Application Monitoring (APM) tools. It describes the scope of the two main „standards“  in this area called OpenTracing and OpenCensus. If you want to get a broader overview of this topic first, we recommend to read the first part of this blog series: Open Source Application Performance Monitoring (APM) Tools – A Classification and Overview of Tools and Standards

Even though the name „standard“ might not be 100%  appropriate for the two specifications covered in this blog article, it gives you a sense of what they are trying to do: Their goal is to harmonize the way instrumentation is added to an application using common Application Programming Interfaces (APIs).  It is important to note that those two are not the first attempts to harmonize tracing implementations but they seem to be much more successful in terms of adoption than their predecessor Application Response Measurement (ARM) which is a specification with a similar goal hosted by the OpenGroup.

Anatomy of an APM Solution

In order to understand the scope of both standards, let’s first look at the high level architecture of many APM solutions in the following figure. As you can see, an APM solution usually consists of agents collecting metric and tracing data from an application which is then sent to a collector, further processed by a server and eventually presented to a user in a user interface (UI).

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus


Effort Distribution in an APM Solution

One of the main reasons for the development of standards for collecting APM data is to reduce the effort for the development of APM solutions. In the following Figure we have depicted the effort distribution between the aforementioned components exemplified using an iceberg analogy. The most important thing to note here, is that most of the effort for providing a fully fledged APM solution nowadays does not lie in the development of the UI, the servers or the collectors but in the agents gathering the raw data from the instrumented applications. This becomes even more obvious if you think about the wide variaty of application platforms available nowadays. When you try to support basic Java, .NET, Go, PHP or JavaScript applications you have at least five different agents to maintain. However, even this is not sufficient as multiple versions of the application runtimes may make it necessary for you to support multiple versions for each language, even if you just assume two versions for each agent you end up with ten different agent versions. It all gets worse when you think about application frameworks on top of each language (e.g., Java EE or Spring in Java), these frameworks are also available in multiple versions and when you add them to the matrix of agents you need it is easy to end up with more than 20 agent versions you need to maintain.

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus

Scope of APM Standards

As the aforementioned effort to develop and maintain a wide variety of agents needs to be spent by each and every APM vendor nowadays, the idea behind the Open APM Standards is to provide a common API to contribute APM data regardless of the APM solution in place. This idea is depicted in the following Figure. Using this approach, the instrumentation code can either be integrated by application framework providers (e.g., Spring in Java) or by a common agent for a given runtime, which can be used by multiple APM vendors. This fact mainly supports the development of open source APM solutions as one team alone could not provide the support for all technologies on the market today. Using open source APM standards the effort can be distributed across multiple teams and projects and they can all benefit from each other. For commercial APM vendors such an API provides the ability to enhance the existing trace information with user-contributed content without binding their users to a vendor-specific API.

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus

Scope of OpenTracing and OpenCensus

The scope and goal of our focus areas OpenTracing and OpenCensus can be summarized as follows:

  • OpenTracing wants to become something like a standard tracing API (such as SLF4J for logging in Java) which is already built into most frameworks you use (e.g., Spring/Hibernate in Java) and allows to plug in multiple APM solutions at runtime.
  • OpenCensus does not only specify a tracing API but also packages all aspects of data collection and distribution and automatically publishes the traces to known endpoints. Furthermore, it supports metric collection using so called stats, which is not supported by OpenTracing.

This difference in scope is also depicted in the following Figure as an overlay to the more generic overview in the previous picture. Therefore, they are not directly comparable, as OpenCensus has a broader scope than OpenTracing but in the following, we will focus on their common denominator – a tracing API that allows you to contribute tracing information independent of the APM solution in place.

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus

OpenTracing

In this section we will give you a very brief overview of the concepts and API provided by OpenTracing. A very good and a lot more detailed introduction to OpenTracing can be found on the project website (http://opentracing.io/documentation/), in the OpenTracing specification itself (https://github.com/opentracing/specification/blob/master/specification.md) and on the website of an OpenTracing-compatible tracer called Jaeger (https://www.jaegertracing.io/docs/architecture/).

The most fundamental concept in OpenTracing is of course a trace, that describes the execution flow of a business transaction through the components of an application. The parts of an overall business transaction are called „span“, which can denote a component invocation of an application component or an arbitrary unit of work which makes sense in this application’s context. These spans have relationships which are typically derived from the execution flow of the application components. An overview of the relationship types (causal and temporal) are shown in the figures below (taken from the OpenTracing specification).

The most obvious relationship type might be the temporal one, as it describes when a span started or ended within the timeframe of the overall transaction:

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus

Another relationship type is the causal relationship which is not always as obvious as the temporal one, as it denotes the cause and effect between spans. Some key cause and effect relationships are denoted by the OpenTracing specification as follows (this is the same transaction trace as the one for the temporal relationships before):

Open Application Performance Monitoring (APM) Standards - OpenTracing and OpenCensus

In order to use OpenTracing in your application, there are multiple language bindings for the API provided by the OpenTracing project (visit http://opentracing.io/ for a complete and up-to-date list), in the following we will show you how to use OpenTracing using Java.

If you want to create a transaction consisting of spans, you need to write the code shown below. The only classes which are used by the application are  io.opentracing.util.GlobalTracer and io.opentracing.Span, no other API is required.

try (Span parent = GlobalTracer.get().buildSpan(„hello“).start()) {
try (Span child = GlobalTracer.get().buildSpan(„world“).asChildOf(parent).start()) { … }
}

In order for your traces to be collected by an APM implementation, it needs to be registered once. This registration differs a bit depending on the solution but in the following code listing you can find an example of binding an application to the Jaeger APM implementation. You only have one APM-specific class in our code in this case, which is the com.uber.jaeger.Configuration class that is required for the connection configuration to Jaeger but all other classes in your code are vendor independent and allow you to simply change this registration code to use another APM solution.

GlobalTracer.register( new Configuration(„your_service_name“,new Configuration.SamplerConfiguration(„const“, 1), new Configuration.ReporterConfiguration(false, „localhost“, null, 1000, 10000)).getTracer());

OpenCensus

As mentioned earlier in the description of its scope, OpenCensus does a lot more than providing a tracing API but in order to compare both standards head-to-head, we will focus on the tracing API in this blog article. For other aspects of OpenCensus, please consult its website: https://opencensus.io/overview/index.html.  The code for adding traces to your application is quite similar for OpenCensus (adapted from https://opencensus.io/java/index.html and https://github.com/census-instrumentation/opencensus-java/blob/master/examples/src/main/java/io/opencensus/examples/trace/MultiSpansTracing.java):

io.opencensus.trace.Tracer tracer = io.opencensus.trace.Tracer.getTracer();

io.opencensus.trace.Span rootSpan = tracer.spanBuilderWithExplicitParent(„MyRootSpan“, null).startSpan();
io.opencensus.trace.Span childSpan = tracer.spanBuilderWithExplicitParent(„MyChildSpan“, rootSpan).startSpan();
childSpan.end();
rootSpan.end();

In order to export the data to different endpoints OpenCensus supports different Exporters to which the OpenCensus implementation pushes the data. The list of available Exporters is published on the OpenCensus website as part of the roadmap: https://opencensus.io/roadmap/index.html

In the following example, we use the Zipkin exporter for OpenCensus which can be found here: https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/trace/zipkin

io.opencensus.exporter.trace.zipkin.ZipkinTraceExporter.createAndRegister("http://127.0.0.1:9411/api/v2/spans", "my-service");

Summary

As the examples show, the code for adding traces in your application or registering a new APM tool is not that much different between OpenCensus and OpenTracing. Or at least it does not differ in a way that coding effort is a key differentiator. What makes the most difference between both standards is the technology support. OpenTracing has a language binding for 9 different programming languages and at least 10 APM solutions that implement this standard at the time of writing this article. OpenCensus supports seven different programming languages and officially supports five exporters as of today. However, OpenCensus also provides support for metrics and additional features compared to OpenTracing. Therefore, time will tell which of both standards will gain more adoption. At the moment it seems that OpenTracing’s approach to focus on one thing – transaction tracing – and just provide an API seems to gain a lot more attention than the heavier approach of OpenCensus.