如何调试开放遥测java代理扩展插装?

ruarlubt  于 2023-03-21  发布在  Java
关注(0)|答案(2)|浏览(191)

我尝试遵循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引用它来运行应用程序,当我击中端点,它似乎工作和其他指标导出。任何人都有任何建议,如何调试这个或如果你知道我做错了什么,请让我知道,谢谢!!

4xrmg8kj

4xrmg8kj1#

你试过使用javaagent调试模式吗?它非常冗长,但应该会打印一些有用的输出。
你不应该将任何状态或依赖项放入TypeInstrumentation类中(也不应该放入advice类中)。所有应该注入到应用程序代码中的代码必须保存在单独的类中。在TypeInstrumentation实现中的telemetrymeterclick字段在通知类中是不可见的。我建议将所有逻辑提取到单独的帮助类中,然后从通知中调用该类。
有关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如何正确实现InstrumentationModuleTypeInstrumentation s和advice类的更详细说明,请参阅www.example.com。
除此之外,buildObserver()ObservableLongMeasurement只应该在BatchCallback中使用。如果您直接在advice类中调用它,它将不会注册任何内容;使用build()LongCounter代替。

ajsxfq5m

ajsxfq5m2#

你必须在应该提到DemoHelloWorldInstrumentation类的地方添加InstrumentationModule

@AutoService(InstrumentationModule.class)
public class Module extends InstrumentationModule {

    public Module() {
        super("some-name");
    }

    @Override
    public List<TypeInstrumentation> typeInstrumentations() {
        return List.of(
                new DemoHelloWorldInstrumentation());
    }

}

相关问题