/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package org.springside.modules.metrics.reporter;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.modules.metrics.MetricRegistry;
import org.springside.modules.metrics.Reporter;
import org.springside.modules.metrics.metric.Counter;
import org.springside.modules.metrics.metric.CounterMetric;
import org.springside.modules.metrics.metric.Gauge;
import org.springside.modules.metrics.metric.Histogram;
import org.springside.modules.metrics.metric.HistogramMetric;
import org.springside.modules.metrics.metric.Timer;
import org.springside.modules.metrics.metric.TimerMetric;
/**
* 使用Slf4j以INFO级别将Metrics打印到日志.
*
* 默认logger name是"metrics",可在构造函数中设定.用户需要在日志的配置文件中对该logger进行正确配置.
*
* TODO: 另一个输出为JSON的实现
*/
public class Slf4jReporter implements Reporter {
private static final String DEFAULT_LOGGER_NAME = "metrics";
private Logger reportLogger;
public Slf4jReporter() {
this(DEFAULT_LOGGER_NAME);
}
public Slf4jReporter(String loggerName) {
reportLogger = LoggerFactory.getLogger(loggerName);
if (!reportLogger.isInfoEnabled()) {
System.out.println("metrics logger " + loggerName + " is not config correctly");
}
}
@Override
public void report(Map<String, Gauge> gauges, Map<String, Counter> counters, Map<String, Histogram> histograms,
Map<String, Timer> timers) {
if (!reportLogger.isInfoEnabled()) {
return;
}
for (Entry<String, Gauge> entry : MetricRegistry.getSortedMetrics(gauges).entrySet()) {
logGauge(entry.getKey(), entry.getValue().latestMetric);
}
for (Entry<String, Counter> entry : MetricRegistry.getSortedMetrics(counters).entrySet()) {
logCounter(entry.getKey(), entry.getValue().latestMetric);
}
for (Entry<String, Histogram> entry : MetricRegistry.getSortedMetrics(histograms).entrySet()) {
logHistogram(entry.getKey(), entry.getValue().latestMetric);
}
for (Entry<String, Timer> entry : MetricRegistry.getSortedMetrics(timers).entrySet()) {
logTimer(entry.getKey(), entry.getValue().latestMetric);
}
}
private void logGauge(String name, Number gauge) {
reportLogger.info("type=GAUGE, name={}, value={}", name, gauge);
}
private void logCounter(String name, CounterMetric counter) {
reportLogger.info("type=COUNTER, name={}, totalCount={}, avgRate={}, latestRate={}", name, counter.totalCount,
counter.avgRate, counter.latestRate);
}
private void logHistogram(String name, HistogramMetric histogram) {
reportLogger.info("type=HISTOGRAM, name={}, min={}, max={}, avg={}{}", name, histogram.min, histogram.max,
histogram.avg, buildPcts(histogram.pcts));
}
private void logTimer(String name, TimerMetric timer) {
reportLogger.info(
"type=TIMER, name={}, totalCount={}, avgRate={}, latestRate={}, minLatency={}ms, maxLatency={}ms, avgLatency={}ms{}",
name, timer.counterMetric.totalCount, timer.counterMetric.avgRate, timer.counterMetric.latestRate,
timer.histogramMetric.min, timer.histogramMetric.max, timer.histogramMetric.avg,
buildPcts(timer.histogramMetric.pcts));
}
private static String buildPcts(Map<Double, Long> pcts) {
StringBuilder builder = new StringBuilder();
for (Entry<Double, Long> entry : pcts.entrySet()) {
builder.append(", ").append(entry.getKey()).append("%<=").append(entry.getValue()).append("ms");
}
return builder.toString();
}
}