Java Metrics+Grafana+InfluxDB搭建监控系统
Contents
以下的测试, 都是基于 Ubuntu 14.04.2 LTS + Java 8 + SpringBoot
Grafana 安装
sudo echo "deb https://packagecloud.io/grafana/stable/debian/ stretch main" > /etc/apt/sources.list.d/grafana.list
curl https://packagecloud.io/gpg.key | sudo apt-key add -
sudo apt-get update -y ; sudo apt-get install grafana
启动/停止
sudo service grafana-server start
sudo service grafana-server stop
登录:
默认的用户名和密码都是 admin
登录后, 它会提示让你修改密码的.
InfluxDB 安装
cd ~/Downloads/
wget https://dl.influxdata.com/influxdb/releases/influxdb_1.5.4_amd64.deb
sudo dpkg -i influxdb_1.5.4_amd64.deb
启动/停止
service influxdb start
service influxdb stop
Java Metrics 的使用
pom.xml
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>4.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.dropwizard.metrics/metrics-jvm -->
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jvm</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.10</version>
</dependency>
<dependency>
<groupId>com.github.davidb</groupId>
<artifactId>metrics-influxdb</artifactId>
<version>0.9.3</version>
</dependency>
代码里使用
package com.company.metrics;
import com.codahale.metrics.*;
import com.codahale.metrics.jvm.*;
import com.company.util.MetricsUtil;
import metrics_influxdb.HttpInfluxdbProtocol;
import metrics_influxdb.InfluxdbReporter;
import metrics_influxdb.api.measurements.CategoriesMetricMeasurementTransformer;
import org.apache.commons.lang3.StringUtils;
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.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
/**
* @author emacsist
*/
@Component
public class AppMetrics {
private static final Logger log = LoggerFactory.getLogger(AppMetrics.class);
@Autowired
private ReloadableProperties reloadableProperties;
public static final MetricRegistry metrics = new MetricRegistry();
@Value("${server.port}")
private int port;
@Value("${influxdb.host}")
private String influxHost;
@Value("${influxdb.user}")
private String influxUser;
@Value("${influxdb.passwd}")
private String influxPasswd;
@Value("${influxdb.db}")
private String influxDB;
@Value("${influxdb.port}")
private int influxPort;
@PostConstruct
public void init() {
initJVM();
initProperties();
if (StringUtils.isBlank(influxHost)) {
startConsoleReporter();
} else {
influxDbReporter();
}
}
private void initJVM() {
metrics.register("jvm.gc", new GarbageCollectorMetricSet());
metrics.register("jvm.thread-state", new CachedThreadStatesGaugeSet(10, TimeUnit.SECONDS));
metrics.register("jvm.mem", new MemoryUsageGaugeSet());
metrics.register("jvm.attr", new JvmAttributeGaugeSet());
metrics.register("jvm.buffer-pool", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
metrics.register("jvm.fd.usage", new FileDescriptorRatioGauge());
}
private void influxDbReporter() {
log.info("use influxdb as reporter {}:{}, {}, {}", influxHost, influxPort, influxUser, influxDB);
final ScheduledReporter reporter = InfluxdbReporter.forRegistry(metrics)
.protocol(new HttpInfluxdbProtocol("http", influxHost, influxPort, influxUser, influxPasswd, influxDB))
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.filter(MetricFilter.ALL)
.skipIdleMetrics(false)
//这里使用的是SpringBoot, 这是Java使用的监听的端口和本机IP地址, 来唯一表示该JVM进程, 你也可以使用其他的方式
.tag("client", Integer.toString(port))
.tag("server", MetricsUtil.getHost())
.transformer(new CategoriesMetricMeasurementTransformer("module", "artifact"))
.build();
reporter.start(10, TimeUnit.SECONDS);
}
private void startConsoleReporter() {
log.info("use console as reporter");
ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
reporter.start(10, TimeUnit.SECONDS);
}
}
如果一切正常的话, 你就可以在 influxdb 中看到数据了.
> show measurements
name: measurements
name
----
PS-MarkSweep.count
PS-MarkSweep.time
PS-Scavenge.count
PS-Scavenge.time
blocked.count
count
daemon.count
deadlock.count
deadlocks
direct.capacity
direct.count
direct.used
heap.committed
heap.init
heap.max
heap.usage
heap.used
mapped.capacity
mapped.count
mapped.used
name
new.count
non-heap.committed
non-heap.init
non-heap.max
non-heap.usage
non-heap.used
pools.Code-Cache.committed
pools.Code-Cache.init
pools.Code-Cache.max
pools.Code-Cache.usage
pools.Code-Cache.used
这些就是 Java Metrics 收集的指标, 并保存在了 InfluxDB.
可视化监控数据
在 Grafana 中的数据源里, 配置好 InfluxDB 作为一个数据源.如下操作即可看到图表了:
其他的指标, 可以利用 Java Metrics 库来自定义.这里就不多说了. 主要思路即是: 在 Java Metrics 中收集好指标 -> 保存到 InfluxDB -> Grafana 查询出来, 保存好 Panel 即可.