Codahale Metrics: использование аннотации @Timed metrics в простой Java
Я пытаюсь добавить метрики к простому Java-приложению, используя метрики codahale. Я хотел бы использовать аннотацию @Timed, но мне непонятно, какой MetricRegistry он использует или как сказать, какой MetricRegistry использовать. Приложение представляет собой обычное приложение Java 8, построенное с помощью Maven 3, no Spring, без спящего режима.
Я не могу найти документацию о том, как реализовать @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>
Когда я использую программный вызов Timer, я могу получать отчеты, потому что знаю, какой 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 работают. Я добавил Lombok как зависимость в 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/)
Ответы
Ответ 1
Короче говоря, вы не можете использовать @Timed
без какого-либо AOP (будь то Spring AOP или AspectJ).
Неделя или две назад я также решил добавить показатели к нашему проекту и выбрал AspectJ для этой задачи (главным образом потому, что я использовал его в прошлом для аналогичной цели и потому, что он позволяет компилировать время, когда Spring позволяет только время выполнения через прокси).
Здесь вы сможете найти всю необходимую информацию и инструкции: https://github.com/astefanutti/metrics-aspectj.
Что касается Lombok, я предполагаю, что они используют встроенный процессор аннотаций javac:
Еще одна точка зрения - реализация как кода, поддерживающего интеграцию IDE, так и процессора обработки аннотаций javac. Обе эти части проекта Lombok используют непубличные API для достижения своего колдовства. Это означает, что существует риск того, что Project Lombok будет разорван с последующими релизами IDE или JDK.
Ответ 2
Использование @Timed
фактически не требует использования AOP, как ранее утверждалось в самом высоком ответе, если вы находитесь внутри контейнера и используете одну из библиотек инструментов Dropwizard. Например, см. Модуль Jersey 2.x, который вы можете увидеть, используя отражение (как и другие, на которые я смотрел), если вы читаете источник.
Вы можете прочитать все эти модули в документах Dropwizard под соответствующими марками "Instrumenting ____".
Я понимаю, что OP явно не работал в таком контейнере, но я хотел предложить эту информацию, так как многие из нас, которые ищут этот ответ, могут работать над современной веб-службой, которая может регистрировать такие ресурсы в своей среде выполнения.
Ответ 3
Использовать встроенный MetricRegistry, доступ к которому можно получить из параметра начальной загрузки в методе инициализации вашего класса приложения.
@Override
public void initialize(final Bootstrap<Configuration> bootstrap) {
final JmxReporter reporter = JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build();
reporter.start();
}
Ответ 4
Как было сказано в другом ответе, вы должны иметь что-то в приложении для прослушивания ваших экземпляров и проверить их для аннотации @Timed.
Если вы используете Guice, вы можете использовать: https://github.com/palominolabs/metrics-guice
Ответ 5
AOP является излишним и не подходит для использования @timed, как правило, говоря.
Реестр метрик по умолчанию записывает метрики @timed в ConcurrentHashMap и не добавляет никаких значимых слушателей.
Конструктор DropStage 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):
![введите описание изображения здесь]()
Ответ 6
Для этого также можно использовать stagemonitor-core. Смотрите здесь здесь и здесь. Преимущество состоит в том, что stagemonitor (который является свободным и открытым исходным кодом) не зависит от каких-либо AOP, подобных AOP или AJB-перехватчикам. Он использует манипуляцию с байт-кодом через приложение времени выполнения, что означает, что вам даже не нужно добавлять флаг -javaagent
к запуску вашего приложения - достаточно простой зависимости.
Если вы хотите измерить время выполнения в веб-приложении или в удаленном приложении EJB, вам даже не нужно вручную аннотировать ваш код. Кроме того, stagemonitor предлагает предварительно сконфигурированные приборные панели Grafana и Kibana.
Отказ от ответственности: я один из разработчиков stagemonitor
Ответ 7
В новых версиях 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-адрес Admin Metrics в тестовой среде.
В некоторых других версиях вам необходимо явно зарегистрировать InstrumentedResourceMethodApplicationListener
, как показано в этом документе