blob: 6c8cad2c0ae351b9d57878ee9c4da7db363d0139 [file] [log] [blame]
Ray Milkey26921af2014-06-30 16:27:40 -07001package net.onrc.onos.core.metrics;
2
Ray Milkey49d67be2014-07-10 13:47:01 -07003import com.codahale.metrics.Counter;
Ray Milkey128651a2014-07-14 11:24:28 -07004import com.codahale.metrics.Gauge;
Ray Milkey49d67be2014-07-10 13:47:01 -07005import com.codahale.metrics.Histogram;
6import com.codahale.metrics.Meter;
7import com.codahale.metrics.Metric;
Ray Milkey128651a2014-07-14 11:24:28 -07008import com.codahale.metrics.MetricFilter;
Ray Milkey26921af2014-06-30 16:27:40 -07009import com.codahale.metrics.MetricRegistry;
Ray Milkey49d67be2014-07-10 13:47:01 -070010import com.codahale.metrics.Timer;
Ray Milkey26921af2014-06-30 16:27:40 -070011
Ray Milkey128651a2014-07-14 11:24:28 -070012import java.util.Map;
Ray Milkey71cd2c82014-07-16 15:02:33 -070013import java.util.concurrent.ConcurrentHashMap;
14import java.util.concurrent.ConcurrentMap;
Ray Milkey128651a2014-07-14 11:24:28 -070015
Ray Milkey26921af2014-06-30 16:27:40 -070016/**
17 * This class acts a singleton to hold the Metrics registry for ONOS.
Ray Milkey71cd2c82014-07-16 15:02:33 -070018 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
19 * string-based naming scheme: COMPONENT.FEATURE.NAME.
20 * Example: "Topology.Counters.TopologyUpdates".
21 * The COMPONENT and FEATURE names have to be registered in advance before
22 * a metric can be created. Example:
23 * <pre>
24 * <code>
25 * private static final OnosMetrics.MetricsComponent COMPONENT =
26 * OnosMetrics.registerComponent("Topology");
27 * private static final OnosMetrics.MetricsFeature FEATURE =
28 * COMPONENT.registerFeature("Counters");
29 * private final Counter counterTopologyUpdates =
30 * OnosMetrics.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
31 * </code>
32 * </pre>
33 * Gauges are slightly different because they are not created directly in
34 * this class, but are allocated by the caller and passed in for registration:
35 * <pre>
36 * <code>
37 * private final Gauge<Long> gauge =
38 * new {@literal Gauge<Long>}() {
39 * {@literal @}Override
40 * public Long getValue() {
41 * return gaugeValue;
42 * }
43 * };
44 * OnosMetrics.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
45 * </code>
46 * </pre>
Ray Milkey26921af2014-06-30 16:27:40 -070047 */
48public final class OnosMetrics {
49
50 /**
51 * Hide constructor. The only way to get the registry is through the
52 * singleton getter.
53 */
54 private OnosMetrics() {}
55
Ray Milkey49d67be2014-07-10 13:47:01 -070056 /**
57 * Components that can hold Metrics. This is used as the first part of
58 * a Metric's name.
59 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070060 public interface MetricsComponent {
Ray Milkey49d67be2014-07-10 13:47:01 -070061 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -070062 * Fetches the name of the Component.
Ray Milkey49d67be2014-07-10 13:47:01 -070063 *
Ray Milkey71cd2c82014-07-16 15:02:33 -070064 * @return name of the Component
Ray Milkey49d67be2014-07-10 13:47:01 -070065 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070066 public String getName();
Ray Milkey49d67be2014-07-10 13:47:01 -070067
Ray Milkey71cd2c82014-07-16 15:02:33 -070068 /**
69 * Registers a Feature for this component.
70 *
71 * @param featureName name of the Feature to register
72 * @return Feature object that can be used when creating Metrics
73 */
74 public MetricsFeature registerFeature(final String featureName);
Ray Milkey49d67be2014-07-10 13:47:01 -070075 }
76
77 /**
78 * Features that can hold Metrics. This is used as the second part of
79 * a Metric's name.
80 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070081 public interface MetricsFeature {
Ray Milkey49d67be2014-07-10 13:47:01 -070082 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -070083 * Fetches the name of the Feature.
84 *
85 * @return name of the Feature
Ray Milkey49d67be2014-07-10 13:47:01 -070086 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070087 public String getName();
88 }
Ray Milkey49d67be2014-07-10 13:47:01 -070089
Ray Milkey71cd2c82014-07-16 15:02:33 -070090 /**
91 * Implementation of a class to represent the Component portion of a
92 * Metric's name.
93 */
94 private static final class Component implements MetricsComponent {
Ray Milkey49d67be2014-07-10 13:47:01 -070095 private final String name;
96
97 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -070098 * Constructs a component from a name.
Ray Milkey49d67be2014-07-10 13:47:01 -070099 *
Ray Milkey71cd2c82014-07-16 15:02:33 -0700100 * @param newName name of the component
Ray Milkey49d67be2014-07-10 13:47:01 -0700101 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700102 private Component(final String newName) {
103 name = newName;
Ray Milkey49d67be2014-07-10 13:47:01 -0700104 }
105
106 @Override
Ray Milkey71cd2c82014-07-16 15:02:33 -0700107 public String getName() {
108 return name;
109 }
110
111 /**
112 * Registry to hold the Features defined in this Component.
113 */
114 private ConcurrentMap<String, MetricsFeature> featuresRegistry =
115 new ConcurrentHashMap<>();
116
117 @Override
118 public MetricsFeature registerFeature(final String featureName) {
119 MetricsFeature feature = featuresRegistry.get(featureName);
120 if (feature == null) {
121 final MetricsFeature createdFeature = new Feature(featureName);
122 feature = featuresRegistry.putIfAbsent(featureName, createdFeature);
123 if (feature == null) {
124 feature = createdFeature;
125 }
126 }
127 return feature;
128 }
129 }
130
131 /**
132 * Implementation of a class to represent the Feature portion of a Metric's
133 * name.
134 */
135 private static final class Feature implements MetricsFeature {
136 private final String name;
137
138 /**
139 * Constructs a Feature from a name.
140 *
141 * @param newName name of the Feature
142 */
143 private Feature(final String newName) {
144 name = newName;
145 }
146
147 @Override
148 public String getName() {
Ray Milkey49d67be2014-07-10 13:47:01 -0700149 return name;
150 }
151 }
152
Ray Milkey71cd2c82014-07-16 15:02:33 -0700153 /**
154 * Registry to hold the Components defined in the system.
155 */
156 private static ConcurrentMap<String, MetricsComponent> componentsRegistry =
157 new ConcurrentHashMap<>();
158
159 /**
160 * Registers a component.
161 *
162 * @param name name of the Component to register
163 * @return MetricsComponent object that can be used to create Metrics.
164 */
165 public static MetricsComponent registerComponent(final String name) {
166 MetricsComponent component = componentsRegistry.get(name);
167 if (component == null) {
168 final MetricsComponent createdComponent = new Component(name);
169 component = componentsRegistry.putIfAbsent(name, createdComponent);
170 if (component == null) {
171 component = createdComponent;
172 }
173 }
174 return component;
175 }
176
177 /**
178 * Registry for the Metrics objects created in the system.
179 */
Ray Milkey26921af2014-06-30 16:27:40 -0700180 private static final MetricRegistry METRICS_REGISTRY = new MetricRegistry();
181
182 /**
Ray Milkey49d67be2014-07-10 13:47:01 -0700183 * Generates a name for a Metric from its component and feature.
184 *
185 * @param component component the metric is defined in
186 * @param feature feature the metric is defined in
187 * @param metricName local name of the metric
188 *
189 * @return full name of the metric
190 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700191 public static String generateName(final MetricsComponent component,
192 final MetricsFeature feature,
Ray Milkey49d67be2014-07-10 13:47:01 -0700193 final String metricName) {
Ray Milkey71cd2c82014-07-16 15:02:33 -0700194 return MetricRegistry.name(component.getName(),
195 feature.getName(),
196 metricName);
Ray Milkey49d67be2014-07-10 13:47:01 -0700197 }
198
199 /**
200 * Creates a Counter metric.
201 *
202 * @param component component the Counter is defined in
203 * @param feature feature the Counter is defined in
204 * @param metricName local name of the metric
205 * @return Counter Meteric
206 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700207 public static Counter createCounter(final MetricsComponent component,
208 final MetricsFeature feature,
Ray Milkey49d67be2014-07-10 13:47:01 -0700209 final String metricName) {
210 final String name = generateName(component, feature, metricName);
211 return METRICS_REGISTRY.counter(name);
212 }
213
214 /**
215 * Creates a Histogram metric.
216 *
217 * @param component component the Histogram is defined in
218 * @param feature feature the Histogram is defined in
219 * @param metricName local name of the metric
220 * @return Histogram Metric
221 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700222 public static Histogram createHistogram(final MetricsComponent component,
223 final MetricsFeature feature,
Ray Milkey49d67be2014-07-10 13:47:01 -0700224 final String metricName) {
225 final String name = generateName(component, feature, metricName);
226 return METRICS_REGISTRY.histogram(name);
227 }
228
229 /**
230 * Creates a Timer metric.
231 *
232 * @param component component the Timer is defined in
233 * @param feature feature the Timeer is defined in
234 * @param metricName local name of the metric
235 * @return Timer Metric
236 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700237 public static Timer createTimer(final MetricsComponent component,
238 final MetricsFeature feature,
Ray Milkey49d67be2014-07-10 13:47:01 -0700239 final String metricName) {
240 final String name = generateName(component, feature, metricName);
241 return METRICS_REGISTRY.timer(name);
242 }
243
244 /**
245 * Creates a Meter metric.
246 *
247 * @param component component the Meter is defined in
248 * @param feature feature the Meter is defined in
249 * @param metricName local name of the metric
250 * @return Meter Metric
251 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700252 public static Meter createMeter(final MetricsComponent component,
253 final MetricsFeature feature,
Ray Milkey49d67be2014-07-10 13:47:01 -0700254 final String metricName) {
255 final String name = generateName(component, feature, metricName);
256 return METRICS_REGISTRY.meter(name);
257 }
258
259 /**
260 * Registers an already created Metric. This is used for situation where a
261 * caller needs to allocate its own Metric, but still register it with the
262 * system.
263 *
264 * @param component component the Metric is defined in
265 * @param feature feature the metric is defined in
266 * @param metricName local name of the metric
267 * @param metric Metric to register
268 */
Ray Milkey71cd2c82014-07-16 15:02:33 -0700269 public static void registerMetric(final MetricsComponent component,
270 final MetricsFeature feature,
Ray Milkey128651a2014-07-14 11:24:28 -0700271 final String metricName,
272 final Metric metric) {
Ray Milkey49d67be2014-07-10 13:47:01 -0700273 final String name = generateName(component, feature, metricName);
274 METRICS_REGISTRY.register(name, metric);
275 }
276
277 /**
Ray Milkey128651a2014-07-14 11:24:28 -0700278 * Fetches the existing Timers.
Ray Milkey26921af2014-06-30 16:27:40 -0700279 *
Ray Milkey128651a2014-07-14 11:24:28 -0700280 * @param filter filter to use to select Timers
281 * @return a map of the Timers that match the filter, with the key as the
282 * name String to the Timer.
Ray Milkey26921af2014-06-30 16:27:40 -0700283 */
Ray Milkey128651a2014-07-14 11:24:28 -0700284 public static Map<String, Timer> getTimers(final MetricFilter filter) {
285 return METRICS_REGISTRY.getTimers(filter);
286 }
287
288 /**
289 * Fetches the existing Gauges.
290 *
291 * @param filter filter to use to select Gauges
292 * @return a map of the Gauges that match the filter, with the key as the
293 * name String to the Gauge.
294 */
295 @SuppressWarnings("rawtypes")
296 public static Map<String, Gauge> getGauges(final MetricFilter filter) {
297 return METRICS_REGISTRY.getGauges(filter);
298 }
299
300 /**
301 * Fetches the existing Counters.
302 *
303 * @param filter filter to use to select Counters
304 * @return a map of the Counters that match the filter, with the key as the
305 * name String to the Counter.
306 */
307 public static Map<String, Counter> getCounters(final MetricFilter filter) {
308 return METRICS_REGISTRY.getCounters(filter);
309 }
310
311 /**
312 * Fetches the existing Meters.
313 *
314 * @param filter filter to use to select Meters
315 * @return a map of the Meters that match the filter, with the key as the
316 * name String to the Meter.
317 */
318 public static Map<String, Meter> getMeters(final MetricFilter filter) {
319 return METRICS_REGISTRY.getMeters(filter);
320 }
321
322 /**
323 * Fetches the existing Histograms.
324 *
325 * @param filter filter to use to select Histograms
326 * @return a map of the Histograms that match the filter, with the key as the
327 * name String to the Histogram.
328 */
329 public static Map<String, Histogram> getHistograms(final MetricFilter filter) {
330 return METRICS_REGISTRY.getHistograms(filter);
331 }
332
333 /**
334 * Removes all Metrics that match a given filter.
335 *
336 * @param filter filter to use to select the Metrics to remove.
337 */
338 public static void removeMatching(final MetricFilter filter) {
339 METRICS_REGISTRY.removeMatching(filter);
Ray Milkey26921af2014-06-30 16:27:40 -0700340 }
341}
342