Surabhi Patel
Surabhi Patel

Reputation: 31

How to use extensions in OpenTelemetry java for auto-instrumentation

I have created a my custom extension with below custom spanProcessor with customizerProvider. I am providing my custom span processor in my tracerProvider.

I am running my extensions and java-agent with below cmd:

java -javaagent:C:/Users/abc/Desktop/auto-instrumentation/src/opentelemetry-javaagent.jar \
-Dotel.javaagent.extensions=C:/Users/abc/Desktop/auto-instrumentation/src/extension_example-1.0-SNAPSHOT.jar \
-Dotel.exporter.jaeger.endpoint=http://localhost:4317 \
-Dotel.traces.exporter=otlp \
-Dotel.metrics.exporter=none \
-Dotel.resource.attributes="service.name=MyApp" \
-jar MyApp-0.0.1-SNAPSHOT.jar \

my jaeger backend is not showing my spanProcessor attribute. It is only showing default span attributes. I even don't see any indication that my extension is loaded. can any body help me?

SpanProcessor class:

package org.example.javaagent;

import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SpanProcessor;

public class ExampleSpanProcessor implements SpanProcessor {
    
    @Override
        public void onStart(Context parentContext, ReadWriteSpan span) {
            span.setAttribute("customAttribute", "customValue");
        }

        @Override
        public boolean isStartRequired() {
            return true;
        }

        @Override
        public void onEnd(ReadableSpan span) {}

        @Override
        public boolean isEndRequired() {
            return false;
        }

        @Override
        public CompletableResultCode shutdown() {
            return CompletableResultCode.ofSuccess();
        }

        @Override
        public CompletableResultCode forceFlush() {
            return CompletableResultCode.ofSuccess();
        }
}

CustomizerProvider class:

package org.example.javaagent;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;

import java.util.HashMap;
import java.util.Map;

@AutoService(AutoConfigurationCustomizerProvider.class)
public class ExampleAutoConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider {

    @Override
    public void customize(AutoConfigurationCustomizer autoConfiguration) {
        System.out.printf("Called customize extension method");

        autoConfiguration
                .addTracerProviderCustomizer(this::configureSdkTracerProvider)
                .addPropertiesSupplier(this::getDefaultProperties);
    }

    private SdkTracerProviderBuilder configureSdkTracerProvider(
            SdkTracerProviderBuilder tracerProvider, ConfigProperties config) {

        return tracerProvider
                .setSpanLimits(SpanLimits.builder().setMaxNumberOfAttributes(1024).build())
                .addSpanProcessor(new ExampleSpanProcessor());
    }

    private Map<String, String> getDefaultProperties() {
        Map<String, String> properties = new HashMap<>();
        properties.put("otel.exporter.otlp.endpoint", "http://backend:8080");
        properties.put("otel.exporter.otlp.insecure", "true");
        properties.put("otel.config.max.attrs", "16");
        return properties;
    }
}

I hit the http://localhost:8080/myapp, but it is showing span which was collectedby javaagent and not my custome span which is customeAttribute: customeValue. It is not showing my print statement in console that my extension is called. So How do I get to know whether my extension is executed or not

Upvotes: 3

Views: 2636

Answers (2)

alexSunder
alexSunder

Reputation: 412

Did you check the version of the OpenTelemetry java agent that is used?

In my case the reasone why extention did't work was in that on the project Spring Boot version 3.2.2 is used with it spring-boot-dependencies bom.
spring-boot-dependencies version 3.2.2 brings opentelemetry-bom 1.31.0 to the project dependencies, which is why I used the same version of the OpenTelemetry java agent.

But in the extension examples from https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/examples/extension OpenTelemetry java agent version 2.x.x is used.
So you need to check out on github to the corresponding version which matches the version of your OpenTelemetry java agent, because extension configuration is different.
In 1.3.x version you don't need to use @AutoService.
Insead of this you need to add META-INF/services folder into projects resources folder and add to this folder io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider file with following content:

org.example.javaagent.ExampleAutoConfigurationCustomizerProvider

Upvotes: 0

Gregor Zeitlinger
Gregor Zeitlinger

Reputation: 439

As already said in the comment, https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/examples/extension is the right starting point to create an extension.

  • it doesn't matter if you use gradle or maven
  • @AutoService takes case of creating the lookup file using an annotation processor - maybe this was missing - but it's totally fine to just create the lookup file manually

Upvotes: 0

Related Questions