Метрики Codahale: использование аннотации @ Timed metrics в простой Java

Я пытаюсь добавить метрики в простое приложение Java, используя метрики codahale. Я хотел бы использовать аннотацию @Timed, но мне неясно, какую MetricRegistry она использует, или как сказать ей, какую MetricRegistry использовать. Приложение представляет собой простое приложение Java 8, построенное с Maven 3, Без весны, без спящего режима.

Я не могу найти никакой документации о том, как реализовать @Timed в документации dropwizard: https://dropwizard.github.io/metrics/3.1.0/manual/

я добавил следующие зависимости:

<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>

когда я использую программный вызов таймера, я могу получать отчеты, потому что я знаю, какая MetricsRegistry используется:

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

но когда я использую гораздо более элегантную аннотацию @Timed, я понятия не имею, какой реестр используется, и поэтому я не могу создать репортера, что означает, что я не могу получить данные о метриках (я даже не уверен, что это действительно так что угодно):

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

пожалуйста, посоветуйте, как сделать аннотации @Timed и другие метрики работать в обычном приложении Java.

дополнительная информация: причина, по которой я нахожу это странным, заключается в том, что я добавил структуру Lombok и аннотации @Slf4j работают. Я добавил Ломбок в качестве зависимости в Maven pom.XML-код:

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

и я могу использовать аннотацию класса @Sl4fj, чтобы добавить регистратор в класс, не загромождая член переменные:

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

поэтому, если это возможно, просто добавив зависимость, я считаю, что мне просто не хватает зависимости или конфигурации, чтобы получить работу аннотации codahale @Timed, как описано выше.

(кстати, проверьте Ломбок, это сделает вашу жизнь проще: http://projectlombok.org/ )

8 ответов


короче говоря, вы не можете использовать @Timed без какого-либо AOP (будь то Spring AOP или AspectJ).

неделю или две назад я также решил добавить метрики в наш проект и выбрал AspectJ для этой задачи (в основном потому, что я использовал его в прошлом для аналогичной цели и потому, что он позволяет ткать время компиляции, в то время как Spring позволяет только время выполнения через прокси).

вы должны быть в состоянии найти всю необходимую информацию и инструкции здесь: https://github.com/astefanutti/metrics-aspectj.

Что касается Ломбока, я думаю, они используют встроенный процессор аннотаций javac:

другой точкой соперничества является реализация как кода, поддерживающего интеграцию IDE, так и процессора аннотаций javac. Обе эти части проекта Ломбок используют непубличные API для выполнения своего волшебства. Это означает, что существует риск того, что проект Ломбок будет разбит с последующим Выпуски IDE или JDK.


С помощью @Timed фактически не требует использования AOP, как было ранее заявлено в топ-рейтинге answer, если вы находитесь внутри контейнера и используете одну из библиотек инструментов Dropwizard. Смотрите Джерси 2.например, модуль x, который вы можете видеть, использует отражение (как и другие, на которые я смотрел), если Вы читаете источник.

вы можете прочитать все эти модули в Dropwizard docs под тегом "инструментирование ____" пули.

Я понимаю, что OP явно не работал в таком контейнере, но я хотел бы предложить эту информацию, так как многие из нас, ищущие этот ответ, могут работать над современной веб-службой, которая может регистрировать такие ресурсы в своей среде выполнения.


используйте встроенный MetricRegistry доступ из параметра bootstrap в методе initialize класса приложения.

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

Как указано в другом ответе, у вас должно быть что-то в приложении, чтобы слушать ваши экземпляры классов и проверять их на аннотацию @Timed.

Если вы используете Guice, вы можете использовать:https://github.com/palominolabs/metrics-guice


AOP является излишним и не подходит для использования @timed, как правило разговор.

реестр метрик по умолчанию записывает метрики @timed в ConcurrentHashMap и не присоединяет никаких значимых прослушивателей.

конструктор начальной загрузки DropWizard:

/**
 * 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>();
}

таким образом, вам нужно создать/запустить / зарегистрировать соответствующий реестр метрик в чтобы увидеть результаты.

здесь я использую И JMX:

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

Это все, что вам нужно сделать.

вот пример вывода (запустите jconsole против вашего Java-приложения / сервера для просмотра результатов JMX):

enter image description here


вы также можете использовать stagemonitor-core для этого. Ознакомиться с документацией здесь и здесь. Преимущество заключается в том, что stagemonitor (который является бесплатным и открытым исходным кодом btw) не зависит от каких-либо контейнерных перехватчиков AOP, таких как Spring AOP или EJB. Он использует манипуляции байт-кода через вложение времени выполнения, что означает, что вам даже не нужно добавлять -javaagent флаг для запуска приложения-достаточно простой зависимости.

Если вы хотите измерить время выполнения время в веб-приложении или в удаленном приложении EJB вам даже не нужно вручную аннотировать свой код. Кроме того, stagemonitor предлагает настроенных Grafana и дашборд платформы Kibana.

отказ от ответственности: я один из разработчиков stagemonitor


в более новых версиях Dropwizard (я использую 0.9.2) вы можете получить доступ к умолчанию MetricRegistry через настройка io.dropwizard.setup.Environment. Это значение по умолчанию MetricRegistry уже есть InstrumentedResourceMethodApplicationListener связанные с ним, который слушает все показатели ваших ресурсов.

если вы зарегистрировали ресурс с JerseyEnvironment как под,

environment.jersey().register(resource);

вам нужно только аннотировать свой метод ресурса (или класс) с помощью @Timed, @Metered или @ExceptionMetered зарегистрировать соответствующий метрика.

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

вы можете назначить Reporter (как Slf4jReporter или JmxReporter) по умолчанию MetricRegistry под

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

в качестве быстрого теста, чтобы увидеть, если ваши показатели на самом деле были зарегистрированы, вы можете сделать GET вызовите URL http://localhost:8081/metrics или соответствующий URL-адрес метрики администратора в тестовой среде.

некоторые другие версии требуют, чтобы вы явно зарегистрировать InstrumentedResourceMethodApplicationListener как показано в этом Doc


этот простой / правый к точке пример https://karollotkowski.wordpress.com/2015/10/19/api-endpoint-in-one-minute-with-dropwizard/ просто показал, что ему нужна только аннотация

enter image description here