当前位置: 首页 > 知识库问答 >
问题:

删除向导指标注释@Timed不起作用

汤承德
2023-03-14

我正在尝试使用@Timed等注释(http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/annotation/package-summary.html)自动将指标发布到我的指标注册。

这不是开箱即用的。在搜索问题时,我发现了Codahale Metrics:在普通Java中使用@Timed metrics注释,其中提到唯一可行的方法是使用aspectj。我将它添加到了我的项目中,但是在MetricRegistry中仍然看不到我的指标。

这是我的pom文件。我添加了librato库,它加载在< code > com . coda hale . metrics:metrics-annotation 中。

<dependency>
  <groupId>io.astefanutti.metrics.aspectj</groupId>
  <artifactId>metrics-aspectj</artifactId>
  <version>${metrics-aspectj.version}</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.8.10</version>
</dependency>

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <configuration>
      <showWeaveInfo>true</showWeaveInfo>
      <source>1.8</source>
      <target>1.8</target>
      <complianceLevel>1.8</complianceLevel>
      <encoding>UTF-8</encoding>
      <verbose>true</verbose>
      <aspectLibraries>
        <aspectLibrary>
          <groupId>io.astefanutti.metrics.aspectj</groupId>
          <artifactId>metrics-aspectj</artifactId>
        </aspectLibrary>
      </aspectLibraries>
    </configuration>
    <executions>
      <execution>
        <phase>process-sources</phase>
        <goals>
          <goal>compile</goal>
          <goal>test-compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

<dependency>
  <groupId>com.librato.metrics</groupId>
  <artifactId>metrics-librato</artifactId>
  <version>${metrics-librato.version}</version>
</dependency>

这就是我试图使用指标的方式

@Metrics(registry = "default") // this.metricRegistry is default
public class Foo {
    @Inject
    private MetricRegistry metricRegistry;
    ...

    @Metered(name = "meterName")
    public void bar() {
        Meter meter = metricRegistry.meter("manual");
        meter.mark();
        // this.metricRegistry does not contain "meterName" after the ConsoleReporter prints the metrics for "default"
        // this.metricRegistry contains "manual" after the ConsoleReporter prints the metrics for "default"
    }

当我编译时,我在日志中看到了这一点:

[INFO] Extending interface set for type 'Foo' (Foo.java) to include 'io.astefanutti.metrics.aspectj.Profiled' (MetricAspect.aj)
[INFO] Type 'Foo' (Foo.java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'java.util.Map<java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Gauge>> io.astefanutti.metrics.aspectj.Profiled.gauges')
[INFO] Type 'Foo' (Foo.java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'java.util.Map<java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Meter>> io.astefanutti.metrics.aspectj.Profiled.meters')
[INFO] Type 'Foo' (Foo.java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'java.util.Map<java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Timer>> io.astefanutti.metrics.aspectj.Profiled.timers')
[INFO] Join point 'staticinitialization(void Foo.<clinit>())' in Type 'Foo' (Foo.java:46) advised by after advice from 'io.astefanutti.metrics.aspectj.MetricStaticAspect' (metrics-aspectj-1.2.0.jar!MetricStaticAspect.class:41(from MetricStaticAspect.aj))
[INFO] Join point 'method-execution(void Foo.bar())' in Type 'Foo' (Foo.java:74) advised by around advice from 'io.astefanutti.metrics.aspectj.TimedAspect' (metrics-aspectj-1.2.0.jar!TimedAspect.class:26(from TimedAspect.aj))
[INFO] Join point 'method-execution(void Foo.bar())' in Type 'Foo' (Foo.java:74) advised by before advice from 'io.astefanutti.metrics.aspectj.MeteredAspect' (metrics-aspectj-1.2.0.jar!MeteredAspect.class:26(from MeteredAspect.aj))

这似乎表明我设置的带注释的指标工作正常。然而,我也在我的日志中看到了这一点

[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedStaticAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredStaticAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedStaticAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.MetricAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MetricAspect.class:45

[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.class:26

[WARNING] advice defined in io.astefanutti.metrics.aspectj.MetricStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MetricStaticAspect.class:41

[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
    /Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredStaticAspect.class:26

这是我的应用程序设置

@Override
public void run(AppConfiguration configuration, Environment environment) {

    ConsoleReporter reporter = ConsoleReporter.forRegistry(environment.metrics())
            .convertRatesTo(TimeUnit.SECONDS)
            .convertDurationsTo(TimeUnit.MILLISECONDS)
            .build();
    reporter.start(2, TimeUnit.MINUTES);
}

共有2个答案

邓威
2023-03-14

您面临的问题是AspectJ advice使用的< code>MetricRegistry实例不同于您用于手动计量测试和< code>ConsoleReporter的实例。

由于您的问题没有指定@Inject-edMetricRegistry实例的来源,因此我只能推测它与您使用的ConsoleReporter,但很可能与AspectJ建议使用的“default”注册表不同。AspectJ建议使用的方法是通过

SharedMetricRegistries.getOrCreate("default");

为了解决您的问题,您应该:

>

  • 通过使用首选的依赖关系注入框架使用工厂方法的方式(对于 Spring,@Bean @Produces对于 CDI),确保@Inject指标注册实例和由环境.metrics() 返回的实例与共享指标注册.getOrCreate(“默认”)相同。

    Foo 类中使用 EL 表达式@Metrics注释的注册表值,如下所示:

    @Metrics(registry = "${this.metricRegistry}")
    

    为上面引用的< code>metricRegistry属性提供一个getter:

    public MetricRegistry getMetricRegistry() {
        return this.metricRegistry;
    }
    

    并确保项目中具有所需的 EL 库:

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.1-b09</version>
    </dependency>
    

  • 孟高峰
    2023-03-14

    我刚刚尝试了这个,效果很好。这是我的整个设置:

    pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany.app</groupId>
        <artifactId>my-app</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>my-app</name>
        <url>http://maven.apache.org</url>
    
    
        <dependencies>
    
            <dependency>
                <groupId>io.astefanutti.metrics.aspectj</groupId>
                <artifactId>metrics-aspectj</artifactId>
                <version>1.2.0</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <configuration>
                        <aspectLibraries>
                            <aspectLibrary>
                                <groupId>io.astefanutti.metrics.aspectj</groupId>
                                <artifactId>metrics-aspectj</artifactId>
                            </aspectLibrary>
                        </aspectLibraries>
                        <complianceLevel>1.8</complianceLevel>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4.1</version>
                    <configuration>
                        <!-- get all project dependencies -->
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <!-- MainClass in mainfest make a executable jar -->
                        <archive>
                            <manifest>
                                <mainClass>com.mkyong.core.utils.App</mainClass>
                            </manifest>
                        </archive>
    
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <!-- bind to the packaging phase -->
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    注意,我需要添加< code > AspectJ-maven-plugin 。我还添加了一个< code>assembly插件,以便稍后测试。这真的没有必要,我只是不想去寻找本地机器上的依赖项。

    我的定时课:

    package com.mycompany.app;
    
    import java.util.concurrent.ThreadLocalRandom;
    
    import com.codahale.metrics.annotation.Timed;
    
    import io.astefanutti.metrics.aspectj.Metrics;
    @Metrics(registry = "someMetrics")
    public class TimedClass {
    
        @Timed(name = "test")
        public void doSomething() {
            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
            }
            System.out.println("Done");
        }
    
        @Timed(name = "test-random")
        public void doSomething2() {
            try {
                Thread.sleep(ThreadLocalRandom.current().nextLong(100L));
            } catch (InterruptedException e) {
            }
            System.out.println("Done");
        }
    }
    

    和应用程序:

    package com.mycompany.app;
    
    import java.util.concurrent.TimeUnit;
    
    import com.codahale.metrics.ConsoleReporter;
    import com.codahale.metrics.MetricRegistry;
    import com.codahale.metrics.SharedMetricRegistries;
    public class App {
    
        public static void main(String[] args) throws InterruptedException {
            MetricRegistry metrics =
                    SharedMetricRegistries.getOrCreate("someMetrics");
    
            ConsoleReporter.forRegistry(metrics)
            .convertRatesTo(TimeUnit.SECONDS)
            .convertDurationsTo(TimeUnit.MILLISECONDS)
            .build()
            .start(1, TimeUnit.SECONDS);
    
            TimedClass c = new TimedClass();
            for(int i = 0; i < 10; i++) {
                c.doSomething();
                c.doSomething2();
            }
            c.doSomething();
            Thread.sleep(1010L);
        }
    }
    

    这里发生的是,在编译方面的maven插件时,将找到您使用的注释并应用方面。

    例如,在您(和我)的情况下,来自度量方面源:

    final aspect TimedAspect {
    
        pointcut timed(Profiled object) : execution(@Timed !static * (@Metrics Profiled+).*(..)) && this(object);
    
        Object around(Profiled object) : timed(object) {
            String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString();
            Timer timer = object.timers.get(methodSignature).getMetric();
            Timer.Context context = timer.time();
            try {
                return proceed(object);
            } finally {
                context.stop();
            }
        }
    }
    

    以上所做的就是说:

    任何非静态且具有@Timed注释的方法都应在“周围”方法中执行。

    现在,您可以通过以下操作编译和打包它:

    mvn干净安装包

    这将为未应用的方面打印一堆警告,但这完全没问题(我们实际上并没有使用它们)。

    此外,您现在有了一个包含您的应用程序的fat-jar,您可以执行它来查看我们所做的工作是否有效:

    <code>java-cp target/my-app-1.0-SNAPSHOT-jar-with-dependencies。jar com.mycompany.app.app

    其将打印:

    artur@pdb-ct ~/dev/repo/my-app $ java -cp target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar com.mycompany.app.App
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    04/01/18 15:10:42 ==============================================================
    
    -- Timers ----------------------------------------------------------------------
    com.mycompany.app.TimedClass.test
                 count = 4
             mean rate = 4.11 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 200.21 milliseconds
                   max = 200.37 milliseconds
                  mean = 200.29 milliseconds
                stddev = 0.06 milliseconds
                median = 200.25 milliseconds
                  75% <= 200.32 milliseconds
                  95% <= 200.37 milliseconds
                  98% <= 200.37 milliseconds
                  99% <= 200.37 milliseconds
                99.9% <= 200.37 milliseconds
    com.mycompany.app.TimedClass.test-random
                 count = 4
             mean rate = 4.10 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 20.41 milliseconds
                   max = 32.28 milliseconds
                  mean = 26.07 milliseconds
                stddev = 4.56 milliseconds
                median = 28.26 milliseconds
                  75% <= 32.28 milliseconds
                  95% <= 32.28 milliseconds
                  98% <= 32.28 milliseconds
                  99% <= 32.28 milliseconds
                99.9% <= 32.28 milliseconds
    
    
    Done
    Done
    Done
    Done
    Done
    Done
    Done
    04/01/18 15:10:43 ==============================================================
    
    -- Timers ----------------------------------------------------------------------
    com.mycompany.app.TimedClass.test
                 count = 8
             mean rate = 4.06 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 200.16 milliseconds
                   max = 200.37 milliseconds
                  mean = 200.25 milliseconds
                stddev = 0.06 milliseconds
                median = 200.25 milliseconds
                  75% <= 200.26 milliseconds
                  95% <= 200.37 milliseconds
                  98% <= 200.37 milliseconds
                  99% <= 200.37 milliseconds
                99.9% <= 200.37 milliseconds
    com.mycompany.app.TimedClass.test-random
                 count = 7
             mean rate = 3.55 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 20.41 milliseconds
                   max = 97.20 milliseconds
                  mean = 43.68 milliseconds
                stddev = 28.17 milliseconds
                median = 28.26 milliseconds
                  75% <= 76.30 milliseconds
                  95% <= 97.20 milliseconds
                  98% <= 97.20 milliseconds
                  99% <= 97.20 milliseconds
                99.9% <= 97.20 milliseconds
    
    
    Done
    Done
    Done
    Done
    Done
    Done
    04/01/18 15:10:44 ==============================================================
    
    -- Timers ----------------------------------------------------------------------
    com.mycompany.app.TimedClass.test
                 count = 11
             mean rate = 3.70 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 200.13 milliseconds
                   max = 200.37 milliseconds
                  mean = 200.23 milliseconds
                stddev = 0.07 milliseconds
                median = 200.21 milliseconds
                  75% <= 200.26 milliseconds
                  95% <= 200.37 milliseconds
                  98% <= 200.37 milliseconds
                  99% <= 200.37 milliseconds
                99.9% <= 200.37 milliseconds
    com.mycompany.app.TimedClass.test-random
                 count = 10
             mean rate = 3.37 calls/second
         1-minute rate = 0.00 calls/second
         5-minute rate = 0.00 calls/second
        15-minute rate = 0.00 calls/second
                   min = 15.19 milliseconds
                   max = 97.20 milliseconds
                  mean = 48.90 milliseconds
                stddev = 30.99 milliseconds
                median = 32.28 milliseconds
                  75% <= 76.30 milliseconds
                  95% <= 97.20 milliseconds
                  98% <= 97.20 milliseconds
                  99% <= 97.20 milliseconds
                99.9% <= 97.20 milliseconds
    

    几点:

    这在Eclipse中不起作用。你将不得不安装一个扩展来让它工作(我还没有试过),看这里:

    https://github.com/astefanutti/metrics-aspectj/blob/master/README.md

    有关如何使用 AJDT 的说明:

    https://www.ibm.com/developerworks/library/j-ajdt/

    原因是(模糊的,因为我没有花太多时间在这上面)这些方面是在编译时应用的,而不是在运行时。Eclipse 在 IDE 中运行时使用自己的编译器,因此它只执行您的代码。但是,pom文件中的maven插件是在编译代码时应用这些方面的。

    我希望这有所帮助,

    附言原谅我的命名/包装-我使用了默认的maven生成器

    阿图尔

    跟进:

    要添加dropwizard指标,如果您想使用上述解决方案,您可以将其添加到共享指标中。例如:

            MetricRegistry myCustomRegistry = new MetricRegistry();
            SharedMetricRegistries.add("my-metric-registry", myCustomRegistry);
    

    在您的例子中,这将来自<code>environment()。metrics()或类似。

     类似资料:
    • 我有一个简单的类叫BeaconDao 然而,当我用@service或@component标记beaconDao时,一切都运行得非常好。有人能看出问题所在吗?

    • 问题内容: 我正在尝试使用Java批注,但似乎无法使我的代码认识到其中存在。我究竟做错了什么? 问题答案: 您需要使用注释界面上的@Retention注释将注释指定为运行时注释。 即

    • 问题内容: 我知道有一些关于此的帖子,但是它们大约一年了,没有任何回应。实际上,我们在PostgreSQL 8.4上使用的是Hibernate 4.2.1.Final。我们有两个这样的实体 实体A(顶级层次结构类) 实体B(子类) 如您所见,使用注释了一个实体,但是当使用来获取顶级类时 我们也通过属性获得了B子类。实际上,SQL语句包含。这仍然是Hibernate第四版中的错误,还是我做错了什么?

    • 问题内容: 我从Spring Framework开始,想做一个带有注释的HelloWorld,我已经创建了一个控制器和一个视图,我猜它是基本的hello工作。但是,我想使用注释,因为我不能再使用SimpleFormController(已弃用)。 我收到的错误是Estado HTTP 404-/av/index.jsp 我正在使用Netbeans,并将示例基于它提供的基本模板。我有以下文件,我可以

    • 接口说明 该接口已经废弃,请使用【单体化、标绘、压平 -> GEOJSON上传】接口 如果出现标记有误或者不想在对某个位置进行标记,可以调用该接口来删除标记的位置 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 API地址 POST /api/marker/1.0.0/del 是否需要登录 是 请求字段说明 参数 类型 请求类型 是否必须 说明 id s