Metrics是一個給JAVA服務的各項指標提供度量工具的包,在JAVA代碼中嵌入Metrics代碼,可以方便的對業務代碼的各個指標進行監控,同時,Metrics能夠很好的跟Ganlia、Graphite結合,方便的提供圖形化接口。基本使用方式直接將core包(目前穩定版本3.0.1)導入pom文件即可,配置如下:
<dependency> <groupId>com.codahale.metrics</groupId> <artifactId>metrics-core</artifactId> <version>3.0.1</version> </dependency>
core包主要提供如下核心功能:
- Metrics Registries類似一個metrics容器,維護一個Map,可以是一個服務一個實例。
- 支持五種metric類型:Gauges、Counters、Meters、Histograms和Timers。
- 可以將metrics值通過JMX、Console,CSV文件和SLF4J loggers發布出來。
五種Metrics類型:
1. Gauges
Gauges是一個最簡單的計量,一般用來統計瞬時狀態的數據信息,比如系統中處於pending狀態的job。測試代碼
package com.netease.test.metrics; import com.codahale.metrics.ConsoleReporter; import com.codahale.metrics.Gauge; import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; import java.util.Queue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; /** * User: hzwangxx * Date: 14-2-17 * Time: 14:47 * 測試Gauges,實時統計pending狀態的job個數 */ public class TestGauges { /** * 實例化一個registry,最核心的一個模塊,相當於一個應用程序的metrics系統的容器,維護一個Map */ private static final MetricRegistry metrics = new MetricRegistry(); private static Queue<String> queue = new LinkedBlockingDeque<String>(); /** * 在控制台上打印輸出 */ private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build(); public static void main(String[] args) throws InterruptedException { reporter.start(3, TimeUnit.SECONDS); //實例化一個Gauge Gauge<Integer> gauge = new Gauge<Integer>() { @Override public Integer getValue() { return queue.size(); } }; //注冊到容器中 metrics.register(MetricRegistry.name(TestGauges.class, "pending-job", "size"), gauge); //測試JMX JmxReporter jmxReporter = JmxReporter.forRegistry(metrics).build(); jmxReporter.start(); //模擬數據 for (int i=0; i<20; i++){ queue.add("a"); Thread.sleep(1000); } } } /* console output: 14-2-17 15:29:35 =============================================================== -- Gauges ---------------------------------------------------------------------- com.netease.test.metrics.TestGauges.pending-job.size value = 4 14-2-17 15:29:38 =============================================================== -- Gauges ---------------------------------------------------------------------- com.netease.test.metrics.TestGauges.pending-job.size value = 6 14-2-17 15:29:41 =============================================================== -- Gauges ---------------------------------------------------------------------- com.netease.test.metrics.TestGauges.pending-job.size value = 9 */
通過以上步驟將會向MetricsRegistry容器中注冊一個名字為com.netease.test.metrics .TestGauges.pending-job.size的metrics,實時獲取隊列長度的指標。另外,Core包種還擴展了幾種特定的Gauge:
- JMX Gauges—提供給第三方庫只通過JMX將指標暴露出來。
- Ratio Gauges—簡單地通過創建一個gauge計算兩個數的比值。
- Cached Gauges—對某些計量指標提供緩存
Derivative Gauges—提供Gauge的值是基於其他Gauge值的接口。
2. Counter
Counter是Gauge的一個特例,維護一個計數器,可以通過inc()和dec()方法對計數器做修改。使用步驟與Gauge基本類似,在MetricRegistry中提供了靜態方法可以直接實例化一個Counter。
package com.netease.test.metrics; import com.codahale.metrics.ConsoleReporter; import com.codahale.metrics.Counter; import com.codahale.metrics.MetricRegistry; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.TimeUnit; import static com.codahale.metrics.MetricRegistry.*; /** * User: hzwangxx * Date: 14-2-14 * Time: 14:02 * 測試Counter */ public class TestCounter { /** * 實例化一個registry,最核心的一個模塊,相當於一個應用程序的metrics系統的容器,維護一個Map */ private static final MetricRegistry metrics = new MetricRegistry(); /** * 在控制台上打印輸出 */ private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build(); /** * 實例化一個counter,同樣可以通過如下方式進行實例化再注冊進去 * pendingJobs = new Counter(); * metrics.register(MetricRegistry.name(TestCounter.class, "pending-jobs"), pendingJobs); */ private static Counter pendingJobs = metrics.counter(name(TestCounter.class, "pedding-jobs")); // private static Counter pendingJobs = metrics.counter(MetricRegistry.name(TestCounter.class, "pedding-jobs")); private static Queue<String> queue = new LinkedList<String>(); public static void add(String str) { pendingJobs.inc(); queue.offer(str); } public String take() { pendingJobs.dec(); return queue.poll(); } public static void main(String[]args) throws InterruptedException { reporter.start(3, TimeUnit.SECONDS); while(true){ add("1"); Thread.sleep(1000); } } } /* console output: 14-2-17 17:52:34 =============================================================== -- Counters -------------------------------------------------------------------- com.netease.test.metrics.TestCounter.pedding-jobs count = 4 14-2-17 17:52:37 =============================================================== -- Counters -------------------------------------------------------------------- com.netease.test.metrics.TestCounter.pedding-jobs count = 6 14-2-17 17:52:40 =============================================================== -- Counters -------------------------------------------------------------------- com.netease.test.metrics.TestCounter.pedding-jobs count = 9 */
3. Meters
Meters用來度量某個時間段的平均處理次數(request per second),每1、5、15分鍾的TPS。比如一個service的請求數,通過metrics.meter()實例化一個Meter之后,然后通過meter.mark()方法就能將本次請求記錄下來。統計結果有總的請求數,平均每秒的請求數,以及最近的1、5、15分鍾的平均TPS。
package com.netease.test.metrics; import com.codahale.metrics.ConsoleReporter; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; import java.util.concurrent.TimeUnit; import static com.codahale.metrics.MetricRegistry.*; /** * User: hzwangxx * Date: 14-2-17 * Time: 18:34 * 測試Meters */ public class TestMeters { /** * 實例化一個registry,最核心的一個模塊,相當於一個應用程序的metrics系統的容器,維護一個Map */ private static final MetricRegistry metrics = new MetricRegistry(); /** * 在控制台上打印輸出 */ private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build(); /** * 實例化一個Meter */ private static final Meter requests = metrics.meter(name(TestMeters.class, "request")); public static void handleRequest() { requests.mark(); } public static void main(String[] args) throws InterruptedException { reporter.start(3, TimeUnit.SECONDS); while(true){ handleRequest(); Thread.sleep(100); } } } /* 14-2-17 18:43:08 =============================================================== -- Meters ---------------------------------------------------------------------- com.netease.test.metrics.TestMeters.request count = 30 mean rate = 9.95 events/second 1-minute rate = 0.00 events/second 5-minute rate = 0.00 events/second 15-minute rate = 0.00 events/second 14-2-17 18:43:11 =============================================================== -- Meters ---------------------------------------------------------------------- com.netease.test.metrics.TestMeters.request count = 60 mean rate = 9.99 events/second 1-minute rate = 10.00 events/second 5-minute rate = 10.00 events/second 15-minute rate = 10.00 events/second 14-2-17 18:43:14 =============================================================== -- Meters ---------------------------------------------------------------------- com.netease.test.metrics.TestMeters.request count = 90 mean rate = 9.99 events/second 1-minute rate = 10.00 events/second 5-minute rate = 10.00 events/second 15-minute rate = 10.00 events/second */