随着系统越来越大,越来越复杂,我们需要在业务方面加上一些监控服务。Metrics作为一款监控指标的度量类库,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控,同时,Metrics能够很好的跟Ganlia、Graphite结合,方便的提供图形化接口。
使用Metrics
使用Metrics,只需要在pom文件里面增加metrics-core的依赖:
1 2 3 4 5
| <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> <version>4.0.0</version> </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 27
| package com.lzumetal.springboot.metrics.config;
import com.codahale.metrics.MetricRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class MonitorConfiguration {
@Bean(name = "metricRegistry") 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 19
| package com.lzumetal.springboot.metrics;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication 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 82
| package 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;
@RunWith(SpringRunner.class) @SpringBootTest(classes = Bootstrap.class) public class MetricsTest {
private static Queue<Integer> queue = new LinkedBlockingDeque<Integer>();
private static final Logger log = LoggerFactory.getLogger(MetricsTest.class);
@Autowired private MetricRegistry registry;
@Test 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); }
}
@Test public void GaugeTest2() throws InterruptedException {
registry.register(MetricRegistry.name(MetricsTest.class, "queue", "size"), (Gauge) () -> { return queue.size(); });
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 53
| -- 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 8
| 2018-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
|