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