随着系统越来越大,越来越复杂,我们需要在业务方面加上一些监控服务。Metrics作为一款监控指标的度量类库,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控,同时,Metrics能够很好的跟Ganlia、Graphite结合,方便的提供图形化接口。
使用Metrics
使用Metrics,只需要在pom文件里面增加metrics-core
的依赖:
1 | <dependency> |
core包主要提供如下核心功能:
Metrics中MetricRegistry是中心容器,它是程序中所有度量的容器,所有新的度量工具都要注册到一个MetricRegistry实例中才可以使用,尽量在一个应用中保持让这个MetricRegistry实例保持单例。
支持五种metric类型:
- Gauges(度量)
- Counters(计数器)
- Meters(TPS计算器)
- Histograms(直方图数据)
- Timers(计时器)
可以将metrics值通过JMX、Console,CSV文件和SLF4J loggers发布出来。
Gauge (仪表)
Gauge代表一个度量的即时值。 当你开汽车的时候, 当前速度是Gauge值。 你测体温的时候, 体温计的刻度是一个Gauge值。 当你的程序运行的时候,内存使用量和数据库连接数都可以通过Gauge值来度量。
下面是一个使用SpringBoot创建的domo示例:
配置类:MonitorConfiguration.java,将MetricRegistry的实例配置到Spring的IOC容器中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package com.lzumetal.springboot.metrics.config;
import com.codahale.metrics.MetricRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* <p>Description: </p>
*
* @author liaosi
* @date 2018-07-28
*/
public class MonitorConfiguration {
/**
* 其实就是一个metrics容器,因为该类的一个属性final ConcurrentMap<String, Metric> metrics,
* 在实际使用中做成单例的
* @return
*/
"metricRegistry") (name =
public MetricRegistry metricRegistry() {
return new MetricRegistry();
}
}
SpringBood项目启动类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.lzumetal.springboot.metrics;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* <p>Description: </p>
*
* @author liaosi
* @date 2018-07-28
*/
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
测试类:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82package com.lzumetal.springboot.metrics.test;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
import com.lzumetal.springboot.metrics.Bootstrap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
* <p>Description: </p>
*
* @author liaosi
* @date 2018-07-28
*/
(SpringRunner.class)
//classes指定项目启动类 (classes = Bootstrap.class)
public class MetricsTest {
private static Queue<Integer> queue = new LinkedBlockingDeque<Integer>();
private static final Logger log = LoggerFactory.getLogger(MetricsTest.class);
private MetricRegistry registry;
public void GaugeTest() throws InterruptedException {
//让监控的数据输出到控制台
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
reporter.start(3L, TimeUnit.SECONDS);
registry.register(MetricRegistry.name(MetricsTest.class, "queue", "size"), (Gauge) () -> {
return queue.size();
});
TimeUnit.SECONDS.sleep(5L);
for (int i = 0; i < 20; i++) {
queue.add(new Random().nextInt(100));
TimeUnit.SECONDS.sleep(1L);
}
}
public void GaugeTest2() throws InterruptedException {
registry.register(MetricRegistry.name(MetricsTest.class, "queue", "size"), (Gauge) () -> {
return queue.size();
});
//让监控的数据输出到slf4j的日志
Slf4jReporter.Builder builder = Slf4jReporter.forRegistry(registry);
builder.outputTo(log);
builder.withLoggingLevel(Slf4jReporter.LoggingLevel.ERROR);
builder.build().start(3, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(5L);
for (int i = 0; i < 20; i++) {
queue.add(new Random().nextInt(100));
TimeUnit.SECONDS.sleep(1L);
}
}
}
GaugeTest()
方法(监控数据输出到控制台)运行结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 0
18-7-29 22:56:36 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 2
18-7-29 22:56:39 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 5
18-7-29 22:56:42 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 8
18-7-29 22:56:45 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 10
18-7-29 22:56:48 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 13
18-7-29 22:56:51 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 16
18-7-29 22:56:54 ===============================================================
-- Gauges ----------------------------------------------------------------------
com.lzumetal.springboot.metrics.test.MetricsTest.queue.size
value = 19
GaugeTest()
方法(监控数据输出到slf4j日志)运行结果:1
2
3
4
5
6
7
82018-07-29 22:45:16.154 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=0
2018-07-29 22:45:19.147 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=2
2018-07-29 22:45:22.147 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=5
2018-07-29 22:45:25.147 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=8
2018-07-29 22:45:28.147 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=10
2018-07-29 22:45:31.148 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=13
2018-07-29 22:45:34.148 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=16
2018-07-29 22:45:37.148 ERROR 15484 --- [rter-1-thread-1] c.l.springboot.metrics.test.MetricsTest : type=GAUGE, name=com.lzumetal.springboot.metrics.test.MetricsTest.queue.size, value=19