Skip to content

Commit 934dbc9

Browse files
committed
Totally revamp metrics-core.
Big new changes: * Meter and timers no longer have units. Units will be the responsibility of reporters. * Metrics are identified by dotted names, not quasi-ObjectNames. * Reporting architecture has been radically simplified. * You can register metrics not created by the registry. * Separated health checks into their own modules. * No more default registries. I've pinned the other modules to metrics-core 2.2.0 to make a progressive upgrade easier.
1 parent c5da911 commit 934dbc9

File tree

102 files changed

+2203
-5665
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+2203
-5665
lines changed

metrics-core/pom.xml

+3-31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
35
<modelVersion>4.0.0</modelVersion>
46

57
<parent>
@@ -11,34 +13,4 @@
1113
<artifactId>metrics-core</artifactId>
1214
<name>Metrics Core Library</name>
1315
<packaging>bundle</packaging>
14-
15-
<dependencies>
16-
<dependency>
17-
<groupId>com.yammer.metrics</groupId>
18-
<artifactId>metrics-annotation</artifactId>
19-
<version>${project.version}</version>
20-
</dependency>
21-
<dependency>
22-
<groupId>org.slf4j</groupId>
23-
<artifactId>slf4j-api</artifactId>
24-
<version>${slf4j.version}</version>
25-
</dependency>
26-
</dependencies>
27-
28-
<build>
29-
<plugins>
30-
<plugin>
31-
<groupId>org.apache.maven.plugins</groupId>
32-
<artifactId>maven-jar-plugin</artifactId>
33-
<version>2.3.2</version>
34-
<executions>
35-
<execution>
36-
<goals>
37-
<goal>test-jar</goal>
38-
</goals>
39-
</execution>
40-
</executions>
41-
</plugin>
42-
</plugins>
43-
</build>
4416
</project>
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
1-
package com.yammer.metrics.reporting;
2-
3-
import com.yammer.metrics.core.MetricsRegistry;
1+
package com.yammer.metrics;
42

53
import java.util.concurrent.Executors;
64
import java.util.concurrent.ScheduledExecutorService;
75
import java.util.concurrent.ThreadFactory;
86
import java.util.concurrent.TimeUnit;
97
import java.util.concurrent.atomic.AtomicInteger;
108

11-
/**
12-
* An abstract base class for all reporter implementations which periodically poll registered
13-
* metrics (e.g., to send the data to another service).
14-
*/
15-
public abstract class AbstractPollingReporter extends AbstractReporter implements Runnable {
9+
public abstract class AbstractPollingReporter implements Reporter {
1610
/**
1711
* A simple named thread factory.
1812
*/
13+
@SuppressWarnings("NullableProblems")
1914
private static class NamedThreadFactory implements ThreadFactory {
2015
private final ThreadGroup group;
2116
private final AtomicInteger threadNumber = new AtomicInteger(1);
@@ -38,44 +33,45 @@ public Thread newThread(Runnable r) {
3833
}
3934
}
4035

36+
private final MetricRegistry registry;
4137
private final ScheduledExecutorService executor;
4238

4339
/**
4440
* Creates a new {@link AbstractPollingReporter} instance.
4541
*
46-
* @param registry the {@link MetricsRegistry} containing the metrics this reporter will
47-
* report
48-
* @param name the reporter's name
49-
* @see AbstractReporter#AbstractReporter(MetricsRegistry)
42+
* @param registry the {@link MetricRegistry} containing the metrics this reporter will report
43+
* @param name the reporter's name
5044
*/
51-
protected AbstractPollingReporter(MetricsRegistry registry, String name) {
52-
super(registry);
45+
protected AbstractPollingReporter(MetricRegistry registry, String name) {
46+
this.registry = registry;
5347
this.executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(name));
5448
}
5549

5650
/**
5751
* Starts the reporter polling at the given period.
5852
*
59-
* @param period the amount of time between polls
60-
* @param unit the unit for {@code period}
53+
* @param period the amount of time between polls
54+
* @param unit the unit for {@code period}
6155
*/
6256
public void start(long period, TimeUnit unit) {
63-
executor.scheduleAtFixedRate(this, period, period, unit);
57+
executor.scheduleAtFixedRate(new Runnable() {
58+
@Override
59+
public void run() {
60+
report(registry.getGauges(),
61+
registry.getCounters(),
62+
registry.getHistograms(),
63+
registry.getMeters(),
64+
registry.getTimers());
65+
}
66+
}, period, period, unit);
6467
}
6568

66-
@Override
67-
public void shutdown() {
69+
public void stop() {
6870
executor.shutdown();
6971
try {
7072
executor.awaitTermination(1, TimeUnit.SECONDS);
7173
} catch (InterruptedException ignored) {
7274
// do nothing
7375
}
7476
}
75-
76-
/**
77-
* The method called when a a poll is scheduled to occur.
78-
*/
79-
@Override
80-
public abstract void run();
8177
}

metrics-core/src/main/java/com/yammer/metrics/core/Clock.java metrics-core/src/main/java/com/yammer/metrics/Clock.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.yammer.metrics.core;
1+
package com.yammer.metrics;
22

33
import java.lang.management.ManagementFactory;
44
import java.lang.management.ThreadMXBean;
@@ -30,13 +30,12 @@ public long getTime() {
3030
*
3131
* @return the default {@link Clock} instance
3232
*
33-
* @see com.yammer.metrics.core.Clock.UserTimeClock
33+
* @see Clock.UserTimeClock
3434
*/
3535
public static Clock defaultClock() {
3636
return DEFAULT;
3737
}
3838

39-
4039
/**
4140
* A clock implementation which returns the current time in epoch nanoseconds.
4241
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package com.yammer.metrics;
2+
3+
import java.io.PrintStream;
4+
import java.text.DateFormat;
5+
import java.util.*;
6+
7+
// TODO: 3/10/13 <coda> -- write tests
8+
// TODO: 3/10/13 <coda> -- write docs
9+
10+
public class ConsoleReporter extends AbstractPollingReporter {
11+
private static final int CONSOLE_WIDTH = 80;
12+
13+
private final PrintStream output;
14+
private final Locale locale;
15+
private final Clock clock;
16+
private final DateFormat dateFormat;
17+
18+
public ConsoleReporter(MetricRegistry registry,
19+
PrintStream output,
20+
Locale locale,
21+
Clock clock,
22+
TimeZone timeZone) {
23+
super(registry, "console-reporter");
24+
this.output = output;
25+
this.locale = locale;
26+
this.clock = clock;
27+
this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT,
28+
DateFormat.MEDIUM,
29+
locale);
30+
dateFormat.setTimeZone(timeZone);
31+
}
32+
33+
@Override
34+
public void report(SortedMap<String, Gauge> gauges,
35+
SortedMap<String, Counter> counters,
36+
SortedMap<String, Histogram> histograms,
37+
SortedMap<String, Meter> meters,
38+
SortedMap<String, Timer> timers) {
39+
final String dateTime = dateFormat.format(new Date(clock.getTime()));
40+
printWithBanner(dateTime, '=');
41+
output.println();
42+
43+
printWithBanner("-- Gauges", '-');
44+
for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
45+
output.println(entry.getKey());
46+
printGauge(entry);
47+
}
48+
output.println();
49+
50+
printWithBanner("-- Counters", '-');
51+
for (Map.Entry<String, Counter> entry : counters.entrySet()) {
52+
output.println(entry.getKey());
53+
printCounter(entry);
54+
}
55+
output.println();
56+
57+
printWithBanner("-- Histograms", '-');
58+
for (Map.Entry<String, Histogram> entry : histograms.entrySet()) {
59+
output.println(entry.getKey());
60+
printHistogram(entry.getValue());
61+
}
62+
output.println();
63+
64+
printWithBanner("-- Meters", '-');
65+
for (Map.Entry<String, Meter> entry : meters.entrySet()) {
66+
output.println(entry.getKey());
67+
printMetered(entry.getValue());
68+
}
69+
output.println();
70+
71+
printWithBanner("-- Timers", '-');
72+
for (Map.Entry<String, Timer> entry : timers.entrySet()) {
73+
output.println(entry.getKey());
74+
printTimer(entry.getValue());
75+
}
76+
output.println();
77+
78+
output.println();
79+
output.flush();
80+
}
81+
82+
private void printCounter(Map.Entry<String, Counter> entry) {
83+
output.printf(locale, " count = %d%n", entry.getValue().getCount());
84+
}
85+
86+
private void printGauge(Map.Entry<String, Gauge> entry) {
87+
output.printf(locale, " value = %s%n", entry.getValue().getValue());
88+
}
89+
90+
private void printHistogram(Histogram histogram) {
91+
output.printf(locale, " count = %d%n", histogram.getCount());
92+
output.printf(locale, " min = %2.2f%n", histogram.getMin());
93+
output.printf(locale, " max = %2.2f%n", histogram.getMax());
94+
output.printf(locale, " mean = %2.2f%n", histogram.getMean());
95+
output.printf(locale, " stddev = %2.2f%n", histogram.getStdDev());
96+
printSnapshot(histogram.getSnapshot());
97+
}
98+
99+
private void printTimer(Timer timer) {
100+
final Snapshot snapshot = timer.getSnapshot();
101+
printMetered(timer);
102+
output.printf(locale, " min = %2.2f%n", timer.getMin());
103+
output.printf(locale, " max = %2.2f%n", timer.getMax());
104+
output.printf(locale, " mean = %2.2f%n", timer.getMean());
105+
output.printf(locale, " stddev = %2.2f%n", timer.getStdDev());
106+
printSnapshot(snapshot);
107+
}
108+
109+
private void printSnapshot(Snapshot snapshot) {
110+
output.printf(locale, " median = %2.2f%n", snapshot.getMedian());
111+
output.printf(locale, " 75%% <= %2.2f%n", snapshot.get75thPercentile());
112+
output.printf(locale, " 95%% <= %2.2f%n", snapshot.get95thPercentile());
113+
output.printf(locale, " 98%% <= %2.2f%n", snapshot.get98thPercentile());
114+
output.printf(locale, " 99%% <= %2.2f%n", snapshot.get99thPercentile());
115+
output.printf(locale, " 99.9%% <= %2.2f%n", snapshot.get999thPercentile());
116+
}
117+
118+
private void printMetered(Metered timer) {
119+
output.printf(locale, " count = %d%n", timer.getCount());
120+
output.printf(locale, " mean rate = %2.2f%n", timer.getMeanRate());
121+
output.printf(locale, " 1-minute rate = %2.2f%n", timer.getOneMinuteRate());
122+
output.printf(locale, " 5-minute rate = %2.2f%n", timer.getFiveMinuteRate());
123+
output.printf(locale, " 15-minute rate = %2.2f%n", timer.getFifteenMinuteRate());
124+
}
125+
126+
private void printWithBanner(String s, char c) {
127+
output.print(s);
128+
output.print(' ');
129+
for (int i = 0; i < (CONSOLE_WIDTH - s.length() - 1); i++) {
130+
output.print(c);
131+
}
132+
output.println();
133+
}
134+
}

metrics-core/src/main/java/com/yammer/metrics/core/Counter.java metrics-core/src/main/java/com/yammer/metrics/Counter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.yammer.metrics.core;
1+
package com.yammer.metrics;
22

33
import java.util.concurrent.atomic.AtomicLong;
44

@@ -8,7 +8,7 @@
88
public class Counter implements Metric {
99
private final AtomicLong count;
1010

11-
Counter() {
11+
public Counter() {
1212
this.count = new AtomicLong(0);
1313
}
1414

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.yammer.metrics;
2+
3+
import java.util.SortedMap;
4+
5+
// TODO: 3/10/13 <coda> -- implement CsvReporter
6+
7+
public class CsvReporter extends AbstractPollingReporter {
8+
/**
9+
* Creates a new {@link CsvReporter} instance.
10+
*
11+
* @param registry the {@link MetricRegistry} containing the metrics this reporter will report
12+
*/
13+
protected CsvReporter(MetricRegistry registry) {
14+
super(registry, "csv-reporter");
15+
}
16+
17+
@Override
18+
public void report(SortedMap<String, Gauge> gauges,
19+
SortedMap<String, Counter> counters,
20+
SortedMap<String, Histogram> histograms,
21+
SortedMap<String, Meter> meters,
22+
SortedMap<String, Timer> timers) {
23+
}
24+
}

metrics-core/src/main/java/com/yammer/metrics/stats/EWMA.java metrics-core/src/main/java/com/yammer/metrics/EWMA.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.yammer.metrics.stats;
1+
package com.yammer.metrics;
22

33
import java.util.concurrent.TimeUnit;
44
import java.util.concurrent.atomic.AtomicLong;

metrics-core/src/main/java/com/yammer/metrics/stats/ExponentiallyDecayingSample.java metrics-core/src/main/java/com/yammer/metrics/ExponentiallyDecayingSample.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
package com.yammer.metrics.stats;
2-
3-
import com.yammer.metrics.core.Clock;
1+
package com.yammer.metrics;
42

53
import java.util.ArrayList;
64
import java.util.concurrent.ConcurrentSkipListMap;

metrics-core/src/main/java/com/yammer/metrics/core/Gauge.java metrics-core/src/main/java/com/yammer/metrics/Gauge.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.yammer.metrics.core;
1+
package com.yammer.metrics;
22

33

44
/**
@@ -15,7 +15,7 @@
1515
*
1616
* @param <T> the type of the metric's value
1717
*/
18-
public abstract class Gauge<T> implements Metric {
18+
public interface Gauge<T> extends Metric {
1919
/**
2020
* Returns the metric's current value.
2121
*

metrics-core/src/main/java/com/yammer/metrics/HealthChecks.java

-21
This file was deleted.

0 commit comments

Comments
 (0)