Регистрация MetricRegistry внутри комплекта Dropwizard

Я создаю пакет Dropwizard для повторного использования во всех моих микросервисах. Одной из вещей, которую я хотел бы стандартизировать, является MetricRegistry каждый сервис использует.

Было бы здорово, если бы я мог настроить каждый сервис на использование одного и того же MetricRegistry просто добавив мой пакет в init, так что-то вроде:

class Microservice1 extends Application<Microservice1Config> {
    @Override
    void initialize(Bootstrap<Microservice1Config> cfg) {
        // Boom! Standardized metrics/reporters configured and initialized!
        bootstrap.addBundle(new MyBundle())
    }
}

Проблема в том, что Bundle API, кажется, не способствует этому типу поведения:

class MyBundle implements Bundle {
    MetricRegistry metricRegistry

    @Override
    void initialize(Bootstrap bootstrap) {

    }

    @Override
    void run(Environment environment) {
        environment.jersey().register(???)
    }
}

Так как register(...) метод не регистрируется metricRegistry как ресурс JAX-RS, я в растерянности относительно того, как соединить вещи так, чтобы это metricRegistry используется для всех показателей во всем микросервисе. Идеи?


Обновить

То, что я ищу, это где поставить следующее:

MetricRegistry metricRegistry = new MetricRegistry()
Slf4jReporter slf4jReporter = Slf4jReporter.forRegistry(metricRegistry)
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.SECONDS)
    .build()

slf4jReporter.start(5, TimeUnit.SECONDS)

1 ответ

Решение

Ну, есть метрический реестр, доступный из environment.metrics(), Есть много способов сделать это так, как вам нужно. Я использую комплект dropwizard-guice, чтобы добавить поддержку Guice.

private GuiceBundle<MyConfiguration> guiceBundle;

@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {

  guiceBundle = GuiceBundle.<MyConfiguration>newBuilder()
    .addModule(new MyModule())
    .setConfigClass(MyConfiguration.class)
    .build(Stage.DEVELOPMENT);

  bootstrap.addBundle(guiceBundle);
}

Затем я создаю правило провайдера в модуле приложения для реестра метрик.

public class MyModule extends AbstractModule {

  ...

  @Provides
  @Singleton
  public MetricRegistry provideRegistry( Environment environment ) {
    return environment.metrics();
  }
}

И на своем ресурсе я отмечаю реестр как внедренный.

@Path("/resource")
public class MyResource {
  @Inject
  MetricRegistry registry;
}

Наконец, я запрашиваю свои статические ресурсы у инжектора Guice, а затем передаю экземпляр в Jersey вместо имени класса.

@Override
public void run(Environment environment) {
  Injector injector = guiceBundle.getInjector();
  environment.jersey().register(injector.getInstance(MyResource.class));
}

Возможно, вы могли бы просто зарегистрировать имя класса и полагаться на мост Guice/HK2 для обеспечения внедрения, но исторически интеграция Guice/HK2 была проблематичной.

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

Например, если вы хотите отправить метрики в графит, вы можете настроить репортер метрик графита. Вам нужно будет добавить зависимость от графитного репортера.

<dependency>
  <artifactId>dropwizard-metrics-graphite</artifactId>
  <groupId>io.dropwizard</groupId>
  <version>${dropwizard.version}</version>
</dependency>

и добавьте конфигурацию для репортера.

metrics:
  reporters:
    - type: graphite
      prefix: <PREFIX_FOR_METRICS>
      host: <GRAPHITE_HOST>
      port: <GRAPHITE_PORT>
      frequency: 10s
Другие вопросы по тегам