blob: eaf2a54a7d4d4323dc83ab48a6f8b86defbd1726 [file] [log] [blame]
pankaj390abbc2014-10-01 17:01:05 -07001package org.onlab.metrics;
2
3import java.util.Map;
pankaj5de84112014-10-02 15:33:28 -07004import java.util.concurrent.ConcurrentHashMap;
pankaj390abbc2014-10-01 17:01:05 -07005import java.util.concurrent.ConcurrentMap;
pankaj5de84112014-10-02 15:33:28 -07006import java.util.concurrent.TimeUnit;
pankaj390abbc2014-10-01 17:01:05 -07007
pankajf6577b62014-10-02 16:38:38 -07008import org.apache.felix.scr.annotations.Activate;
9import org.apache.felix.scr.annotations.Component;
10import org.apache.felix.scr.annotations.Deactivate;
11
pankaj366ce8b2014-10-07 17:18:37 -070012import com.codahale.metrics.ConsoleReporter;
pankaj390abbc2014-10-01 17:01:05 -070013import com.codahale.metrics.Counter;
14import com.codahale.metrics.Gauge;
15import com.codahale.metrics.Histogram;
16import com.codahale.metrics.Meter;
17import com.codahale.metrics.Metric;
18import com.codahale.metrics.MetricFilter;
19import com.codahale.metrics.MetricRegistry;
20import com.codahale.metrics.Timer;
21
22/**
23 * This class holds the Metrics registry for ONOS.
24 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
25 * string-based naming scheme: COMPONENT.FEATURE.NAME.
26 * Example: "Topology.Counters.TopologyUpdates".
27 * The COMPONENT and FEATURE names have to be registered in advance before
28 * a metric can be created. Example:
29 * <pre>
30 * <code>
31 * private final MetricsManager.MetricsComponent COMPONENT =
32 * MetricsManager.registerComponent("Topology");
33 * private final MetricsManager.MetricsFeature FEATURE =
34 * COMPONENT.registerFeature("Counters");
35 * private final Counter counterTopologyUpdates =
36 * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
37 * </code>
38 * </pre>
39 * Gauges are slightly different because they are not created directly in
40 * this class, but are allocated by the caller and passed in for registration:
41 * <pre>
42 * <code>
43 * private final Gauge<Long> gauge =
44 * new {@literal Gauge<Long>}() {
45 * {@literal @}Override
46 * public Long getValue() {
47 * return gaugeValue;
48 * }
49 * };
50 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
51 * </code>
52 * </pre>
53 */
pankajf6577b62014-10-02 16:38:38 -070054@Component(immediate = true)
pankaj390abbc2014-10-01 17:01:05 -070055public final class MetricsManager implements MetricsService {
56
57 /**
58 * Registry to hold the Components defined in the system.
59 */
pankaje138e272014-10-02 15:17:11 -070060 private ConcurrentMap<String, MetricsComponent> componentsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070061
62 /**
63 * Registry for the Metrics objects created in the system.
64 */
pankaj5de84112014-10-02 15:33:28 -070065 private final MetricRegistry metricsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070066
pankaj5de84112014-10-02 15:33:28 -070067 /**
68 * Default Reporter for this metrics manager.
69 */
pankaj366ce8b2014-10-07 17:18:37 -070070 private final ConsoleReporter reporter;
pankaje138e272014-10-02 15:17:11 -070071
pankaj5de84112014-10-02 15:33:28 -070072 public MetricsManager() {
pankaj5de84112014-10-02 15:33:28 -070073 this.metricsRegistry = new MetricRegistry();
pankaj366ce8b2014-10-07 17:18:37 -070074 this.reporter = ConsoleReporter.forRegistry(metricsRegistry)
pankaj5de84112014-10-02 15:33:28 -070075 .convertRatesTo(TimeUnit.SECONDS)
76 .convertDurationsTo(TimeUnit.MICROSECONDS)
pankaj366ce8b2014-10-07 17:18:37 -070077 .build();
pankaje138e272014-10-02 15:17:11 -070078 }
pankaj390abbc2014-10-01 17:01:05 -070079
pankajf6577b62014-10-02 16:38:38 -070080 @Activate
81 public void activate() {
pankaj9e34ff22014-10-06 13:21:03 -070082 this.componentsRegistry = new ConcurrentHashMap<>();
83 reporter.start(10, TimeUnit.SECONDS);
pankajf6577b62014-10-02 16:38:38 -070084 }
85
86 @Deactivate
87 public void deactivate() {
pankaj9e34ff22014-10-06 13:21:03 -070088 reporter.stop();
pankajf6577b62014-10-02 16:38:38 -070089 }
90
pankaj390abbc2014-10-01 17:01:05 -070091 /**
92 * Registers a component.
93 *
94 * @param name name of the Component to register
95 * @return MetricsComponent object that can be used to create Metrics.
96 */
pankaj3855bcb2014-10-01 18:17:31 -070097 @Override
pankaj390abbc2014-10-01 17:01:05 -070098 public MetricsComponent registerComponent(final String name) {
99 MetricsComponent component = componentsRegistry.get(name);
100 if (component == null) {
101 final MetricsComponent createdComponent = new MetricsComponent(name);
102 component = componentsRegistry.putIfAbsent(name, createdComponent);
103 if (component == null) {
104 component = createdComponent;
105 }
106 }
107 return component;
108 }
109
110 /**
111 * Generates a name for a Metric from its component and feature.
112 *
113 * @param component component the metric is defined in
114 * @param feature feature the metric is defined in
115 * @param metricName local name of the metric
116 *
117 * @return full name of the metric
118 */
pankaj3855bcb2014-10-01 18:17:31 -0700119 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -0700120 final MetricsFeature feature,
121 final String metricName) {
122 return MetricRegistry.name(component.getName(),
123 feature.getName(),
124 metricName);
125 }
126
127 /**
128 * Creates a Counter metric.
129 *
130 * @param component component the Counter is defined in
131 * @param feature feature the Counter is defined in
132 * @param metricName local name of the metric
133 * @return the created Counter Meteric
134 */
pankaj3855bcb2014-10-01 18:17:31 -0700135 @Override
pankaj390abbc2014-10-01 17:01:05 -0700136 public Counter createCounter(final MetricsComponent component,
137 final MetricsFeature feature,
138 final String metricName) {
139 final String name = generateName(component, feature, metricName);
140 return metricsRegistry.counter(name);
141 }
142
143 /**
144 * Creates a Histogram metric.
145 *
146 * @param component component the Histogram is defined in
147 * @param feature feature the Histogram is defined in
148 * @param metricName local name of the metric
149 * @return the created Histogram Metric
150 */
pankaj3855bcb2014-10-01 18:17:31 -0700151 @Override
pankaj390abbc2014-10-01 17:01:05 -0700152 public Histogram createHistogram(final MetricsComponent component,
153 final MetricsFeature feature,
154 final String metricName) {
155 final String name = generateName(component, feature, metricName);
156 return metricsRegistry.histogram(name);
157 }
158
159 /**
160 * Creates a Timer metric.
161 *
162 * @param component component the Timer is defined in
163 * @param feature feature the Timeer is defined in
164 * @param metricName local name of the metric
165 * @return the created Timer Metric
166 */
pankaj3855bcb2014-10-01 18:17:31 -0700167 @Override
pankaj390abbc2014-10-01 17:01:05 -0700168 public Timer createTimer(final MetricsComponent component,
169 final MetricsFeature feature,
170 final String metricName) {
171 final String name = generateName(component, feature, metricName);
172 return metricsRegistry.timer(name);
173 }
174
175 /**
176 * Creates a Meter metric.
177 *
178 * @param component component the Meter is defined in
179 * @param feature feature the Meter is defined in
180 * @param metricName local name of the metric
181 * @return the created Meter Metric
182 */
pankaj3855bcb2014-10-01 18:17:31 -0700183 @Override
pankaj390abbc2014-10-01 17:01:05 -0700184 public Meter createMeter(final MetricsComponent component,
185 final MetricsFeature feature,
186 final String metricName) {
187 final String name = generateName(component, feature, metricName);
188 return metricsRegistry.meter(name);
189 }
190
191 /**
192 * Registers an already created Metric. This is used for situation where a
193 * caller needs to allocate its own Metric, but still register it with the
194 * system.
195 *
196 * @param <T> Metric type
197 * @param component component the Metric is defined in
198 * @param feature feature the Metric is defined in
199 * @param metricName local name of the metric
200 * @param metric Metric to register
201 * @return the registered Metric
202 */
pankaj3855bcb2014-10-01 18:17:31 -0700203 @Override
pankaj390abbc2014-10-01 17:01:05 -0700204 public <T extends Metric> T registerMetric(
205 final MetricsComponent component,
206 final MetricsFeature feature,
207 final String metricName,
208 final T metric) {
209 final String name = generateName(component, feature, metricName);
210 metricsRegistry.register(name, metric);
211 return metric;
212 }
213
214 /**
215 * Fetches the existing Timers.
216 *
217 * @param filter filter to use to select Timers
218 * @return a map of the Timers that match the filter, with the key as the
219 * name String to the Timer.
220 */
pankaj3855bcb2014-10-01 18:17:31 -0700221 @Override
pankaj390abbc2014-10-01 17:01:05 -0700222 public Map<String, Timer> getTimers(final MetricFilter filter) {
223 return metricsRegistry.getTimers(filter);
224 }
225
226 /**
227 * Fetches the existing Gauges.
228 *
229 * @param filter filter to use to select Gauges
230 * @return a map of the Gauges that match the filter, with the key as the
231 * name String to the Gauge.
232 */
pankaj3855bcb2014-10-01 18:17:31 -0700233 @Override
pankaj390abbc2014-10-01 17:01:05 -0700234 public Map<String, Gauge> getGauges(final MetricFilter filter) {
235 return metricsRegistry.getGauges(filter);
236 }
237
238 /**
239 * Fetches the existing Counters.
240 *
241 * @param filter filter to use to select Counters
242 * @return a map of the Counters that match the filter, with the key as the
243 * name String to the Counter.
244 */
pankaj3855bcb2014-10-01 18:17:31 -0700245 @Override
pankaj390abbc2014-10-01 17:01:05 -0700246 public Map<String, Counter> getCounters(final MetricFilter filter) {
247 return metricsRegistry.getCounters(filter);
248 }
249
250 /**
251 * Fetches the existing Meters.
252 *
253 * @param filter filter to use to select Meters
254 * @return a map of the Meters that match the filter, with the key as the
255 * name String to the Meter.
256 */
pankaj3855bcb2014-10-01 18:17:31 -0700257 @Override
pankaj390abbc2014-10-01 17:01:05 -0700258 public Map<String, Meter> getMeters(final MetricFilter filter) {
259 return metricsRegistry.getMeters(filter);
260 }
261
262 /**
263 * Fetches the existing Histograms.
264 *
265 * @param filter filter to use to select Histograms
266 * @return a map of the Histograms that match the filter, with the key as the
267 * name String to the Histogram.
268 */
pankaj3855bcb2014-10-01 18:17:31 -0700269 @Override
pankaj390abbc2014-10-01 17:01:05 -0700270 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
271 return metricsRegistry.getHistograms(filter);
272 }
273
274 /**
275 * Removes all Metrics that match a given filter.
276 *
277 * @param filter filter to use to select the Metrics to remove.
278 */
pankaj3855bcb2014-10-01 18:17:31 -0700279 @Override
pankaj390abbc2014-10-01 17:01:05 -0700280 public void removeMatching(final MetricFilter filter) {
281 metricsRegistry.removeMatching(filter);
282 }
283}
284