OpenTelemetry Instrumentation: Manual vs. Automatic (with Examples)

  • Topics

What Is OpenTelemetry Instrumentation? 

OpenTelemetry provides a set of APIs, libraries, and agents designed to capture, process, and export telemetry data from software applications. Instrumentation refers to ensuring an application’s code generates traces, metrics, and logs that make it observable.

The OpenTelemetry project is an open-source initiative to provide standard methods for collecting telemetry data, which is led by the Cloud Native Computing Foundation (CNCF). OpenTelemetry aims to provide a standardized, vendor-agnostic way of capturing telemetry data. It’s designed to work across different programming languages, platforms, and cloud environments.

There are three primary types of instrumentation supported by OpenTelemetry:

  • Manual instrumentation: Involves adding specific code snippets to your application to capture and send telemetry data. It can capture custom metrics specific to your application, like items in a shopping cart or the time it takes to perform a specific database query. Manual instrumentation provides a high level of control and flexibility but takes time to implement.
  • Automatic instrumentation: Involves using pre-built libraries or agents that automatically capture and send telemetry data without requiring you to modify your application’s code. It is typically used to capture standard metrics like CPU usage, memory usage, request latency, and error rates. This is less flexible than manual instrumentation but much simpler and quicker to implement.

OpenTelemetry supports using automated and manual instrumentation together for the same application. You can start by using automated instrumentation to get the basic metrics and then, over time, implement manual instrumentation to get additional metrics specific to your application.

Another option for instrumenting your applications is to inject auto-instrumentation with the OpenTelemetry Kubernetes Operator. The OpenTelemetry Operator manages the lifecycle of OpenTelemetry components within a Kubernetes environment, ensuring that they are correctly deployed, updated, and configured.

Working with Manual Instrumentation in OpenTelemetry 

Import the OpenTelemetry API and SDK

Start by importing the OpenTelemetry API and SDK. The OpenTelemetry API provides the interfaces and classes necessary for instrumentation, while the SDK provides the implementation of these interfaces.

To import the OpenTelemetry API and SDK, you’ll need to add the necessary dependencies to your project. If you’re using Maven, you would add the following to your pom.xml:

Note: You will need to have Maven and the Java Development Kit installed on your system.

<dependency>

    <groupId>io.opentelemetry</groupId>

    <artifactId>opentelemetry-api</artifactId>

    <version>VERSION</version>

</dependency>

<dependency>

    <groupId>io.opentelemetry</groupId>

    <artifactId>opentelemetry-sdk</artifactId>

    <version>VERSION</version>

</dependency>

Configure the OpenTelemetry API

Once you’ve imported the necessary dependencies, it’s time to configure the OpenTelemetry API. The API configuration controls how you interact with the OpenTelemetry system, allowing you to specify what kind of data you want to collect (traces, metrics, logs) and how that data should be collected.

Here’s an example of how you might configure the API:

OpenTelemetry.setGlobalTracerProvider(
    SdkTracerProvider.builder()
    .setSampler(Sampler.alwaysOn())
    .build()
);

In this example, we’re setting the global tracer provider to always sample traces. Every trace will be recorded, which can be useful for debugging but might be overkill for production systems.

Configure the OpenTelemetry SDK

With the API configured, we can now move on to configuring the OpenTelemetry SDK. The SDK configuration controls how the collected data is processed and exported. This includes the export format, the export destination, and the export interval.

Here is a basic SDK configuration:

OpenTelemetrySdk.builder()
    .setTracerProvider(tracerProvider)
    .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
    .buildAndRegisterGlobal();

In this example, we’re setting the tracer provider, setting the context propagators to use the W3C Trace Context Propagator, and registering the SDK configuration as the global configuration.

Create Telemetry Data

Once you have your API and SDK configured, you can start creating telemetry data. You can create spans representing operations within a trace and attach attributes, events, and status information to those spans.

Here’s an example of how you might create a span:

Tracer tracer = OpenTelemetry.getGlobalTracer("my-instrumentation-library-name","semver:1.0.0");
Span span = tracer.spanBuilder("my-operation").startSpan();
try (Scope scope = span.makeCurrent()) {
    // your code here
} catch (Throwable t) {
    span.setStatus(StatusCode.ERROR, "Change it to your error message");
} finally {
    span.end();
}

In this example, we’re creating a span for an operation named “my-operation”, executing some code within the span, and ending the span when we’re done.

Compile using the command maven clean install in the project directory.

Export Data

The final step is to export your telemetry data. OpenTelemetry supports various export formats and destinations, including Jaeger, Zipkin, Prometheus, and more. You can also write your exporter if you need to export data in a custom format or to a custom destination.

Here’s an example of how you might export data to Jaeger:

JaegerGrpcSpanExporter exporter =
    JaegerGrpcSpanExporter.builder()
    .setEndpoint("jaeger:14250")
    .build();

BatchSpanProcessor processor =
    BatchSpanProcessor.builder(exporter)
    .build();

OpenTelemetrySdk.getGlobalTracerManagement().addSpanProcessor(processor);

In this example, we’re creating a Jaeger exporter, setting the endpoint to “jaeger:14250”, creating a batch span processor that uses our exporter, and adding our processor to the global tracer management.

Automatically Instrumenting an Application with OpenTelemetry: Python Example 

Let’s take a closer look at how you can use automatic instrumentation in OpenTelemetry with Python. OpenTelemetry provides SDKs for several popular programming languages.

Setup

First, you need to install the OpenTelemetry Python library. You can do this using pip, the Python package manager:

pip install opentelemetry-api
pip install opentelemetry-sdk

Next, you need to install the specific instrumentation packages for your application’s libraries or frameworks. For example, if you’re using Flask, a popular web framework for Python, you would install the Flask instrumentation package:

pip install opentelemetry-instrumentation-flask

Configure the Agent

Once you’ve installed the necessary packages, you need to configure the OpenTelemetry agent. This involves specifying the configuration settings for the agent, such as the endpoint for exporting the telemetry data, the sampling rate, and any filters you want to apply to the data.

To configure the agent, you can use environment variables or a configuration file. For example, you can set the export endpoint and sampling rate like this:

export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_SAMPLING_RATE=0.5

This tells the agent to send the telemetry data to a local OpenTelemetry Collector instance and to sample 50% of the traces.

With the OpenTelemetry agent configured, your Python application is now ready to capture and send telemetry data automatically. You can start your application as usual, and the agent will automatically instrument your code and collect the telemetry data.

Related content: Read our guide to OpenTelemetry architecture

Microservices Monitoring with Lumigo

Lumigo is cloud native observability tool that provides automated distributed tracing of microservice applications and supports OpenTelemetry for reporting of tracing data and resources. With Lumigo, users can:

  • See the end-to-end path of a transaction and full system map of applications
  • Monitor and debug third-party APIs and managed services (ex. Amazon DynamoDB, Twilio, Stripe)
  • Go from alert to root cause analysis in one click
  • Understand system behavior and explore performance and cost issues 
  • Group services into business contexts

Get started with a free trial of Lumigo for your microservice applications

Debug fast and move on.

  • Resolve issues 3x faster
  • Reduce error rate
  • Speed up development
No code, 5-minute set up
Start debugging free