blob: 95e3635631cc26c338c166a0817f11eda79230c7 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
pankaj390abbc2014-10-01 17:01:05 -070019package org.onlab.metrics;
20
21import java.util.Map;
pankaj5de84112014-10-02 15:33:28 -070022import java.util.concurrent.ConcurrentHashMap;
pankaj390abbc2014-10-01 17:01:05 -070023import java.util.concurrent.ConcurrentMap;
24
25import com.codahale.metrics.Counter;
26import com.codahale.metrics.Gauge;
27import com.codahale.metrics.Histogram;
28import com.codahale.metrics.Meter;
29import com.codahale.metrics.Metric;
30import com.codahale.metrics.MetricFilter;
31import com.codahale.metrics.MetricRegistry;
32import com.codahale.metrics.Timer;
33
34/**
35 * This class holds the Metrics registry for ONOS.
36 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
37 * string-based naming scheme: COMPONENT.FEATURE.NAME.
38 * Example: "Topology.Counters.TopologyUpdates".
39 * The COMPONENT and FEATURE names have to be registered in advance before
40 * a metric can be created. Example:
41 * <pre>
42 * <code>
43 * private final MetricsManager.MetricsComponent COMPONENT =
44 * MetricsManager.registerComponent("Topology");
45 * private final MetricsManager.MetricsFeature FEATURE =
46 * COMPONENT.registerFeature("Counters");
47 * private final Counter counterTopologyUpdates =
48 * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
49 * </code>
50 * </pre>
51 * Gauges are slightly different because they are not created directly in
52 * this class, but are allocated by the caller and passed in for registration:
53 * <pre>
54 * <code>
55 * private final Gauge<Long> gauge =
56 * new {@literal Gauge<Long>}() {
57 * {@literal @}Override
58 * public Long getValue() {
59 * return gaugeValue;
60 * }
61 * };
62 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
63 * </code>
64 * </pre>
65 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070066public class MetricsManager implements MetricsService {
pankaj390abbc2014-10-01 17:01:05 -070067
68 /**
69 * Registry to hold the Components defined in the system.
70 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070071 private ConcurrentMap<String, MetricsComponent> componentsRegistry =
72 new ConcurrentHashMap<>();
pankaj390abbc2014-10-01 17:01:05 -070073
74 /**
75 * Registry for the Metrics objects created in the system.
76 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070077 private MetricRegistry metricsRegistry = new MetricRegistry();
pankaj390abbc2014-10-01 17:01:05 -070078
pankaj5de84112014-10-02 15:33:28 -070079 /**
Pavlin Radoslavov35592492014-10-21 21:49:58 -070080 * Clears the internal state.
pankaj5de84112014-10-02 15:33:28 -070081 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070082 protected void clear() {
pankaj9e34ff22014-10-06 13:21:03 -070083 this.componentsRegistry = new ConcurrentHashMap<>();
Pavlin Radoslavov35592492014-10-21 21:49:58 -070084 this.metricsRegistry = new MetricRegistry();
pankajf6577b62014-10-02 16:38:38 -070085 }
86
pankaj390abbc2014-10-01 17:01:05 -070087 /**
88 * Registers a component.
89 *
90 * @param name name of the Component to register
91 * @return MetricsComponent object that can be used to create Metrics.
92 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -070093 @Override
94 public MetricsComponent registerComponent(final String name) {
pankaj390abbc2014-10-01 17:01:05 -070095 MetricsComponent component = componentsRegistry.get(name);
96 if (component == null) {
Pavlin Radoslavov35592492014-10-21 21:49:58 -070097 final MetricsComponent createdComponent =
98 new MetricsComponent(name);
pankaj390abbc2014-10-01 17:01:05 -070099 component = componentsRegistry.putIfAbsent(name, createdComponent);
100 if (component == null) {
101 component = createdComponent;
102 }
103 }
104 return component;
105 }
106
107 /**
108 * Generates a name for a Metric from its component and feature.
109 *
110 * @param component component the metric is defined in
111 * @param feature feature the metric is defined in
112 * @param metricName local name of the metric
113 *
114 * @return full name of the metric
115 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700116 private String generateName(final MetricsComponent component,
117 final MetricsFeature feature,
118 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700119 return MetricRegistry.name(component.getName(),
120 feature.getName(),
121 metricName);
122 }
123
124 /**
125 * Creates a Counter metric.
126 *
127 * @param component component the Counter is defined in
128 * @param feature feature the Counter is defined in
129 * @param metricName local name of the metric
130 * @return the created Counter Meteric
131 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700132 @Override
133 public Counter createCounter(final MetricsComponent component,
134 final MetricsFeature feature,
135 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700136 final String name = generateName(component, feature, metricName);
137 return metricsRegistry.counter(name);
138 }
139
140 /**
141 * Creates a Histogram metric.
142 *
143 * @param component component the Histogram is defined in
144 * @param feature feature the Histogram is defined in
145 * @param metricName local name of the metric
146 * @return the created Histogram Metric
147 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700148 @Override
149 public Histogram createHistogram(final MetricsComponent component,
150 final MetricsFeature feature,
151 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700152 final String name = generateName(component, feature, metricName);
153 return metricsRegistry.histogram(name);
154 }
155
156 /**
157 * Creates a Timer metric.
158 *
159 * @param component component the Timer is defined in
160 * @param feature feature the Timeer is defined in
161 * @param metricName local name of the metric
162 * @return the created Timer Metric
163 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700164 @Override
165 public Timer createTimer(final MetricsComponent component,
166 final MetricsFeature feature,
167 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700168 final String name = generateName(component, feature, metricName);
169 return metricsRegistry.timer(name);
170 }
171
172 /**
173 * Creates a Meter metric.
174 *
175 * @param component component the Meter is defined in
176 * @param feature feature the Meter is defined in
177 * @param metricName local name of the metric
178 * @return the created Meter Metric
179 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700180 @Override
181 public Meter createMeter(final MetricsComponent component,
182 final MetricsFeature feature,
183 final String metricName) {
pankaj390abbc2014-10-01 17:01:05 -0700184 final String name = generateName(component, feature, metricName);
185 return metricsRegistry.meter(name);
186 }
187
188 /**
189 * Registers an already created Metric. This is used for situation where a
190 * caller needs to allocate its own Metric, but still register it with the
191 * system.
192 *
193 * @param <T> Metric type
194 * @param component component the Metric is defined in
195 * @param feature feature the Metric is defined in
196 * @param metricName local name of the metric
197 * @param metric Metric to register
198 * @return the registered Metric
199 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700200 @Override
201 public <T extends Metric> T registerMetric(
pankaj390abbc2014-10-01 17:01:05 -0700202 final MetricsComponent component,
203 final MetricsFeature feature,
204 final String metricName,
205 final T metric) {
206 final String name = generateName(component, feature, metricName);
207 metricsRegistry.register(name, metric);
208 return metric;
209 }
210
211 /**
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700212 * Removes the metric with the given name.
213 *
214 * @param component component the Metric is defined in
215 * @param feature feature the Metric is defined in
216 * @param metricName local name of the metric
217 * @return true if the metric existed and was removed, otherwise false
218 */
219 @Override
220 public boolean removeMetric(final MetricsComponent component,
221 final MetricsFeature feature,
222 final String metricName) {
223 final String name = generateName(component, feature, metricName);
224 return metricsRegistry.remove(name);
225 }
226
227 /**
pankaj390abbc2014-10-01 17:01:05 -0700228 * Fetches the existing Timers.
229 *
230 * @param filter filter to use to select Timers
231 * @return a map of the Timers that match the filter, with the key as the
232 * name String to the Timer.
233 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700234 @Override
235 public Map<String, Timer> getTimers(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700236 return metricsRegistry.getTimers(filter);
237 }
238
239 /**
240 * Fetches the existing Gauges.
241 *
242 * @param filter filter to use to select Gauges
243 * @return a map of the Gauges that match the filter, with the key as the
244 * name String to the Gauge.
245 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700246 @Override
247 public Map<String, Gauge> getGauges(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700248 return metricsRegistry.getGauges(filter);
249 }
250
251 /**
252 * Fetches the existing Counters.
253 *
254 * @param filter filter to use to select Counters
255 * @return a map of the Counters that match the filter, with the key as the
256 * name String to the Counter.
257 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700258 @Override
259 public Map<String, Counter> getCounters(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700260 return metricsRegistry.getCounters(filter);
261 }
262
263 /**
264 * Fetches the existing Meters.
265 *
266 * @param filter filter to use to select Meters
267 * @return a map of the Meters that match the filter, with the key as the
268 * name String to the Meter.
269 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700270 @Override
271 public Map<String, Meter> getMeters(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700272 return metricsRegistry.getMeters(filter);
273 }
274
275 /**
276 * Fetches the existing Histograms.
277 *
278 * @param filter filter to use to select Histograms
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700279 * @return a map of the Histograms that match the filter, with the key as
280 * the name String to the Histogram.
pankaj390abbc2014-10-01 17:01:05 -0700281 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700282 @Override
283 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700284 return metricsRegistry.getHistograms(filter);
285 }
286
287 /**
288 * Removes all Metrics that match a given filter.
289 *
290 * @param filter filter to use to select the Metrics to remove.
291 */
Pavlin Radoslavov35592492014-10-21 21:49:58 -0700292 @Override
293 public void removeMatching(final MetricFilter filter) {
pankaj390abbc2014-10-01 17:01:05 -0700294 metricsRegistry.removeMatching(filter);
295 }
296}