2015-08-25 8 views
9

Ich versuche, alle Metriken, die am Endpunkt /metrics zu einem StatsdMetricWriter sichtbar sind, zu exportieren.Spring Boot Actuator Metriken (& Dropwizard Metriken) zu Statsd exportieren

ich die folgende Konfigurationsklasse haben bisher:

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); 
    } 
} 

Welche alle Kennzahlen schreibt, die ich Statsd hinzugefügt haben, aber ich möchte auch die System/JVM-Metriken senden, sind auf dem /metrics Endpunkt sichtbar.

Was fehlt mir?

+0

Vielleicht [diese PR] (https://github.com/spring-projects/spring -boot/pull/3719) (ausstehende Zusammenführung) würde helfen –

+0

Hoffen, dass das @ StéphaneNicoll verschmolzen wird! Diese Änderung bietet mehr Komfort beim Einrichten des Statsd-Writers, aber meine Frage hängt eher davon ab, wie eine '@ ExportMetricReader'-Bean eingerichtet wird, die die am Endpunkt '/ metrics' verfügbaren Metriken exportiert. –

+0

FTR, es ist verschmolzen. – gilad

Antwort

5

Von dem, was ich in Spring-Boot-Code gesehen habe, werden nur Anrufe zu CounterService und GaugeService Implementierungen an Dropwizard MetricRegistry weitergeleitet.

Daher ist, wie Sie schon bemerkt, nur counter.* und gauge.* Metriken aus dem /metrics Endpunkt bis in Statsd beenden.

System- und JVM-Metriken werden über die benutzerdefinierte Klasse SystemPublicMetrics verfügbar gemacht, die keinen Zähler- oder Messdienst verwendet.

Ich bin mir nicht sicher, ob es eine einfachere Lösung gibt (vielleicht wird jemand vom Spring-Team kommentieren), aber eine Möglichkeit (nicht Spring-Boot-spezifisch) wäre eine geplante Aufgabe, die regelmäßig Systemstatistiken schreibt an die MetricRegistry.

+1

Danke für Ihre Antwort @mzc. Ich hätte gerne die vorhandenen 'SystemPublicMetrics' verwendet, aber wie Sie bereits sagten, ist es nicht so einfach. Zum Glück gibt es einen i.dropwizard.metrics: metrics-jvm''-Bibliothek, die den Export von jvm-Metriken ermöglicht. Trotzdem möchte ich diese netten Tomcat-Metriken exportieren, daher könnte es nützlich sein, die von Ihnen vorgeschlagene Lösung zu erkunden. –

5

Zum Registrieren von JVM-Metriken können Sie die JVM-bezogenen MetricSets verwenden, die von der Bibliothek codehale.metrics.jvm bereitgestellt werden. Sie können einfach das gesamte Set hinzufügen, ohne anzugeben, ob es sich um Messinstrumente oder Zähler handelt.

Hier ist mein Beispiel-Code, wo ich Jvm bezogene Messwerte am Registrierung:

@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() 
    ); 
} 

}

Hinweis: Ich bin mit Federverschluß Version 1.3.0.M4

+0

Danke für deine Antwort @YonatanWilcof. Sieht aus, als wären wir auf der gleichen Version von Spring Boot. Ich war in der Lage, die JVM-Metriken wie Sie beschrieben durch Hinzufügen von "io.dropwizard.metrics: metrics-jvm: 3.1.2" zu meinen Abhängigkeiten und Registrierung von 'GarbageCollectorMetricSet',' MemoryUsageGaugeSet' und 'ThreadStatesGaugeSet 'zum' metricRegistry'. Ich hatte gehofft, in der Lage zu sein, den vorhandenen "SystemPublicMetrics" -Mechanismus zu verwenden, aber das erledigt auch die Arbeit. Sieht so aus, als gäbe es auch eine 'metric-jdbi' Bibliothek! Zeit, sich darauf einzulassen :) –

+0

Ich denke, das letzte Stück für mich wäre herauszufinden, wie Tomcat/Endpunktzahlen zur Registrierung hinzugefügt werden. –

+0

@Yonatan Wilkof: aus welchem ​​jar wird die Klasse 'StatsdProperties' importiert, scheint es nicht in 'io.dropwizard.metrics', 'com.ryantenney.metrics' und 'spring-boot-starter-aktor' zu stehen ". Muss ich etwas anderes zu meiner pom.xml hinzufügen? Vielen Dank. –

4

Viel Spaß! (Siehe die Öffentlichkeit in der Konsole protokollierte Metriken als dropwizard Metriken)

@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); 
    } 

} 
+0

Danke @CelinHC, ich muss diese Lösung einen Schuss geben, wenn ich etwas Zeit bekomme –

+0

Ein anderer, wohl sauberer Weg ist hier beschrieben: http://Stackoverflow.com/a/42933115/716720 –

+1

@SergeyShcherbakov Leider Frühjahr Jungs denke, es ist LOW. https://github.com/spring-projects/spring-boot/issues/4197 – CelinHC

6

Ich hatte das gleiche Problem und eine Lösung hier gefunden: https://github.com/tzolov/export-metrics-example

Nur ein MetricsEndpointMetricReader zu Ihren Konfigurations hinzufügen und alles zur Verfügung zu th e/Metriken Der Endpunkt wird unter StatsdMetricWriter veröffentlicht.

ist die komplette Beispiel Config für Frühjahr Boot 1.3.x und dropwizard Metriken-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); 
    } 

} 
Verwandte Themen