Sending System Metrics to Graphite with Spring-Boot

半城伤御伤魂 提交于 2019-12-07 17:55:12

问题


Spring-Boot actuator exposes many useful metrics at /metrics such as uptime, memory usage, GC count.

Only a subset of these are sent to Graphite when using the Dropwizard Metrics integration. In specific, only the counters and gauges

Is there any way to get these other metrics to be published to graphite?

The documentation suggests that it should be possible:

Users of the Dropwizard ‘Metrics’ library will find that Spring Boot metrics are automatically published to com.codahale.metrics.MetricRegistry


回答1:


System Metrics created by Spring boot are not reported automatically because MetricsRegistry does not know anything about those Metrics.

You should register those metrics manually when your application boots up.

@Autowired
private SystemPublicMetrics systemPublicMetrics;

private void registerSystemMetrics(MetricRegistry metricRegistry) {
    systemPublicMetrics.metrics().forEach(m -> {
        Gauge<Long> metricGauge = () -> m.getValue().longValue();
        metricRegistry.register(m.getName(), metricGauge);   
    });
}

I have defined Gauge, not all the system metrics should be added as gauge. e.g. the Counter should be used to capture count values.

If you don't want to use Spring boot. Use can include metrics-jvm out of the box to capture JVM level metrics.




回答2:


Here's a solution that does update DropWizard metrics on Spring metrics change. It also does that without turning @EnableScheduling on:

@EnableMetrics
@Configuration
public class ConsoleMetricsConfig extends MetricsConfigurerAdapter {

    @Autowired
    private SystemPublicMetrics systemPublicMetrics;

    @Override
    public void configureReporters(MetricRegistry metricRegistry) {

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

        metricRegistry.register("spring.boot", (MetricSet) () -> {
            final Map<String, Metric> gauges = new HashMap<String, Metric>();

            for (final org.springframework.boot.actuate.metrics.Metric<?> springMetric : 
                    systemPublicMetrics.metrics()) {

                gauges.put(springMetric.getName(), (Gauge<Object>) () -> {

                    return systemPublicMetrics.metrics().stream()
                        .filter(m -> StringUtils.equals(m.getName(), springMetric.getName()))
                        .map(m -> m.getValue())
                        .findFirst()
                        .orElse(null);

                });
            }
            return Collections.unmodifiableMap(gauges);
        });

        registerReporter(ConsoleReporter
            .forRegistry(metricRegistry)
            .convertRatesTo(TimeUnit.SECONDS)
            .convertDurationsTo(TimeUnit.MILLISECONDS)
            .build())
            .start(intervalSecs, TimeUnit.SECONDS);

    }
}

It uses the com.ryantenney.metrics library for enabling additional Spring annotations support and DropWizard reporters:

    <dependency>
        <groupId>com.ryantenney.metrics</groupId>
        <artifactId>metrics-spring</artifactId>
        <version>3.1.3</version>
    </dependency>

But it is actually not necessary in this particular case.



来源:https://stackoverflow.com/questions/30852914/sending-system-metrics-to-graphite-with-spring-boot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!