blob: e07d3f9248e77d5fd9ec8321939c5d061eddca1f [file] [log] [blame]
pankaj390abbc2014-10-01 17:01:05 -07001package org.onlab.metrics;
2
pankaj5de84112014-10-02 15:33:28 -07003import java.io.File;
4import java.util.Locale;
pankaj390abbc2014-10-01 17:01:05 -07005import java.util.Map;
pankaj5de84112014-10-02 15:33:28 -07006import java.util.concurrent.ConcurrentHashMap;
pankaj390abbc2014-10-01 17:01:05 -07007import java.util.concurrent.ConcurrentMap;
pankaj5de84112014-10-02 15:33:28 -07008import java.util.concurrent.TimeUnit;
pankaj390abbc2014-10-01 17:01:05 -07009
pankajf6577b62014-10-02 16:38:38 -070010import org.apache.felix.scr.annotations.Activate;
11import org.apache.felix.scr.annotations.Component;
12import org.apache.felix.scr.annotations.Deactivate;
13
pankaj390abbc2014-10-01 17:01:05 -070014import com.codahale.metrics.Counter;
pankaj5de84112014-10-02 15:33:28 -070015import com.codahale.metrics.CsvReporter;
pankaj390abbc2014-10-01 17:01:05 -070016import com.codahale.metrics.Gauge;
17import com.codahale.metrics.Histogram;
18import com.codahale.metrics.Meter;
19import com.codahale.metrics.Metric;
20import com.codahale.metrics.MetricFilter;
21import com.codahale.metrics.MetricRegistry;
22import com.codahale.metrics.Timer;
23
24/**
25 * This class holds the Metrics registry for ONOS.
26 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
27 * string-based naming scheme: COMPONENT.FEATURE.NAME.
28 * Example: "Topology.Counters.TopologyUpdates".
29 * The COMPONENT and FEATURE names have to be registered in advance before
30 * a metric can be created. Example:
31 * <pre>
32 * <code>
33 * private final MetricsManager.MetricsComponent COMPONENT =
34 * MetricsManager.registerComponent("Topology");
35 * private final MetricsManager.MetricsFeature FEATURE =
36 * COMPONENT.registerFeature("Counters");
37 * private final Counter counterTopologyUpdates =
38 * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
39 * </code>
40 * </pre>
41 * Gauges are slightly different because they are not created directly in
42 * this class, but are allocated by the caller and passed in for registration:
43 * <pre>
44 * <code>
45 * private final Gauge<Long> gauge =
46 * new {@literal Gauge<Long>}() {
47 * {@literal @}Override
48 * public Long getValue() {
49 * return gaugeValue;
50 * }
51 * };
52 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
53 * </code>
54 * </pre>
55 */
pankajf6577b62014-10-02 16:38:38 -070056@Component(immediate = true)
pankaj390abbc2014-10-01 17:01:05 -070057public final class MetricsManager implements MetricsService {
58
59 /**
60 * Registry to hold the Components defined in the system.
61 */
pankaje138e272014-10-02 15:17:11 -070062 private ConcurrentMap<String, MetricsComponent> componentsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070063
64 /**
65 * Registry for the Metrics objects created in the system.
66 */
pankaj5de84112014-10-02 15:33:28 -070067 private final MetricRegistry metricsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070068
pankaj5de84112014-10-02 15:33:28 -070069 /**
70 * Default Reporter for this metrics manager.
71 */
72 private final CsvReporter reporter;
pankaje138e272014-10-02 15:17:11 -070073
pankaj5de84112014-10-02 15:33:28 -070074 public MetricsManager() {
75 this.componentsRegistry = new ConcurrentHashMap<>();
76 this.metricsRegistry = new MetricRegistry();
77
78 this.reporter = CsvReporter.forRegistry(metricsRegistry)
79 .formatFor(Locale.US)
80 .convertRatesTo(TimeUnit.SECONDS)
81 .convertDurationsTo(TimeUnit.MICROSECONDS)
82 .build(new File("/tmp/"));
83
84 reporter.start(10, TimeUnit.SECONDS);
pankaje138e272014-10-02 15:17:11 -070085 }
pankaj390abbc2014-10-01 17:01:05 -070086
pankajf6577b62014-10-02 16:38:38 -070087 @Activate
88 public void activate() {
89 }
90
91 @Deactivate
92 public void deactivate() {
93 }
94
pankaj390abbc2014-10-01 17:01:05 -070095 /**
96 * Registers a component.
97 *
98 * @param name name of the Component to register
99 * @return MetricsComponent object that can be used to create Metrics.
100 */
pankaj3855bcb2014-10-01 18:17:31 -0700101 @Override
pankaj390abbc2014-10-01 17:01:05 -0700102 public MetricsComponent registerComponent(final String name) {
103 MetricsComponent component = componentsRegistry.get(name);
104 if (component == null) {
105 final MetricsComponent createdComponent = new MetricsComponent(name);
106 component = componentsRegistry.putIfAbsent(name, createdComponent);
107 if (component == null) {
108 component = createdComponent;
109 }
110 }
111 return component;
112 }
113
114 /**
115 * Generates a name for a Metric from its component and feature.
116 *
117 * @param component component the metric is defined in
118 * @param feature feature the metric is defined in
119 * @param metricName local name of the metric
120 *
121 * @return full name of the metric
122 */
pankaj3855bcb2014-10-01 18:17:31 -0700123 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -0700124 final MetricsFeature feature,
125 final String metricName) {
126 return MetricRegistry.name(component.getName(),
127 feature.getName(),
128 metricName);
129 }
130
131 /**
132 * Creates a Counter metric.
133 *
134 * @param component component the Counter is defined in
135 * @param feature feature the Counter is defined in
136 * @param metricName local name of the metric
137 * @return the created Counter Meteric
138 */
pankaj3855bcb2014-10-01 18:17:31 -0700139 @Override
pankaj390abbc2014-10-01 17:01:05 -0700140 public Counter createCounter(final MetricsComponent component,
141 final MetricsFeature feature,
142 final String metricName) {
143 final String name = generateName(component, feature, metricName);
144 return metricsRegistry.counter(name);
145 }
146
147 /**
148 * Creates a Histogram metric.
149 *
150 * @param component component the Histogram is defined in
151 * @param feature feature the Histogram is defined in
152 * @param metricName local name of the metric
153 * @return the created Histogram Metric
154 */
pankaj3855bcb2014-10-01 18:17:31 -0700155 @Override
pankaj390abbc2014-10-01 17:01:05 -0700156 public Histogram createHistogram(final MetricsComponent component,
157 final MetricsFeature feature,
158 final String metricName) {
159 final String name = generateName(component, feature, metricName);
160 return metricsRegistry.histogram(name);
161 }
162
163 /**
164 * Creates a Timer metric.
165 *
166 * @param component component the Timer is defined in
167 * @param feature feature the Timeer is defined in
168 * @param metricName local name of the metric
169 * @return the created Timer Metric
170 */
pankaj3855bcb2014-10-01 18:17:31 -0700171 @Override
pankaj390abbc2014-10-01 17:01:05 -0700172 public Timer createTimer(final MetricsComponent component,
173 final MetricsFeature feature,
174 final String metricName) {
175 final String name = generateName(component, feature, metricName);
176 return metricsRegistry.timer(name);
177 }
178
179 /**
180 * Creates a Meter metric.
181 *
182 * @param component component the Meter is defined in
183 * @param feature feature the Meter is defined in
184 * @param metricName local name of the metric
185 * @return the created Meter Metric
186 */
pankaj3855bcb2014-10-01 18:17:31 -0700187 @Override
pankaj390abbc2014-10-01 17:01:05 -0700188 public Meter createMeter(final MetricsComponent component,
189 final MetricsFeature feature,
190 final String metricName) {
191 final String name = generateName(component, feature, metricName);
192 return metricsRegistry.meter(name);
193 }
194
195 /**
196 * Registers an already created Metric. This is used for situation where a
197 * caller needs to allocate its own Metric, but still register it with the
198 * system.
199 *
200 * @param <T> Metric type
201 * @param component component the Metric is defined in
202 * @param feature feature the Metric is defined in
203 * @param metricName local name of the metric
204 * @param metric Metric to register
205 * @return the registered Metric
206 */
pankaj3855bcb2014-10-01 18:17:31 -0700207 @Override
pankaj390abbc2014-10-01 17:01:05 -0700208 public <T extends Metric> T registerMetric(
209 final MetricsComponent component,
210 final MetricsFeature feature,
211 final String metricName,
212 final T metric) {
213 final String name = generateName(component, feature, metricName);
214 metricsRegistry.register(name, metric);
215 return metric;
216 }
217
218 /**
219 * Fetches the existing Timers.
220 *
221 * @param filter filter to use to select Timers
222 * @return a map of the Timers that match the filter, with the key as the
223 * name String to the Timer.
224 */
pankaj3855bcb2014-10-01 18:17:31 -0700225 @Override
pankaj390abbc2014-10-01 17:01:05 -0700226 public Map<String, Timer> getTimers(final MetricFilter filter) {
227 return metricsRegistry.getTimers(filter);
228 }
229
230 /**
231 * Fetches the existing Gauges.
232 *
233 * @param filter filter to use to select Gauges
234 * @return a map of the Gauges that match the filter, with the key as the
235 * name String to the Gauge.
236 */
pankaj3855bcb2014-10-01 18:17:31 -0700237 @Override
pankaj390abbc2014-10-01 17:01:05 -0700238 public Map<String, Gauge> getGauges(final MetricFilter filter) {
239 return metricsRegistry.getGauges(filter);
240 }
241
242 /**
243 * Fetches the existing Counters.
244 *
245 * @param filter filter to use to select Counters
246 * @return a map of the Counters that match the filter, with the key as the
247 * name String to the Counter.
248 */
pankaj3855bcb2014-10-01 18:17:31 -0700249 @Override
pankaj390abbc2014-10-01 17:01:05 -0700250 public Map<String, Counter> getCounters(final MetricFilter filter) {
251 return metricsRegistry.getCounters(filter);
252 }
253
254 /**
255 * Fetches the existing Meters.
256 *
257 * @param filter filter to use to select Meters
258 * @return a map of the Meters that match the filter, with the key as the
259 * name String to the Meter.
260 */
pankaj3855bcb2014-10-01 18:17:31 -0700261 @Override
pankaj390abbc2014-10-01 17:01:05 -0700262 public Map<String, Meter> getMeters(final MetricFilter filter) {
263 return metricsRegistry.getMeters(filter);
264 }
265
266 /**
267 * Fetches the existing Histograms.
268 *
269 * @param filter filter to use to select Histograms
270 * @return a map of the Histograms that match the filter, with the key as the
271 * name String to the Histogram.
272 */
pankaj3855bcb2014-10-01 18:17:31 -0700273 @Override
pankaj390abbc2014-10-01 17:01:05 -0700274 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
275 return metricsRegistry.getHistograms(filter);
276 }
277
278 /**
279 * Removes all Metrics that match a given filter.
280 *
281 * @param filter filter to use to select the Metrics to remove.
282 */
pankaj3855bcb2014-10-01 18:17:31 -0700283 @Override
pankaj390abbc2014-10-01 17:01:05 -0700284 public void removeMatching(final MetricFilter filter) {
285 metricsRegistry.removeMatching(filter);
286 }
287}
288