Skip to content

Java Instrumentation

Subscription required

This section describes functionality which requires an active DeepCube subscription. Start your subscription by choosing the plan right for you.

Instrument your Java applications with OpenTelemetry to send traces, metrics, and logs to DeepCube. This guide covers the Java agent for auto-instrumentation, Spring Boot setup, and manual SDK usage.

Back to Instrument Overview

The OpenTelemetry Java agent provides automatic instrumentation for most popular frameworks and libraries with zero code changes.

Download the Agent

curl -L -o opentelemetry-javaagent.jar \
  https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

Run with the Agent

java -javaagent:opentelemetry-javaagent.jar \
  -Dotel.exporter.otlp.endpoint=https://otlp.deepcube.ai \
  -Dotel.exporter.otlp.headers=api-key=YOUR-API-KEY \
  -Dotel.service.name=my-java-app \
  -jar your-application.jar

The agent automatically instruments:

  • Spring Web MVC, WebFlux
  • JAX-RS
  • Servlet API
  • JDBC, Hibernate
  • Kafka, RabbitMQ
  • gRPC
  • HTTP clients (Apache HttpClient, OkHttp, java.net.HttpClient)
  • And many more

Approach 2: Spring Boot Starter

For Spring Boot applications, you can use the OpenTelemetry Spring Boot starter instead of the Java agent:

Maven

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-instrumentation-bom</artifactId>
            <version>2.12.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>io.opentelemetry.instrumentation</groupId>
        <artifactId>opentelemetry-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

Gradle

implementation platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.12.0")
implementation "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter"

Spring Boot Configuration

Configure in application.yml:

otel:
  exporter:
    otlp:
      endpoint: https://otlp.deepcube.ai
      headers:
        api-key: YOUR-API-KEY
  service:
    name: my-spring-boot-app

Or in application.properties:

otel.exporter.otlp.endpoint=https://otlp.deepcube.ai
otel.exporter.otlp.headers.api-key=YOUR-API-KEY
otel.service.name=my-spring-boot-app

Approach 3: Manual Instrumentation with SDK

For full control, configure the OpenTelemetry SDK programmatically.

Maven Dependencies

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.46.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-otlp</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
    </dependency>
</dependencies>

Gradle Dependencies

implementation platform("io.opentelemetry:opentelemetry-bom:1.46.0")
implementation "io.opentelemetry:opentelemetry-api"
implementation "io.opentelemetry:opentelemetry-sdk"
implementation "io.opentelemetry:opentelemetry-exporter-otlp"
implementation "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure"

SDK Initialization

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.semconv.ResourceAttributes;

public class OtelConfig {

    public static OpenTelemetry initialize() {
        Resource resource = Resource.getDefault()
            .merge(Resource.builder()
                .put(ResourceAttributes.SERVICE_NAME, "my-java-app")
                .put(ResourceAttributes.SERVICE_VERSION, "1.0.0")
                .build());

        // Trace exporter
        OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder()
            .setEndpoint("https://otlp.deepcube.ai")
            .addHeader("api-key", "YOUR-API-KEY")
            .build();

        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
            .setResource(resource)
            .addSpanProcessor(BatchSpanProcessor.builder(spanExporter).build())
            .build();

        // Metric exporter
        OtlpGrpcMetricExporter metricExporter = OtlpGrpcMetricExporter.builder()
            .setEndpoint("https://otlp.deepcube.ai")
            .addHeader("api-key", "YOUR-API-KEY")
            .build();

        SdkMeterProvider meterProvider = SdkMeterProvider.builder()
            .setResource(resource)
            .registerMetricReader(PeriodicMetricReader.builder(metricExporter).build())
            .build();

        OpenTelemetrySdk sdk = OpenTelemetrySdk.builder()
            .setTracerProvider(tracerProvider)
            .setMeterProvider(meterProvider)
            .buildAndRegisterGlobal();

        // Shut down providers on JVM exit
        Runtime.getRuntime().addShutdownHook(new Thread(sdk::close));

        return sdk;
    }
}

Creating Custom Spans

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;

public class OrderService {

    private static final Tracer tracer =
        GlobalOpenTelemetry.getTracer("com.myapp.orders");

    public Order processOrder(int orderId) {
        Span span = tracer.spanBuilder("processOrder")
            .setAttribute("order.id", orderId)
            .startSpan();