9

我正在尝试将端点上可见的所有指标导出/metricsStatsdMetricWriter.

到目前为止,我有以下配置类:

package com.tonyghita.metricsdriven.service.config;

import com.codahale.metrics.MetricRegistry;
import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.ExportMetricReader;
import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
import org.springframework.boot.actuate.metrics.reader.MetricRegistryMetricReader;
import org.springframework.boot.actuate.metrics.statsd.StatsdMetricWriter;
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@EnableMetrics(proxyTargetClass = true)
public class MetricsConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(MetricsConfig.class);

    @Value("${statsd.host:localhost}")
    private String host = "localhost";

    @Value("${statsd.port:8125}")
    private int port;

    @Autowired
    private MetricRegistry metricRegistry;

    @Bean
    @ExportMetricReader
    public MetricReader metricReader() {
        return new MetricRegistryMetricReader(metricRegistry);
    }

    @Bean
    @ExportMetricWriter
    public MetricWriter metricWriter() {
        LOGGER.info("Configuring StatsdMetricWriter to export to {}:{}", host, port);
        return new StatsdMetricWriter(host, port);
    }
}

它写入了我添加到 Statsd 的所有指标,但我还想发送/metrics端点上可见的系统/JVM 指标。

我错过了什么?

4

4 回答 4

6

我遇到了同样的问题并在这里找到了解决方案:https ://github.com/tzolov/export-metrics-example

只需将 a 添加MetricsEndpointMetricReader到您的配置中,e/metrics 端点上可用的所有内容都将发布到StatsdMetricWriter.

这是 spring boot 1.3.x 和 dropwizard metrics-jvm 3.1.x 的完整示例配置:

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.ExportMetricWriter;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.MetricsEndpointMetricReader;
import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.boot.actuate.metrics.statsd.StatsdMetricWriter;
import org.springframework.boot.actuate.metrics.writer.Delta;
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MetricsConfiguration {

  @Bean
  public MetricRegistry metricRegistry() {
    final MetricRegistry metricRegistry = new MetricRegistry();

    metricRegistry.register("jvm.memory",new MemoryUsageGaugeSet());
    metricRegistry.register("jvm.thread-states",new ThreadStatesGaugeSet());
    metricRegistry.register("jvm.garbage-collector",new GarbageCollectorMetricSet());

    return metricRegistry;
  }

  /*
   * Reading all metrics that appear on the /metrics endpoint to expose them to metrics writer beans.
   */
  @Bean
  public MetricsEndpointMetricReader metricsEndpointMetricReader(final MetricsEndpoint metricsEndpoint) {
    return new MetricsEndpointMetricReader(metricsEndpoint);
  }

  @Bean
  @ConditionalOnProperty(prefix = "statsd", name = {"prefix", "host", "port"})
  @ExportMetricWriter
  public MetricWriter statsdMetricWriter(@Value("${statsd.prefix}") String statsdPrefix,
                                     @Value("${statsd.host}") String statsdHost,
                                     @Value("${statsd.port}") int statsdPort) {
    return new StatsdMetricWriter(statsdPrefix, statsdHost, statsdPort);
  }

}
于 2016-02-11T09:52:04.967 回答
5

要注册 JVM 指标,您可以使用 codehale.metrics.jvm 库提供的与 JVM 相关的 MetricSet。您可以只添加整套而不提供它们是量规还是计数器。

这是我注册 jvm 相关指标的示例代码:

@Configuration
@EnableMetrics(proxyTargetClass = true)
public class MetricsConfig {

@Autowired
private StatsdProperties statsdProperties;

@Autowired
private MetricsEndpoint metricsEndpoint;

@Autowired
private DataSourcePublicMetrics dataSourcePublicMetrics;

@Bean
@ExportMetricReader
public MetricReader metricReader() {
    return new MetricRegistryMetricReader(metricRegistry());
}

public MetricRegistry metricRegistry() {
    final MetricRegistry metricRegistry = new MetricRegistry();

    //jvm metrics
    metricRegistry.register("jvm.gc",new GarbageCollectorMetricSet());
    metricRegistry.register("jvm.mem",new MemoryUsageGaugeSet());
    metricRegistry.register("jvm.thread-states",new ThreadStatesGaugeSet());

    return metricRegistry;
}

@Bean
@ConditionalOnProperty(prefix = "metrics.writer.statsd", name = {"host", "port"})
@ExportMetricWriter
public MetricWriter statsdMetricWriter() {
    return new StatsdMetricWriter(
            statsdProperties.getPrefix(),
            statsdProperties.getHost(),
            statsdProperties.getPort()
    );
}

}

注意:我使用的是spring boot 1.3.0.M4版本

于 2015-08-28T06:09:51.640 回答
5

从我在 spring-boot 代码中看到的,只有调用CounterServiceGaugeService实现被转发到 dropwizard 的MetricRegistry.

因此,正如您已经观察到的那样,只有来自端点的指标才会counter.*以.gauge.*/metricsStatsd

系统和 JVM 指标通过自定义SystemPublicMetrics类公开,不使用计数器或计量服务。

我不确定是否有更简单的解决方案(也许 Spring 团队的某个人会发表评论),但一种方法(不是 spring-boot 特定的)是使用定期将系统统计信息写入MetricRegistry.

于 2015-08-26T20:43:33.477 回答
4

享受!(查看控制台中记录的公共指标作为 dropwizard 指标)

@Configuration
@EnableMetrics
@EnableScheduling
public class MetricsReporter extends MetricsConfigurerAdapter {

    @Autowired private SystemPublicMetrics systemPublicMetrics;
    private MetricRegistry metricRegistry;

    @Scheduled(fixedDelay = 5000)
    void exportPublicMetrics() {
        for (Metric<?> metric : systemPublicMetrics.metrics()) {
            Counter counter = metricRegistry.counter(metric.getName());
            counter.dec(counter.getCount());
            counter.inc(Double.valueOf(metric.getValue().toString()).longValue());
        }
    }

    @Override
    public void configureReporters(MetricRegistry metricRegistry) {
        this.metricRegistry = metricRegistry;
        ConsoleReporter.forRegistry(metricRegistry).build().start(10, TimeUnit.SECONDS);
    }

}
于 2015-10-14T12:13:17.043 回答