我尝试遵循the open telemetry auto instrumentation java agent extension,并得出以下插装代码:
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package com.example.javaagent.instrumentation;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
public class DemoHelloWorldInstrumentation implements TypeInstrumentation {
private static String CLASS_NAME = "my.package.MyClass";
private static OpenTelemetry telemetry = GlobalOpenTelemetry.get();
private static Meter meter = telemetry.getMeterProvider().meterBuilder(CLASS_NAME).build();
private static ObservableLongMeasurement click =
meter
.counterBuilder("click")
.setUnit("counter")
.setDescription("Number of click")
.buildObserver();
;
static {
meter.batchCallback(
() -> {
click.record(1, Attributes.of(stringKey("none"), "none"));
},
click);
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return AgentElementMatchers.hasSuperType(namedOneOf(CLASS_NAME));
}
@Override
public void transform(TypeTransformer typeTransformer) {
typeTransformer.applyAdviceToMethod(
namedOneOf("sayHello"), this.getClass().getName() + "$GreetingAdvice");
}
@SuppressWarnings("unused")
public static class GreetingAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(@Advice.Argument(value = 0) String name) {
System.out.println("inst name = " + name);
click.record(1, Attributes.of(stringKey("name"), name));
}
}
}
我期待一些指标将导出name = click
,但既没有指标得到导出,也没有println
在标准输出中输出任何东西。我已经检查并确保命名是正确的。它似乎在开放的遥测扩展项目中构建良好,我可以使用-Dotel.javaagent.extensions=/path/to/my/extension.jar
引用它来运行应用程序,当我击中端点,它似乎工作和其他指标导出。任何人都有任何建议,如何调试这个或如果你知道我做错了什么,请让我知道,谢谢!!
2条答案
按热度按时间4xrmg8kj1#
你试过使用javaagent调试模式吗?它非常冗长,但应该会打印一些有用的输出。
你不应该将任何状态或依赖项放入
TypeInstrumentation
类中(也不应该放入advice类中)。所有应该注入到应用程序代码中的代码必须保存在单独的类中。在TypeInstrumentation
实现中的telemetry
,meter
,click
字段在通知类中是不可见的。我建议将所有逻辑提取到单独的帮助类中,然后从通知中调用该类。有关https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/contributing/writing-instrumentation-module.md#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes如何正确实现
InstrumentationModule
、TypeInstrumentation
s和advice类的更详细说明,请参阅www.example.com。除此之外,
buildObserver()
和ObservableLongMeasurement
只应该在BatchCallback
中使用。如果您直接在advice类中调用它,它将不会注册任何内容;使用build()
和LongCounter
代替。ajsxfq5m2#
你必须在应该提到
DemoHelloWorldInstrumentation
类的地方添加InstrumentationModule
: