1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.omid.metrics;
19
20 import com.codahale.metrics.ConsoleReporter;
21 import com.codahale.metrics.CsvReporter;
22 import com.codahale.metrics.MetricFilter;
23 import com.codahale.metrics.MetricRegistry;
24 import com.codahale.metrics.ScheduledReporter;
25 import com.codahale.metrics.Slf4jReporter;
26 import com.codahale.metrics.Timer.Context;
27 import com.codahale.metrics.graphite.Graphite;
28 import com.codahale.metrics.graphite.GraphiteReporter;
29 import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
30 import org.apache.phoenix.thirdparty.com.google.common.net.HostAndPort;
31 import org.apache.commons.io.FileUtils;
32 import org.apache.omid.metrics.CodahaleMetricsConfig.Reporter;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.io.File;
37 import java.io.IOException;
38 import java.net.InetSocketAddress;
39 import java.util.ArrayList;
40 import java.util.List;
41 import java.util.concurrent.TimeUnit;
42
43 public class CodahaleMetricsProvider implements MetricsProvider, MetricsRegistry {
44
45 private static final Logger LOG = LoggerFactory.getLogger(CodahaleMetricsProvider.class);
46
47 private MetricRegistry metrics = new MetricRegistry();
48 private List<ScheduledReporter> reporters = new ArrayList<>();
49
50 private final int metricsOutputFrequencyInSecs;
51
52 public CodahaleMetricsProvider(CodahaleMetricsConfig conf) throws IOException {
53 metricsOutputFrequencyInSecs = conf.getOutputFreqInSecs();
54 int reporterCount = 0;
55 for (Reporter reporter : conf.getReporters()) {
56 ScheduledReporter codahaleReporter = null;
57 switch (reporter) {
58 case CONSOLE:
59 codahaleReporter = createAndGetConfiguredConsoleReporter();
60 break;
61 case GRAPHITE:
62 codahaleReporter = createAndGetConfiguredGraphiteReporter(conf.getPrefix(),
63 conf.getGraphiteHostConfig());
64 break;
65 case CSV:
66 codahaleReporter = createAndGetConfiguredCSVReporter(conf.getPrefix(),
67 conf.getCsvDir());
68 break;
69 case SLF4J:
70 codahaleReporter = createAndGetConfiguredSlf4jReporter(conf.getSlf4jLogger());
71 break;
72 }
73 if (codahaleReporter != null) {
74 reporters.add(codahaleReporter);
75 reporterCount++;
76 }
77 }
78 if (reporterCount == 0) {
79 LOG.warn("No metric reporters found, so metrics won't be available");
80 }
81 startMetrics();
82 }
83
84 @Override
85 public void startMetrics() {
86 for (ScheduledReporter r : reporters) {
87 LOG.info("Starting metrics reporter {} reporting every {} Secs",
88 r.getClass().getCanonicalName(), metricsOutputFrequencyInSecs);
89 r.start(metricsOutputFrequencyInSecs, TimeUnit.SECONDS);
90 }
91 }
92
93 @Override
94 public void stopMetrics() {
95 for (ScheduledReporter r : reporters) {
96 r.report();
97 LOG.info("Stopping reporter {}", r.toString());
98 r.stop();
99 }
100 }
101
102 @Override
103 public <T extends Number> void gauge(String name, Gauge<T> appGauge) {
104 metrics.register(name, new CodahaleGauge<>(appGauge));
105 }
106
107 @Override
108 public Counter counter(String name) {
109 com.codahale.metrics.Counter counter = metrics.counter(name);
110 return new CodahaleCounterWrapper(counter);
111 }
112
113
114 @Override
115 public Timer timer(String name) {
116 com.codahale.metrics.Timer timer = metrics.timer(name);
117 return new CodahaleTimerWrapper(timer);
118 }
119
120 @Override
121 public Meter meter(String name) {
122 com.codahale.metrics.Meter meter = metrics.meter(name);
123 return new CodahaleMeterWrapper(meter);
124 }
125
126 @Override
127 public Histogram histogram(String name) {
128 com.codahale.metrics.Histogram histogram = metrics.histogram(name);
129 return new CodahaleHistogramWrapper(histogram);
130 }
131
132 private ScheduledReporter createAndGetConfiguredConsoleReporter() {
133 return ConsoleReporter.forRegistry(metrics)
134 .convertRatesTo(TimeUnit.SECONDS)
135 .convertDurationsTo(TimeUnit.MILLISECONDS)
136 .build();
137 }
138
139 private ScheduledReporter createAndGetConfiguredGraphiteReporter(String prefix, String graphiteHost) {
140 LOG.info("Configuring Graphite reporter. Sendig data to host:port {}", graphiteHost);
141 HostAndPort addr = HostAndPort.fromString(graphiteHost);
142
143 final Graphite graphite = new Graphite(
144 new InetSocketAddress(addr.getHost(), addr.getPort()));
145
146 return GraphiteReporter.forRegistry(metrics)
147 .prefixedWith(prefix)
148 .convertRatesTo(TimeUnit.SECONDS)
149 .convertDurationsTo(TimeUnit.MILLISECONDS)
150 .filter(MetricFilter.ALL)
151 .build(graphite);
152 }
153
154 private ScheduledReporter createAndGetConfiguredCSVReporter(String prefix, String csvDir) throws IOException {
155
156
157
158
159 File outputDir;
160 if (Strings.isNullOrEmpty(prefix)) {
161 outputDir = new File(csvDir, prefix);
162 } else {
163 outputDir = new File(csvDir);
164 }
165 FileUtils.forceMkdir(outputDir);
166 LOG.info("Configuring stats with csv output to directory [{}]", outputDir.getAbsolutePath());
167 return CsvReporter.forRegistry(metrics)
168 .convertRatesTo(TimeUnit.SECONDS)
169 .convertDurationsTo(TimeUnit.MILLISECONDS)
170 .build(outputDir);
171 }
172
173
174 private ScheduledReporter createAndGetConfiguredSlf4jReporter(String slf4jLogger) {
175 LOG.info("Configuring stats with SLF4J with logger {}", slf4jLogger);
176 return Slf4jReporter.forRegistry(metrics)
177 .outputTo(LoggerFactory.getLogger(slf4jLogger))
178 .convertRatesTo(TimeUnit.SECONDS)
179 .convertDurationsTo(TimeUnit.MILLISECONDS)
180 .build();
181 }
182
183
184
185
186
187 private static class CodahaleGauge<T extends Number> implements com.codahale.metrics.Gauge<T> {
188
189 private final Gauge<T> omidGauge;
190
191 CodahaleGauge(Gauge<T> omidGauge) {
192 this.omidGauge = omidGauge;
193 }
194
195 @Override
196 public T getValue() {
197 return omidGauge.getValue();
198 }
199
200 }
201
202 private static class CodahaleCounterWrapper implements Counter {
203
204 private final com.codahale.metrics.Counter counter;
205
206 CodahaleCounterWrapper(com.codahale.metrics.Counter counter) {
207 this.counter = counter;
208 }
209
210 @Override
211 public void inc() {
212 counter.inc();
213 }
214
215 @Override
216 public void inc(long n) {
217 counter.inc(n);
218 }
219
220 @Override
221 public void dec() {
222 counter.dec();
223 }
224
225 @Override
226 public void dec(long n) {
227 counter.dec(n);
228 }
229
230 }
231
232 private static class CodahaleTimerWrapper implements Timer {
233
234 private final com.codahale.metrics.Timer timer;
235
236 private Context context;
237
238 CodahaleTimerWrapper(com.codahale.metrics.Timer timer) {
239 this.timer = timer;
240 }
241
242 @Override
243 public void start() {
244 context = timer.time();
245 }
246
247 @Override
248 public void stop() {
249 context.stop();
250 }
251
252 @Override
253 public void update(long durationInNs) {
254 timer.update(durationInNs, TimeUnit.NANOSECONDS);
255 }
256
257 }
258
259 private static class CodahaleMeterWrapper implements Meter {
260
261 private com.codahale.metrics.Meter meter;
262
263 CodahaleMeterWrapper(com.codahale.metrics.Meter meter) {
264 this.meter = meter;
265 }
266
267 @Override
268 public void mark() {
269 meter.mark();
270 }
271
272 @Override
273 public void mark(long n) {
274 meter.mark(n);
275 }
276
277 }
278
279 private static class CodahaleHistogramWrapper implements Histogram {
280
281 private com.codahale.metrics.Histogram histogram;
282
283 CodahaleHistogramWrapper(com.codahale.metrics.Histogram histogram) {
284 this.histogram = histogram;
285 }
286
287 @Override
288 public void update(int value) {
289 histogram.update(value);
290 }
291
292 @Override
293 public void update(long value) {
294 histogram.update(value);
295 }
296
297 }
298
299 }