Pregunta Métrica de Codahale: utilizando la anotación de métricas @Timed en Java simple


Estoy tratando de agregar métricas a una aplicación Java simple utilizando métricas codahale. Me gustaría utilizar la anotación @Timed, pero no estoy seguro de qué MetricRegistry usa, ni de cómo indicar qué MetricRegistry usar. La aplicación es una aplicación Java 8 simple, construida con Maven 3, sin Spring, sin Hibernate.

No encuentro ninguna documentación sobre cómo implementar @Timed en la documentación de Dropwizard: https://dropwizard.github.io/metrics/3.1.0/manual/

He agregado estas dependencias:

<dependency>
  <groupId>io.dropwizard.metrics</groupId>
  <artifactId>metrics-core</artifactId>
  <version>3.1.0</version>
</dependency>
<dependency>
  <groupId>com.codahale.metrics</groupId>
  <artifactId>metrics-annotation</artifactId>
  <version>3.0.2</version>
</dependency>

Cuando uso una llamada de programación a Timer, puedo obtener informes porque sé qué MetricsRegistry se usa:

static final MetricRegistry metrics = new MetricRegistry();
private void update() throws SQLException {
  Timer.Context time = metrics.timer("domainobject.update").time();
  try {
    [...]
  } finally {
    time.stop();
  }
}

Pero cuando uso la anotación @Timed mucho más elegante, no tengo idea de qué registro se usa y, por lo tanto, no puedo crear un reportero, lo que significa que no puedo informar las métricas (ni siquiera estoy seguro de si esto realmente funciona). cualquier cosa):

@Timed(name = "domainobject.update")
private void update() throws SQLException {
    [...]
}

Indique cómo hacer que las anotaciones @Timed y otras métricas funcionen en una aplicación Java normal.

Información adicional: La razón por la que estoy encontrando esto extraño es porque he agregado el marco Lombok y las anotaciones @ Slf4j sí funcionan. Agregué Lombok como una dependencia en maven pom.xml:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.14.8</version>
</dependency>

Y puedo usar la anotación de clase @ Sl4fj para agregar un registrador a la clase sin saturar las variables miembro:

@Slf4j
public class App {
  public void logsome(){
    log.info("Hello there");
  }
}

Entonces, si eso es posible simplemente agregando una dependencia, creo que me falta una dependencia o configuración para que la anotación codahale @Timed funcione, como se describió anteriormente.

(por cierto, echa un vistazo a Lombok, te hará la vida más fácil: http://projectlombok.org/ )


32
2018-02-13 12:26


origen


Respuestas:


En resumen, no puedes usar @Timed sin algún tipo de AOP (ya sea Spring AOP o AspectJ).

Hace una o dos semanas, también decidí agregar métricas a nuestro proyecto y elegí AspectJ para esta tarea (principalmente porque lo usé en el pasado para fines similares y porque permite el tiempo de compilación, mientras que Spring solo permite el tiempo de ejecución por medio de proxies) .

Debería poder encontrar toda la información e instrucciones necesarias aquí: https://github.com/astefanutti/metrics-aspectj.

En cuanto a Lombok, creo que usan un procesador de anotaciones javac incorporado:

Otro punto de controversia es la implementación tanto del código que admite la integración IDE como del procesador de anotación javac. Ambas piezas del Proyecto Lombok hacen uso de API no públicas para realizar su hechicería. Esto significa que existe el riesgo de que el Proyecto Lombok se rompa con las versiones posteriores de IDE o JDK.


12
2018-02-14 11:35



Utilizando @Timed en realidad no requiere el uso de AOP, como se afirmó anteriormente en la respuesta mejor calificada, si está dentro de un contenedor y está utilizando una de las bibliotecas de instrumentación de Dropwizard. Ver el módulo Jersey 2.x, por ejemplo, que puedes ver utiliza la reflexión (como lo hacen los otros que miré), si lees el fuente.

Puede leer todos estos módulos en los documentos de Dropwizard bajo el correspondiente "Instrumentando ____" balas.

Entiendo que OP no funcionaba explícitamente en dicho contenedor, pero quería ofrecer esta información, ya que muchos de nosotros que buscamos esta respuesta podemos estar trabajando en un servicio web moderno que pueda registrar dichos recursos en su entorno de tiempo de ejecución.


10
2017-08-23 16:05



Use el MetricRegistry incorporado al cual se accede desde el parámetro bootstrap en el método de inicialización de su clase de aplicación.

@Override
public void initialize(final Bootstrap<Configuration> bootstrap) {
    final JmxReporter reporter = JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build();
    reporter.start();
}

5
2017-08-04 19:21



Como dijo la otra respuesta, debe tener algo en la aplicación para escuchar sus clases instanciadas y verificarlas para la anotación @Timed.

Si usas Guice, podrías usar: https://github.com/palominolabs/metrics-guice


3
2018-03-08 01:27



AOP es excesivo y no apropiado para el uso de @timed, generalmente   Hablando.

El registro de métricas predeterminado escribe @timed metrics en un ConcurrentHashMap y no adjunta ningún oyente significativo.

DropWizard Bootstrap constructor:

/**
 * Creates a new {@link Bootstrap} for the given application.
 * @param application a Dropwizard {@link Application}
 */
public Bootstrap(Application<T> application) {
    this.application = application;
    this.objectMapper = Jackson.newObjectMapper();
    this.bundles = Lists.newArrayList();
    this.configuredBundles = Lists.newArrayList();
    this.commands = Lists.newArrayList();
    this.validatorFactory = Validators.newValidatorFactory();


    // returns new ConcurrentHashMap<String, Metric>(); 
    this.metricRegistry = new MetricRegistry(); 


    this.configurationSourceProvider = new FileConfigurationSourceProvider();
    this.classLoader = Thread.currentThread().getContextClassLoader();
    this.configurationFactoryFactory = new DefaultConfigurationFactoryFactory<T>();
}

Por lo tanto, necesita compilar / iniciar / registrar el registro de métricas apropiado en   para ver resultados

Aquí uso JMX:

@Override
public void initialize(Bootstrap<PayloadStorageConfiguration> bootstrap) {
    JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build().start();
}

Eso es todo lo que necesitas hacer.

Aquí hay un ejemplo de la salida (ejecute jconsole contra su aplicación / servidor Java para ver los resultados de JMX):

enter image description here


3
2018-03-22 23:14



También puedes usar stagemonitor-core para eso. Ver documentación aquí y aquí. La ventaja es que el monitor de etapas (que es de fuente abierta y gratuita por cierto) no depende de ningún AOP basado en contenedor como los interceptores Spring AOP o EJB. Utiliza la manipulación de bytecode a través de un archivo adjunto en tiempo de ejecución, lo que significa que ni siquiera tiene que agregar un -javaagent señalar el inicio de la aplicación: basta con una simple dependencia.

Si desea medir el tiempo de ejecución en una aplicación web o en una aplicación EJB remota, ni siquiera tiene que anotar manualmente su código. Además, stagemonitor ofrece tableros preconfigurados de Grafana y Kibana.

Descargo de responsabilidad: soy uno de los desarrolladores de stagemonitor


0
2018-05-19 09:33



En las versiones más nuevas de Dropwizard (estoy usando 0.9.2), puedes acceder al predeterminado MetricRegistry a través del entorno de configuración io.dropwizard.setup.Environment. Este predeterminado MetricRegistry ya tiene una InstrumentedResourceMethodApplicationListener asociado con él, que escucha todas las métricas de sus recursos.

Si ha registrado un recurso con el JerseyEnvironment como debajo,

environment.jersey().register(resource);

solo necesita anotar su método de recursos (o clase) con @Timed, @Metered o @ExceptionMetered para registrar las métricas respectivas.

@POST
@Timed
public String show() {
    return "yay";
}

Puedes asignar un Reporter (como un Slf4jReporter o JmxReporter) al predeterminado MetricRegistry como bajo

Slf4jReporter.forRegistry(environment.metrics()).build();

Como una prueba rápida para ver si sus métricas han sido registradas, puede hacer una GET llamar a la URL http://localhost:8081/metrics o la URL de métrica de administración correspondiente en su entorno de prueba.

Algunas otras versiones requieren que registres explícitamente un InstrumentedResourceMethodApplicationListener como se muestra en este Doc


0
2017-07-07 15:38