我正在尝试遵循开放遥测自动仪表java代理扩展,并提出了以下插装代码:
/*
* 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
的方式导出,但是这些度量既不会被导出,也不会在stdout中输出println
。我检查过了,确保名字是正确的。它似乎在开放的遥测扩展项目中构建了ok,我可以使用-Dotel.javaagent.extensions=/path/to/my/extension.jar
来引用它来运行应用程序,当我到达端点时,它似乎能工作,其他指标也可以导出。如果你知道我做错了什么,请告诉我,谢谢!
发布于 2022-10-17 08:22:59
你试过使用javaagent调试模式吗?它非常冗长,但是应该打印一些有用的输出。
您不应该将任何状态或依赖项放到TypeInstrumentation
类中(也不应该放在通知类中)。在OTel javaagent中,代理代码无法从应用程序代码中访问;所有应该注入应用程序代码的代码都必须保存在单独的类中。在您的建议类中,您在telemetry
、meter
、click
实现中的字段是不可见的。我建议将所有逻辑提取到单独的助手类,然后从通知中调用该类。
有关如何正确实现InstrumentationModule
、TypeInstrumentation
和通知类的更详细说明,请参见InstrumentationModule
。
除此之外,buildObserver()
和ObservableLongMeasurement
只应该在BatchCallback
中使用。如果直接在通知类中调用它,它将不会注册任何内容;而是使用build()
和LongCounter
。
https://stackoverflow.com/questions/74083208
复制相似问题