tokuhirom's Blog

spring-boot のメトリクスデータを graphite に送る

graphite とはまあザックリ言うと growthforecast みたいなものだが、python で書かれていて、ダッシュボード的な機能が充実してるって感じのものです。

画面の様子は以下の様な感じ。

Graph Tree:

Dashboard:

以下の様な感じで、nc で直接書き込める。http based な gf とはちょっと違う。

PORT=2003
SERVER=graphite.your.org
echo "local.random.diceroll 4 `date +%s`" | nc -q0 ${SERVER} ${PORT}

で、こういうやつにメトリクスデータを送るにはどうしたらいいか。spring-boot 自体はメトリクスの出力先として statsd, redis, opentsdb しかサポートしていない。 statsd から graphite に書き込ませることもできるのだが、今回は直接 graphite に書かせてみた。statsd 経由でやる場合は、各ホストに statsd を動かすってことになるのかなあ。 あんまり statsd 使ってる話を聞かないのでよくわからない。そして、graphite に送るだけなら、直接 graphite に送ればいい気もする。


さて、spring-boot で graphite を送るには、例によって dropwizard-metrics を利用すれば良い。

依存に以下を足す。

compile('io.dropwizard.metrics:metrics-core:3.1.0')
compile('io.dropwizard.metrics:metrics-graphite:3.1.2')

で、実際に動くコードは以下。依存にいれておけば、org.springframework.boot.actuate.autoconfigure.MetricsDropwizardAutoConfiguration が動いて、 com.codahale.metrics.MetricRegistry を Autowired できるようになるんで、これを利用すれば良い。

package com.example.config;

import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.MetricsDropwizardAutoConfiguration;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

@Configuration
@Slf4j
public class GraphiteConfig {
    /**
     * {@link MetricsDropwizardAutoConfiguration} configures Dropwizard's MetricRegistry
     * if it's available in classpath.
     */
    @Autowired
    private MetricRegistry registry;

    @PostConstruct
    public void initialize() {
        final Graphite graphite = new Graphite(new InetSocketAddress("localhost", 2003));
        final GraphiteReporter reporter = GraphiteReporter.forRegistry(registry)
                .prefixedWith("web1.example.com")
                .convertRatesTo(TimeUnit.SECONDS)
                .convertDurationsTo(TimeUnit.MILLISECONDS)
                .filter(MetricFilter.ALL)
                .build(graphite);
        reporter.start(1, TimeUnit.MINUTES);

    }
}

簡単ですね。 full sample code is here: https://github.com/tokuhirom/java-samples/tree/master/spring-boot-graphite-demo