blob: 433311fd5e84e72837a0c32d760fb11eefdf2f1a [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
pankaj390abbc2014-10-01 17:01:05 -070016package org.onlab.metrics;
17
pankaj390abbc2014-10-01 17:01:05 -070018import com.codahale.metrics.Counter;
19import com.codahale.metrics.Gauge;
20import com.codahale.metrics.Histogram;
21import com.codahale.metrics.Meter;
22import com.codahale.metrics.Metric;
23import com.codahale.metrics.MetricFilter;
24import com.codahale.metrics.MetricRegistry;
25import com.codahale.metrics.Timer;
Jian Li55cbd5c2016-04-06 09:50:20 -070026import com.google.common.collect.Sets;
27
28import java.util.Map;
29import java.util.Set;
30import java.util.concurrent.ConcurrentHashMap;
31import java.util.concurrent.ConcurrentMap;
pankaj390abbc2014-10-01 17:01:05 -070032
33/**
34 * This class holds the Metrics registry for ONOS.
35 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
36 * string-based naming scheme: COMPONENT.FEATURE.NAME.
37 * Example: "Topology.Counters.TopologyUpdates".
38 * The COMPONENT and FEATURE names have to be registered in advance before
39 * a metric can be created. Example:
40 * <pre>
41 * <code>
42 * private final MetricsManager.MetricsComponent COMPONENT =
43 * MetricsManager.registerComponent("Topology");
44 * private final MetricsManager.MetricsFeature FEATURE =
45 * COMPONENT.registerFeature("Counters");
46 * private final Counter counterTopologyUpdates =
47 * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
48 * </code>
49 * </pre>
50 * Gauges are slightly different because they are not created directly in
51 * this class, but are allocated by the caller and passed in for registration:
52 * <pre>
53 * <code>
Thomas Vachuska7b652ad2014-10-30 14:10:51 -070054 * private final Gauge&lt;Long&gt; gauge =
55 * new {@literal Gauge&lt;Long&gt}() {
pankaj390abbc2014-10-01 17:01:05 -070056 * {@literal @}Override
57 * public Long getValue() {
58 * return gaugeValue;
59 * }
60 * };
61 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
62 * </code>
63 * </pre>
64 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070065public class MetricsManager implements MetricsService {
pankaj390abbc2014-10-01 17:01:05 -070066
67 /**
68 * Registry to hold the Components defined in the system.
69 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070070 private ConcurrentMap<String, MetricsComponent> componentsRegistry =
71 new ConcurrentHashMap<>();
pankaj390abbc2014-10-01 17:01:05 -070072
73 /**
74 * Registry for the Metrics objects created in the system.
75 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070076 private MetricRegistry metricsRegistry = new MetricRegistry();
pankaj390abbc2014-10-01 17:01:05 -070077
pankaj5de84112014-10-02 15:33:28 -070078 /**
Jian Li55cbd5c2016-04-06 09:50:20 -070079 * Reporter for exposing metrics objects to third party persistent system.
80 */
81 private Set<MetricsReporter> reporters = Sets.newConcurrentHashSet();
82
83 /**
Pavlin Radoslavov35592492014-10-21 21:49:58 -070084 * Clears the internal state.
pankaj5de84112014-10-02 15:33:28 -070085 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070086 protected void clear() {
pankaj9e34ff22014-10-06 13:21:03 -070087 this.componentsRegistry = new ConcurrentHashMap<>();
Pavlin Radoslavov35592492014-10-21 21:49:58 -070088 this.metricsRegistry = new MetricRegistry();
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 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070097 @Override
98 public MetricsComponent registerComponent(final String name) {
pankaj390abbc2014-10-01 17:01:05 -070099 MetricsComponent component = componentsRegistry.get(name);
100 if (component == null) {
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700101 final MetricsComponent createdComponent =
102 new MetricsComponent(name);
pankaj390abbc2014-10-01 17:01:05 -0700103 component = componentsRegistry.putIfAbsent(name, createdComponent);
104 if (component == null) {
105 component = createdComponent;
106 }
107 }
108 return component;
109 }
110
111 /**
Jian Li7261c7b2016-03-05 00:04:55 -0800112 * Fetches existing metric registry.
113 *
114 * @return metric registry
115 */
116 @Override
117 public MetricRegistry getMetricRegistry() {
118 return metricsRegistry;
119 }
120
121 /**
pankaj390abbc2014-10-01 17:01:05 -0700122 * Generates a name for a Metric from its component and feature.
123 *
124 * @param component component the metric is defined in
125 * @param feature feature the metric is defined in
126 * @param metricName local name of the metric
127 *
128 * @return full name of the metric
129 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700130 private String generateName(final MetricsComponent component,
131 final MetricsFeature feature,
132 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700133 return MetricRegistry.name(component.getName(),
134 feature.getName(),
135 metricName);
136 }
137
138 /**
139 * Creates a Counter metric.
140 *
141 * @param component component the Counter is defined in
142 * @param feature feature the Counter is defined in
143 * @param metricName local name of the metric
144 * @return the created Counter Meteric
145 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700146 @Override
147 public Counter createCounter(final MetricsComponent component,
148 final MetricsFeature feature,
149 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700150 final String name = generateName(component, feature, metricName);
151 return metricsRegistry.counter(name);
152 }
153
154 /**
155 * Creates a Histogram metric.
156 *
157 * @param component component the Histogram is defined in
158 * @param feature feature the Histogram is defined in
159 * @param metricName local name of the metric
160 * @return the created Histogram Metric
161 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700162 @Override
163 public Histogram createHistogram(final MetricsComponent component,
164 final MetricsFeature feature,
165 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700166 final String name = generateName(component, feature, metricName);
167 return metricsRegistry.histogram(name);
168 }
169
170 /**
171 * Creates a Timer metric.
172 *
173 * @param component component the Timer is defined in
Yuta HIGUCHI6a462832014-11-23 23:56:03 -0800174 * @param feature feature the Timer is defined in
pankaj390abbc2014-10-01 17:01:05 -0700175 * @param metricName local name of the metric
176 * @return the created Timer Metric
177 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700178 @Override
179 public Timer createTimer(final MetricsComponent component,
180 final MetricsFeature feature,
181 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700182 final String name = generateName(component, feature, metricName);
183 return metricsRegistry.timer(name);
184 }
185
186 /**
187 * Creates a Meter metric.
188 *
189 * @param component component the Meter is defined in
190 * @param feature feature the Meter is defined in
191 * @param metricName local name of the metric
192 * @return the created Meter Metric
193 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700194 @Override
195 public Meter createMeter(final MetricsComponent component,
196 final MetricsFeature feature,
197 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700198 final String name = generateName(component, feature, metricName);
199 return metricsRegistry.meter(name);
200 }
201
202 /**
203 * Registers an already created Metric. This is used for situation where a
204 * caller needs to allocate its own Metric, but still register it with the
205 * system.
206 *
207 * @param <T> Metric type
208 * @param component component the Metric is defined in
209 * @param feature feature the Metric is defined in
210 * @param metricName local name of the metric
211 * @param metric Metric to register
212 * @return the registered Metric
213 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700214 @Override
215 public <T extends Metric> T registerMetric(
pankaj390abbc2014-10-01 17:01:05 -0700216 final MetricsComponent component,
217 final MetricsFeature feature,
218 final String metricName,
219 final T metric) {
220 final String name = generateName(component, feature, metricName);
221 metricsRegistry.register(name, metric);
222 return metric;
223 }
224
225 /**
Jian Li55cbd5c2016-04-06 09:50:20 -0700226 * Registers a reporter to receive any changes on metric registry.
227 *
228 * @param reporter metric reporter
229 */
230 @Override
231 public void registerReporter(MetricsReporter reporter) {
232 reporters.add(reporter);
233 }
234
235 /**
236 * Unregisters the given metric reporter.
237 *
238 * @param reporter metric reporter
239 */
240 @Override
241 public void unregisterReporter(MetricsReporter reporter) {
242 reporters.remove(reporter);
243 }
244
245 /**
246 * Notifies the changes on metric registry to all registered reporters.
247 */
248 @Override
249 public void notifyReporters() {
250 reporters.forEach(MetricsReporter::notifyMetricsChange);
251 }
252
253 /**
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700254 * Removes the metric with the given name.
255 *
256 * @param component component the Metric is defined in
257 * @param feature feature the Metric is defined in
258 * @param metricName local name of the metric
259 * @return true if the metric existed and was removed, otherwise false
260 */
261 @Override
262 public boolean removeMetric(final MetricsComponent component,
263 final MetricsFeature feature,
264 final String metricName) {
265 final String name = generateName(component, feature, metricName);
266 return metricsRegistry.remove(name);
267 }
268
269 /**
pankaj390abbc2014-10-01 17:01:05 -0700270 * Fetches the existing Timers.
271 *
272 * @param filter filter to use to select Timers
273 * @return a map of the Timers that match the filter, with the key as the
274 * name String to the Timer.
275 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700276 @Override
277 public Map<String, Timer> getTimers(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700278 return metricsRegistry.getTimers(filter);
279 }
280
281 /**
282 * Fetches the existing Gauges.
283 *
284 * @param filter filter to use to select Gauges
285 * @return a map of the Gauges that match the filter, with the key as the
286 * name String to the Gauge.
287 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700288 @Override
289 public Map<String, Gauge> getGauges(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700290 return metricsRegistry.getGauges(filter);
291 }
292
293 /**
294 * Fetches the existing Counters.
295 *
296 * @param filter filter to use to select Counters
297 * @return a map of the Counters that match the filter, with the key as the
298 * name String to the Counter.
299 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700300 @Override
301 public Map<String, Counter> getCounters(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700302 return metricsRegistry.getCounters(filter);
303 }
304
305 /**
306 * Fetches the existing Meters.
307 *
308 * @param filter filter to use to select Meters
309 * @return a map of the Meters that match the filter, with the key as the
310 * name String to the Meter.
311 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700312 @Override
313 public Map<String, Meter> getMeters(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700314 return metricsRegistry.getMeters(filter);
315 }
316
317 /**
318 * Fetches the existing Histograms.
319 *
320 * @param filter filter to use to select Histograms
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700321 * @return a map of the Histograms that match the filter, with the key as
322 * the name String to the Histogram.
pankaj390abbc2014-10-01 17:01:05 -0700323 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700324 @Override
325 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700326 return metricsRegistry.getHistograms(filter);
327 }
328
329 /**
330 * Removes all Metrics that match a given filter.
331 *
332 * @param filter filter to use to select the Metrics to remove.
333 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700334 @Override
335 public void removeMatching(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700336 metricsRegistry.removeMatching(filter);
337 }
Flavio Castro4b519412015-07-24 12:57:59 -0700338
339 /**
340 * Fetches the existing Meters.
341 *
342 *
343 * @return a map of all metrics with the key as the
344 * name String to the Meter.
345 */
346 public Map<String, Metric> getMetrics() {
347 return metricsRegistry.getMetrics();
348 }
pankaj390abbc2014-10-01 17:01:05 -0700349}