blob: 357791e602904f6e0efdc27a484035677134bba9 [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() {
pankaj5de84112014-10-02 15:33:28 -070075 this.metricsRegistry = new MetricRegistry();
pankaj5de84112014-10-02 15:33:28 -070076 this.reporter = CsvReporter.forRegistry(metricsRegistry)
77 .formatFor(Locale.US)
78 .convertRatesTo(TimeUnit.SECONDS)
79 .convertDurationsTo(TimeUnit.MICROSECONDS)
pankaj9e34ff22014-10-06 13:21:03 -070080 .build(new File("/var/onos/log/metrics/"));
pankaje138e272014-10-02 15:17:11 -070081 }
pankaj390abbc2014-10-01 17:01:05 -070082
pankajf6577b62014-10-02 16:38:38 -070083 @Activate
84 public void activate() {
pankaj9e34ff22014-10-06 13:21:03 -070085 this.componentsRegistry = new ConcurrentHashMap<>();
86 reporter.start(10, TimeUnit.SECONDS);
pankajf6577b62014-10-02 16:38:38 -070087 }
88
89 @Deactivate
90 public void deactivate() {
pankaj9e34ff22014-10-06 13:21:03 -070091 reporter.stop();
pankajf6577b62014-10-02 16:38:38 -070092 }
93
pankaj390abbc2014-10-01 17:01:05 -070094 /**
95 * Registers a component.
96 *
97 * @param name name of the Component to register
98 * @return MetricsComponent object that can be used to create Metrics.
99 */
pankaj3855bcb2014-10-01 18:17:31 -0700100 @Override
pankaj390abbc2014-10-01 17:01:05 -0700101 public MetricsComponent registerComponent(final String name) {
102 MetricsComponent component = componentsRegistry.get(name);
103 if (component == null) {
104 final MetricsComponent createdComponent = new MetricsComponent(name);
105 component = componentsRegistry.putIfAbsent(name, createdComponent);
106 if (component == null) {
107 component = createdComponent;
108 }
109 }
110 return component;
111 }
112
113 /**
114 * Generates a name for a Metric from its component and feature.
115 *
116 * @param component component the metric is defined in
117 * @param feature feature the metric is defined in
118 * @param metricName local name of the metric
119 *
120 * @return full name of the metric
121 */
pankaj3855bcb2014-10-01 18:17:31 -0700122 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -0700123 final MetricsFeature feature,
124 final String metricName) {
125 return MetricRegistry.name(component.getName(),
126 feature.getName(),
127 metricName);
128 }
129
130 /**
131 * Creates a Counter metric.
132 *
133 * @param component component the Counter is defined in
134 * @param feature feature the Counter is defined in
135 * @param metricName local name of the metric
136 * @return the created Counter Meteric
137 */
pankaj3855bcb2014-10-01 18:17:31 -0700138 @Override
pankaj390abbc2014-10-01 17:01:05 -0700139 public Counter createCounter(final MetricsComponent component,
140 final MetricsFeature feature,
141 final String metricName) {
142 final String name = generateName(component, feature, metricName);
143 return metricsRegistry.counter(name);
144 }
145
146 /**
147 * Creates a Histogram metric.
148 *
149 * @param component component the Histogram is defined in
150 * @param feature feature the Histogram is defined in
151 * @param metricName local name of the metric
152 * @return the created Histogram Metric
153 */
pankaj3855bcb2014-10-01 18:17:31 -0700154 @Override
pankaj390abbc2014-10-01 17:01:05 -0700155 public Histogram createHistogram(final MetricsComponent component,
156 final MetricsFeature feature,
157 final String metricName) {
158 final String name = generateName(component, feature, metricName);
159 return metricsRegistry.histogram(name);
160 }
161
162 /**
163 * Creates a Timer metric.
164 *
165 * @param component component the Timer is defined in
166 * @param feature feature the Timeer is defined in
167 * @param metricName local name of the metric
168 * @return the created Timer Metric
169 */
pankaj3855bcb2014-10-01 18:17:31 -0700170 @Override
pankaj390abbc2014-10-01 17:01:05 -0700171 public Timer createTimer(final MetricsComponent component,
172 final MetricsFeature feature,
173 final String metricName) {
174 final String name = generateName(component, feature, metricName);
175 return metricsRegistry.timer(name);
176 }
177
178 /**
179 * Creates a Meter metric.
180 *
181 * @param component component the Meter is defined in
182 * @param feature feature the Meter is defined in
183 * @param metricName local name of the metric
184 * @return the created Meter Metric
185 */
pankaj3855bcb2014-10-01 18:17:31 -0700186 @Override
pankaj390abbc2014-10-01 17:01:05 -0700187 public Meter createMeter(final MetricsComponent component,
188 final MetricsFeature feature,
189 final String metricName) {
190 final String name = generateName(component, feature, metricName);
191 return metricsRegistry.meter(name);
192 }
193
194 /**
195 * Registers an already created Metric. This is used for situation where a
196 * caller needs to allocate its own Metric, but still register it with the
197 * system.
198 *
199 * @param <T> Metric type
200 * @param component component the Metric is defined in
201 * @param feature feature the Metric is defined in
202 * @param metricName local name of the metric
203 * @param metric Metric to register
204 * @return the registered Metric
205 */
pankaj3855bcb2014-10-01 18:17:31 -0700206 @Override
pankaj390abbc2014-10-01 17:01:05 -0700207 public <T extends Metric> T registerMetric(
208 final MetricsComponent component,
209 final MetricsFeature feature,
210 final String metricName,
211 final T metric) {
212 final String name = generateName(component, feature, metricName);
213 metricsRegistry.register(name, metric);
214 return metric;
215 }
216
217 /**
218 * Fetches the existing Timers.
219 *
220 * @param filter filter to use to select Timers
221 * @return a map of the Timers that match the filter, with the key as the
222 * name String to the Timer.
223 */
pankaj3855bcb2014-10-01 18:17:31 -0700224 @Override
pankaj390abbc2014-10-01 17:01:05 -0700225 public Map<String, Timer> getTimers(final MetricFilter filter) {
226 return metricsRegistry.getTimers(filter);
227 }
228
229 /**
230 * Fetches the existing Gauges.
231 *
232 * @param filter filter to use to select Gauges
233 * @return a map of the Gauges that match the filter, with the key as the
234 * name String to the Gauge.
235 */
pankaj3855bcb2014-10-01 18:17:31 -0700236 @Override
pankaj390abbc2014-10-01 17:01:05 -0700237 public Map<String, Gauge> getGauges(final MetricFilter filter) {
238 return metricsRegistry.getGauges(filter);
239 }
240
241 /**
242 * Fetches the existing Counters.
243 *
244 * @param filter filter to use to select Counters
245 * @return a map of the Counters that match the filter, with the key as the
246 * name String to the Counter.
247 */
pankaj3855bcb2014-10-01 18:17:31 -0700248 @Override
pankaj390abbc2014-10-01 17:01:05 -0700249 public Map<String, Counter> getCounters(final MetricFilter filter) {
250 return metricsRegistry.getCounters(filter);
251 }
252
253 /**
254 * Fetches the existing Meters.
255 *
256 * @param filter filter to use to select Meters
257 * @return a map of the Meters that match the filter, with the key as the
258 * name String to the Meter.
259 */
pankaj3855bcb2014-10-01 18:17:31 -0700260 @Override
pankaj390abbc2014-10-01 17:01:05 -0700261 public Map<String, Meter> getMeters(final MetricFilter filter) {
262 return metricsRegistry.getMeters(filter);
263 }
264
265 /**
266 * Fetches the existing Histograms.
267 *
268 * @param filter filter to use to select Histograms
269 * @return a map of the Histograms that match the filter, with the key as the
270 * name String to the Histogram.
271 */
pankaj3855bcb2014-10-01 18:17:31 -0700272 @Override
pankaj390abbc2014-10-01 17:01:05 -0700273 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
274 return metricsRegistry.getHistograms(filter);
275 }
276
277 /**
278 * Removes all Metrics that match a given filter.
279 *
280 * @param filter filter to use to select the Metrics to remove.
281 */
pankaj3855bcb2014-10-01 18:17:31 -0700282 @Override
pankaj390abbc2014-10-01 17:01:05 -0700283 public void removeMatching(final MetricFilter filter) {
284 metricsRegistry.removeMatching(filter);
285 }
286}
287