Metrics数据的输出格式
Metrics的Histogram可配置项
这篇是之前监控工具——Metrics 快速入门的补充
代码地址
因为每个例子涉及代码较多,且包含测试用例,如果都贴到文章中内容过多,所以只贴出了部分代码。全部的代码在这里: https://gitee.com/daifyutils/springboot-samples。
此篇文章所属模块为:base-metrics
支持的格式
Metric提供了Reporter接口可以对统计的指标进行不同格式的输出。
其提供的基础的输出类型包含:控制台、CSV、Slf4j、JMX、MetricsServlet
控制台
ConsoleReporter 主要用在调试模式,其会将内容输出到控制台中
其配置方法
public static void main(String[] args) throws InterruptedException, IOException {
// 创建一个度量
MetricRegistry registry = new MetricRegistry();
// 注册到控制台中
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).build();
// 每5秒输出一次结果
reporter.start(5, TimeUnit.SECONDS);
Timer timer = registry.timer(MetricRegistry.name(TimersTest.class,"get-latency"));
Timer.Context ctx;
while(true){
ctx = timer.time();
Thread.sleep(random.nextInt(1000));
ctx.stop();
}
}
输出内容
这个时候内容会按照5秒钟的间隔打印出MetricRegistry
所有指标的度量信息,不同的指标使用-----------------
分割
22-5-9 23:39:16 ================================================================
-- Timers ----------------------------------------------------------------------
dai.samples.metrics.TimersTest.get-latency
count = 13
mean rate = 2.60 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 2.60 calls/second
15-minute rate = 2.60 calls/second
min = 13.94 milliseconds
max = 885.82 milliseconds
mean = 371.01 milliseconds
stddev = 298.94 milliseconds
median = 204.48 milliseconds
75% <= 683.32 milliseconds
95% <= 885.82 milliseconds
98% <= 885.82 milliseconds
99% <= 885.82 milliseconds
99.9% <= 885.82 milliseconds
22-5-9 23:39:21 ================================================================
-- Timers ----------------------------------------------------------------------
dai.samples.metrics.TimersTest.get-latency
count = 22
mean rate = 2.20 calls/second
1-minute rate = 2.60 calls/second
5-minute rate = 2.60 calls/second
15-minute rate = 2.60 calls/second
min = 13.94 milliseconds
max = 975.09 milliseconds
mean = 456.54 milliseconds
stddev = 325.83 milliseconds
median = 513.01 milliseconds
75% <= 715.50 milliseconds
95% <= 972.52 milliseconds
98% <= 975.09 milliseconds
99% <= 975.09 milliseconds
99.9% <= 975.09 milliseconds
CSV
其配置方法
public static void main(String[] args) throws InterruptedException {
// 创建一个度量
MetricRegistry registry = new MetricRegistry();
// 注册到控制台中
CsvReporter reporter = CsvReporter.forRegistry(registry)
.formatFor(Locale.CHINA)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
// CSV地址
.build(new File("E:\\reporters"));
// 每5秒输出一次结果
reporter.start(5, TimeUnit.SECONDS);
Timer timer = registry.timer(MetricRegistry.name(TimersTest.class,"latency"));
Timer.Context ctx;
while(true){
ctx = timer.time();
Thread.sleep(random.nextInt(1000));
ctx.stop();
}
}
输出内容
其内容输出到指定的目录下,文件名称为MetricRegistry.name(TimersTest.class,"latency")
的值(本例子中为dai.samples.metrics.TimersTest.latency.csv
)输出的格式为
Slf4j
其配置方法
public static void main(String[] args) throws InterruptedException {
// 创建一个度量
MetricRegistry registry = new MetricRegistry();
// 注册到控制台中
Slf4jReporter reporter = Slf4jReporter.forRegistry(registry)
.outputTo(LoggerFactory.getLogger("com.example.metrics"))
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
// 每5秒输出一次结果
reporter.start(5, TimeUnit.SECONDS);
Timer timer = registry.timer(MetricRegistry.name(TimersTest.class,"get-latency"));
Timer.Context ctx;
while(true){
ctx = timer.time();
Thread.sleep(random.nextInt(1000));
ctx.stop();
}
}
输出内容
使用Slf4j后,打印内容将受到log配置格式的控制,并可以输入到log中
Connected to the target VM, address: '127.0.0.1:13161', transport: 'socket'
23:43:06.566 [metrics-logger-reporter-1-thread-1] INFO dai.samples.reporters.Slf4jReporters - type=TIMER, name=dai.samples.metrics.TimersTest.get-latency, count=7, min=35.1732, max=974.173, mean=637.6869527750133, stddev=296.0382587938576, median=615.7707, p75=972.7867, p95=974.173, p98=974.173, p99=974.173, p999=974.173, mean_rate=1.4002949301181815, m1=0.0, m5=0.0, m15=0.0, rate_unit=events/second, duration_unit=milliseconds
23:43:11.559 [metrics-logger-reporter-1-thread-1] INFO dai.samples.reporters.Slf4jReporters - type=TIMER, name=dai.samples.metrics.TimersTest.get-latency, count=16, min=35.1732, max=974.173, mean=580.3104276645525, stddev=267.0479627424082, median=634.7826, p75=710.237, p95=974.173, p98=974.173, p99=974.173, p999=974.173, mean_rate=1.6010734236661628, m1=1.4, m5=1.4, m15=1.4, rate_unit=events/second, duration_unit=milliseconds
JMX
JMX格式并不建议在生产环境中使用,对于开发环境或者某些需要追踪系统问题的场景下可以使用此方式。
其配置方法
public static void main(String[] args) throws InterruptedException {
// 创建一个度量
MetricRegistry registry = new MetricRegistry();
// 注册到控制台中
JmxReporter reporter = JmxReporter.forRegistry(registry).build();
reporter.start();
Timer timer = registry.timer(MetricRegistry.name(TimersTest.class,"latency"));
Timer.Context ctx;
while(true){
ctx = timer.time();
Thread.sleep(random.nextInt(1000));
ctx.stop();
}
}
查看输出内容
JmxReporter需要使用JConsole
查看可以从命令行直接输入jconsole或在 GUI shell中运行。
在Mbean中可以看到metrics监控的指标,以及各个度量的值
输出度量过滤
实际使用中MetricRegistry会设置多种度量,在不同的场景下我们需要打印我们需要的度量,而Metric提供了MetricFilter接口来过滤需要打印的内容
其配置方法
private static Queue<String> queue = new LinkedList<String>();
private static Counter counter;
private static Random random = new Random();
public static void main(String[] args) throws InterruptedException, IOException {
// 创建一个度量
MetricRegistry registry = new MetricRegistry();
// 注册到控制台中
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
.filter((name, metric) -> Objects.equals(MetricRegistry.name(GaugesTest.class, "queue", "size"),name))
.build();
// 每5秒输出一次结果
reporter.start(5, TimeUnit.SECONDS);
Gauge gauge = () -> queue.size();
// 注册统计内容
registry.register(MetricRegistry.name(GaugesTest.class, "queue", "size"),gauge);
counter = registry.counter(MetricRegistry.name(Queue.class,"jobs","size"));
int num = 1;
while(true){
Thread.sleep(200);
if (random.nextDouble() > 0.7){
String job = takeJob();
}else{
String job = "Job-"+num;
addJob(job);
}
num++;
}
}
private static void addJob(String job) {
counter.inc();
queue.offer(job);
}
private static String takeJob() {
counter.dec();
return queue.poll();
}
输出内容
在添加了filter((name, metric) -> Objects.equals(MetricRegistry.name(GaugesTest.class, "queue", "size"),name)
过滤后,控制台中只会打印我们需要的内容
22-5-9 23:25:04 ================================================================
-- Gauges ----------------------------------------------------------------------
dai.samples.metrics.GaugesTest.queue.size
value = 3265
22-5-9 23:25:09 ================================================================
-- Gauges ----------------------------------------------------------------------
dai.samples.metrics.GaugesTest.queue.size
value = 3265