My Test Main:
Код: Выделить всё
package org.example;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.time.Duration;
/**
* @author David Dvash
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
while (true) {
System.out.println("Going to sleep");
Thread.sleep(10000);
printHello1("Hello");
}
}
public static void printHello1(String name) {
printHello2(name);
}
public static void printHello2(String name) {
System.out.println("Hello, " + name);
}
}
Код: Выделить всё
package org.example;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import java.util.List;
import static java.util.Collections.singletonList;
/**
* @author David Dvash
*/
@AutoService(InstrumentationModule.class)
public class AllMethodsInstrumentationModule extends InstrumentationModule {
public AllMethodsInstrumentationModule() {
super("otel-extension", "otelextension");
System.out.println("In AllMethodsInstrumentationModule Constructor");
}
@Override
public int order() {
return 1;
}
@Override
public List getAdditionalHelperClassNames() {
return List.of(AllMethodsInstrumentation.class.getName(),
"io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation",
MethodSpanAdvice.class.getName());
}
@Override
public ElementMatcher.Junction classLoaderMatcher() {
return ElementMatchers.any();
}
@Override
public List typeInstrumentations() {
return singletonList(new AllMethodsInstrumentation());
}
}
Код: Выделить всё
package org.example;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
/**
* @author David Dvash
*/
@AutoService(TypeInstrumentation.class)
public class AllMethodsInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher classLoaderOptimization() {
System.out.println("in classLoaderOptimization");
// Match all class loaders
return ElementMatchers.any();
}
@Override
public ElementMatcher typeMatcher() {
System.out.println("in typeMatcher");
// Match all classes
return ElementMatchers.any();
}
@Override
public void transform(TypeTransformer transformer) {
System.out.println("in transform");
transformer.applyAdviceToMethod(
ElementMatchers.any(),
MethodSpanAdvice.class.getName()
);
}
}
Код: Выделить всё
package org.example;
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;
import net.bytebuddy.asm.Advice;
/**
* @author David Dvash
*/
public class MethodSpanAdvice {
// This advice is added at the beginning of the instrumented method (OnMethodEnter).
// It creates and starts a new span, and makes it active.
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Scope onEnter(@Advice.Local("otelSpan") Span span) {
// Get a Tracer instance from OpenTelemetry.
Tracer tracer = GlobalOpenTelemetry.getTracer("instrumentation-library-name", "semver:1.0.0");
System.out.print("Entering method");
// Start a new span with the name "mySpan".
span = tracer.spanBuilder("mySpan").startSpan();
// Make this new span the current active span.
Scope scope = span.makeCurrent();
// Return the Scope instance. This will be used in the exit advice to end the span's scope.
return scope;
}
// This advice is added at the end of the instrumented method (OnMethodExit).
// It first closes the span's scope, then checks if any exception was thrown during the method's execution.
// If an exception was thrown, it sets the span's status to ERROR and ends the span.
// If no exception was thrown, it sets a custom attribute "wordCount" on the span, and ends the span.
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void onExit(@Advice.Return(readOnly = false) int wordCount,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Enter Scope scope) {
// Close the scope to end it.
scope.close();
// If an exception was thrown during the method's execution, set the span's status to ERROR.
if (throwable != null) {
span.setStatus(StatusCode.ERROR, "Exception thrown in method");
} else {
// If no exception was thrown, set a custom attribute "wordCount" on the span.
span.setAttribute("wordCount", wordCount);
}
// End the span. This makes it ready to be exported to the configured exporter (e.g., Jaeger, Zipkin).
span.end();
}
}
Код: Выделить всё
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation group: 'net.bytebuddy', name: 'byte-buddy', version: '1.15.3'
implementation group: 'io.opentelemetry', name: 'opentelemetry-api', version: '1.42.1'
implementation 'io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:2.8.0-alpha'
// https://mvnrepository.com/artifact/io.opentelemetry.javaagent/opentelemetry-javaagent-tooling
implementation 'io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:2.8.0-alpha'
// https://mvnrepository.com/artifact/com.google.auto.service/auto-service
implementation 'com.google.auto.service:auto-service:1.1.1
}
test {
useJUnitPlatform()
}
Я знаю, что агент работает правильно, потому что я добавил несколько трассировок вручную и смог увидеть их в Grafana (используя Tempo). Однако я не вижу никаких следов, которые ожидал увидеть от расширения. Что не так с моим расширением?
Подробнее здесь: https://stackoverflow.com/questions/791 ... oesnt-work