blob: 8494d4e577942c7ca1840355eabc1353731e399d [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;
pankaj9c060c02014-10-08 10:21:29 -070011import org.slf4j.Logger;
12import org.slf4j.LoggerFactory;
pankajf6577b62014-10-02 16:38:38 -070013
pankajb847eae2014-10-08 14:39:25 -070014import com.codahale.metrics.ConsoleReporter;
pankaj390abbc2014-10-01 17:01:05 -070015import com.codahale.metrics.Counter;
16import 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
pankaj9c060c02014-10-08 10:21:29 -070059 private final Logger log = LoggerFactory.getLogger(getClass());
pankaj390abbc2014-10-01 17:01:05 -070060 /**
61 * Registry to hold the Components defined in the system.
62 */
pankaje138e272014-10-02 15:17:11 -070063 private ConcurrentMap<String, MetricsComponent> componentsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070064
65 /**
66 * Registry for the Metrics objects created in the system.
67 */
pankaj5de84112014-10-02 15:33:28 -070068 private final MetricRegistry metricsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070069
pankaj5de84112014-10-02 15:33:28 -070070 /**
71 * Default Reporter for this metrics manager.
72 */
pankajb847eae2014-10-08 14:39:25 -070073 //private final Slf4jReporter reporter;
74 private final ConsoleReporter reporter;
pankaje138e272014-10-02 15:17:11 -070075
pankaj5de84112014-10-02 15:33:28 -070076 public MetricsManager() {
pankaj5de84112014-10-02 15:33:28 -070077 this.metricsRegistry = new MetricRegistry();
pankajb847eae2014-10-08 14:39:25 -070078// this.reporter = Slf4jReporter.forRegistry(this.metricsRegistry)
79// .outputTo(log)
80// .convertRatesTo(TimeUnit.SECONDS)
pankaj6005d232014-10-08 15:32:38 -070081// .convertDurationsTo(TimeUnit.MICROSECONDS)
pankajb847eae2014-10-08 14:39:25 -070082// .build();
83 this.reporter = ConsoleReporter.forRegistry(this.metricsRegistry)
pankaj5de84112014-10-02 15:33:28 -070084 .convertRatesTo(TimeUnit.SECONDS)
pankaj6005d232014-10-08 15:32:38 -070085 .convertDurationsTo(TimeUnit.MICROSECONDS)
pankaj366ce8b2014-10-07 17:18:37 -070086 .build();
pankaje138e272014-10-02 15:17:11 -070087 }
pankaj390abbc2014-10-01 17:01:05 -070088
pankajf6577b62014-10-02 16:38:38 -070089 @Activate
90 public void activate() {
pankaj9e34ff22014-10-06 13:21:03 -070091 this.componentsRegistry = new ConcurrentHashMap<>();
92 reporter.start(10, TimeUnit.SECONDS);
pankajf6577b62014-10-02 16:38:38 -070093 }
94
95 @Deactivate
96 public void deactivate() {
pankaj9e34ff22014-10-06 13:21:03 -070097 reporter.stop();
pankajf6577b62014-10-02 16:38:38 -070098 }
99
pankaj390abbc2014-10-01 17:01:05 -0700100 /**
101 * Registers a component.
102 *
103 * @param name name of the Component to register
104 * @return MetricsComponent object that can be used to create Metrics.
105 */
pankaj3855bcb2014-10-01 18:17:31 -0700106 @Override
pankaj390abbc2014-10-01 17:01:05 -0700107 public MetricsComponent registerComponent(final String name) {
108 MetricsComponent component = componentsRegistry.get(name);
109 if (component == null) {
110 final MetricsComponent createdComponent = new MetricsComponent(name);
111 component = componentsRegistry.putIfAbsent(name, createdComponent);
112 if (component == null) {
113 component = createdComponent;
114 }
115 }
116 return component;
117 }
118
119 /**
120 * Generates a name for a Metric from its component and feature.
121 *
122 * @param component component the metric is defined in
123 * @param feature feature the metric is defined in
124 * @param metricName local name of the metric
125 *
126 * @return full name of the metric
127 */
pankaj3855bcb2014-10-01 18:17:31 -0700128 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -0700129 final MetricsFeature feature,
130 final String metricName) {
131 return MetricRegistry.name(component.getName(),
132 feature.getName(),
133 metricName);
134 }
135
136 /**
137 * Creates a Counter metric.
138 *
139 * @param component component the Counter is defined in
140 * @param feature feature the Counter is defined in
141 * @param metricName local name of the metric
142 * @return the created Counter Meteric
143 */
pankaj3855bcb2014-10-01 18:17:31 -0700144 @Override
pankaj390abbc2014-10-01 17:01:05 -0700145 public Counter createCounter(final MetricsComponent component,
146 final MetricsFeature feature,
147 final String metricName) {
148 final String name = generateName(component, feature, metricName);
149 return metricsRegistry.counter(name);
150 }
151
152 /**
153 * Creates a Histogram metric.
154 *
155 * @param component component the Histogram is defined in
156 * @param feature feature the Histogram is defined in
157 * @param metricName local name of the metric
158 * @return the created Histogram Metric
159 */
pankaj3855bcb2014-10-01 18:17:31 -0700160 @Override
pankaj390abbc2014-10-01 17:01:05 -0700161 public Histogram createHistogram(final MetricsComponent component,
162 final MetricsFeature feature,
163 final String metricName) {
164 final String name = generateName(component, feature, metricName);
165 return metricsRegistry.histogram(name);
166 }
167
168 /**
169 * Creates a Timer metric.
170 *
171 * @param component component the Timer is defined in
172 * @param feature feature the Timeer is defined in
173 * @param metricName local name of the metric
174 * @return the created Timer Metric
175 */
pankaj3855bcb2014-10-01 18:17:31 -0700176 @Override
pankaj390abbc2014-10-01 17:01:05 -0700177 public Timer createTimer(final MetricsComponent component,
178 final MetricsFeature feature,
179 final String metricName) {
180 final String name = generateName(component, feature, metricName);
181 return metricsRegistry.timer(name);
182 }
183
184 /**
185 * Creates a Meter metric.
186 *
187 * @param component component the Meter is defined in
188 * @param feature feature the Meter is defined in
189 * @param metricName local name of the metric
190 * @return the created Meter Metric
191 */
pankaj3855bcb2014-10-01 18:17:31 -0700192 @Override
pankaj390abbc2014-10-01 17:01:05 -0700193 public Meter createMeter(final MetricsComponent component,
194 final MetricsFeature feature,
195 final String metricName) {
196 final String name = generateName(component, feature, metricName);
197 return metricsRegistry.meter(name);
198 }
199
200 /**
201 * Registers an already created Metric. This is used for situation where a
202 * caller needs to allocate its own Metric, but still register it with the
203 * system.
204 *
205 * @param <T> Metric type
206 * @param component component the Metric is defined in
207 * @param feature feature the Metric is defined in
208 * @param metricName local name of the metric
209 * @param metric Metric to register
210 * @return the registered Metric
211 */
pankaj3855bcb2014-10-01 18:17:31 -0700212 @Override
pankaj390abbc2014-10-01 17:01:05 -0700213 public <T extends Metric> T registerMetric(
214 final MetricsComponent component,
215 final MetricsFeature feature,
216 final String metricName,
217 final T metric) {
218 final String name = generateName(component, feature, metricName);
219 metricsRegistry.register(name, metric);
220 return metric;
221 }
222
223 /**
224 * Fetches the existing Timers.
225 *
226 * @param filter filter to use to select Timers
227 * @return a map of the Timers that match the filter, with the key as the
228 * name String to the Timer.
229 */
pankaj3855bcb2014-10-01 18:17:31 -0700230 @Override
pankaj390abbc2014-10-01 17:01:05 -0700231 public Map<String, Timer> getTimers(final MetricFilter filter) {
232 return metricsRegistry.getTimers(filter);
233 }
234
235 /**
236 * Fetches the existing Gauges.
237 *
238 * @param filter filter to use to select Gauges
239 * @return a map of the Gauges that match the filter, with the key as the
240 * name String to the Gauge.
241 */
pankaj3855bcb2014-10-01 18:17:31 -0700242 @Override
pankaj390abbc2014-10-01 17:01:05 -0700243 public Map<String, Gauge> getGauges(final MetricFilter filter) {
244 return metricsRegistry.getGauges(filter);
245 }
246
247 /**
248 * Fetches the existing Counters.
249 *
250 * @param filter filter to use to select Counters
251 * @return a map of the Counters that match the filter, with the key as the
252 * name String to the Counter.
253 */
pankaj3855bcb2014-10-01 18:17:31 -0700254 @Override
pankaj390abbc2014-10-01 17:01:05 -0700255 public Map<String, Counter> getCounters(final MetricFilter filter) {
256 return metricsRegistry.getCounters(filter);
257 }
258
259 /**
260 * Fetches the existing Meters.
261 *
262 * @param filter filter to use to select Meters
263 * @return a map of the Meters that match the filter, with the key as the
264 * name String to the Meter.
265 */
pankaj3855bcb2014-10-01 18:17:31 -0700266 @Override
pankaj390abbc2014-10-01 17:01:05 -0700267 public Map<String, Meter> getMeters(final MetricFilter filter) {
268 return metricsRegistry.getMeters(filter);
269 }
270
271 /**
272 * Fetches the existing Histograms.
273 *
274 * @param filter filter to use to select Histograms
275 * @return a map of the Histograms that match the filter, with the key as the
276 * name String to the Histogram.
277 */
pankaj3855bcb2014-10-01 18:17:31 -0700278 @Override
pankaj390abbc2014-10-01 17:01:05 -0700279 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
280 return metricsRegistry.getHistograms(filter);
281 }
282
283 /**
284 * Removes all Metrics that match a given filter.
285 *
286 * @param filter filter to use to select the Metrics to remove.
287 */
pankaj3855bcb2014-10-01 18:17:31 -0700288 @Override
pankaj390abbc2014-10-01 17:01:05 -0700289 public void removeMatching(final MetricFilter filter) {
290 metricsRegistry.removeMatching(filter);
291 }
292}
293