2015-08-25 25 views
9

我試圖導出在端點/metrics處可見的所有指標爲StatsdMetricWriter導出彈簧啓動器指標(&Dropwizard指標)爲

我已經走到這一步,下面的配置類:

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的指標,但我想也發送系統/ JVM度量在/metrics端點上可見。

我錯過了什麼?

+0

也許[本PR(https://github.com/spring-projects/spring -boot /拉/ 3719)(待定合併)將有助於 –

+0

。希望被合併@StéphaneNic​​oll!這個改變增加了設置Statsd編寫器的便利性,但是我的問題更多的是如何設置'@ ExportMetricReader' bean來導出'/ metrics'端點上可用的度量值。 –

+0

FTR,它已合併。 – gilad

回答

5

從我在spring-boot代碼中看到的,只有調用CounterServiceGaugeService的實現纔會被轉發到dropwizard的MetricRegistry

因此,你已經觀察到,從/metrics端點只counter.*gauge.*指標將在Statsd結束。

系統和JVM度量通過定製SystemPublicMetrics類,它不使用計數器或計服務露出。我不確定是否有一個更簡單的解決方案(也許Spring團隊會有人發表評論),但一種方法(不是特定於spring-boot)可以使用定期寫入系統統計信息的計劃任務到MetricRegistry

+1

謝謝您的回答@mzc。我會喜歡使用現有的'SystemPublicMetrics',但正如你所指出的那樣,它並不是那麼簡單。幸運的是,有一個io.dropwizard。指標:metrics-jvm''庫,可以很好地處理jvm指標的輸出。儘管如此,我仍然想要導出這些不錯的tomcat指標,因此探索您提出的解決方案可能很有價值。 –

5

要註冊JVM指標,您可以使用codehale.metrics.jvm庫提供的JVM相關MetricSets。您可以添加整個套件而不用提供量表或計數器。

這裏是我註冊的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() 
    ); 
} 

}

注:我使用的彈簧引導版本1.3.0.M4

+0

感謝您的回答@YonatanWilcof。看起來我們使用的是同一版本的Spring Boot。 我已經能夠像你所描述的那樣通過向我的依賴添加''io.dropwizard.metrics:metrics-jvm:3.1.2''並且註冊'GarbageCollectorMetricSet','MemoryUsageGaugeSet'和'ThreadStatesGaugeSet '到'metricRegistry'。 我希望能夠使用現有的'SystemPublicMetrics'機制,但是這也可以完成工作。 看起來像還有一個'metrics-jdbi'庫!需要深入瞭解的內容:) –

+0

我認爲我的最後一部分是弄清楚如何將tomcat/endpoint統計信息添加到註冊表中。 –

+0

@Yonatan Wilkof:'StatsdProperties'類從哪個jar被導入,我似乎沒有在'io.dropwizard.metrics','com.ryantenney.metrics'和'spring-boot-starter-actuator 」。我是否需要在我的pom.xml中添加其他內容?謝謝。 –

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

} 
+0

謝謝@CelinHC,我得給這個解決方案一個鏡頭,當我得到一些時間 –

+0

另一種可以說是更乾淨的方式在這裏描述: http://stackoverflow.com/a/42933115/716720 –

+1

@SergeyShcherbakov不幸的是,春天的傢伙認爲它是低的。 https://github.com/spring-projects/spring-boot/issues/4197 – CelinHC

6

我有同樣的問題,在這裏找到了一個解決方案:https://github.com/tzolov/export-metrics-example

只需添加一個MetricsEndpointMetricReader到你的配置,並提供一切在日E /指標端點將被髮布到StatsdMetricWriter

下面是一個完整的示例配置爲彈簧引導1.3.x中和dropwizard度量-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); 
    } 

}