blob: d163335df3fdabe8ba61d4c41fd628420ca64e93 [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 /**
Ray Milkey40eb9c82014-07-18 10:28:11 -070051 * Registry to hold the Components defined in the system.
52 */
53 private static ConcurrentMap<String, MetricsComponent> componentsRegistry =
54 new ConcurrentHashMap<>();
55
56 /**
57 * Registry for the Metrics objects created in the system.
58 */
59 private static final MetricRegistry METRICS_REGISTRY = new MetricRegistry();
60
61 /**
Ray Milkey26921af2014-06-30 16:27:40 -070062 * Hide constructor. The only way to get the registry is through the
63 * singleton getter.
64 */
65 private OnosMetrics() {}
66
Ray Milkey49d67be2014-07-10 13:47:01 -070067 /**
68 * Components that can hold Metrics. This is used as the first part of
69 * a Metric's name.
70 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070071 public interface MetricsComponent {
Ray Milkey49d67be2014-07-10 13:47:01 -070072 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -070073 * Fetches the name of the Component.
Ray Milkey49d67be2014-07-10 13:47:01 -070074 *
Ray Milkey71cd2c82014-07-16 15:02:33 -070075 * @return name of the Component
Ray Milkey49d67be2014-07-10 13:47:01 -070076 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070077 public String getName();
Ray Milkey49d67be2014-07-10 13:47:01 -070078
Ray Milkey71cd2c82014-07-16 15:02:33 -070079 /**
80 * Registers a Feature for this component.
81 *
82 * @param featureName name of the Feature to register
83 * @return Feature object that can be used when creating Metrics
84 */
85 public MetricsFeature registerFeature(final String featureName);
Ray Milkey49d67be2014-07-10 13:47:01 -070086 }
87
88 /**
89 * Features that can hold Metrics. This is used as the second part of
90 * a Metric's name.
91 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070092 public interface MetricsFeature {
Ray Milkey49d67be2014-07-10 13:47:01 -070093 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -070094 * Fetches the name of the Feature.
95 *
96 * @return name of the Feature
Ray Milkey49d67be2014-07-10 13:47:01 -070097 */
Ray Milkey71cd2c82014-07-16 15:02:33 -070098 public String getName();
99 }
Ray Milkey49d67be2014-07-10 13:47:01 -0700100
Ray Milkey71cd2c82014-07-16 15:02:33 -0700101 /**
102 * Implementation of a class to represent the Component portion of a
103 * Metric's name.
104 */
105 private static final class Component implements MetricsComponent {
Ray Milkey49d67be2014-07-10 13:47:01 -0700106 private final String name;
107
108 /**
Ray Milkey40eb9c82014-07-18 10:28:11 -0700109 * Registry to hold the Features defined in this Component.
110 */
111 private final ConcurrentMap<String, MetricsFeature> featuresRegistry =
112 new ConcurrentHashMap<>();
113
114 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -0700115 * Constructs a component from a name.
Ray Milkey49d67be2014-07-10 13:47:01 -0700116 *
Ray Milkey71cd2c82014-07-16 15:02:33 -0700117 * @param newName name of the component
Ray Milkey49d67be2014-07-10 13:47:01 -0700118 */
Ray Milkey40eb9c82014-07-18 10:28:11 -0700119 Component(final String newName) {
Ray Milkey71cd2c82014-07-16 15:02:33 -0700120 name = newName;
Ray Milkey49d67be2014-07-10 13:47:01 -0700121 }
122
123 @Override
Ray Milkey71cd2c82014-07-16 15:02:33 -0700124 public String getName() {
125 return name;
126 }
127
Ray Milkey71cd2c82014-07-16 15:02:33 -0700128 @Override
129 public MetricsFeature registerFeature(final String featureName) {
130 MetricsFeature feature = featuresRegistry.get(featureName);
131 if (feature == null) {
132 final MetricsFeature createdFeature = new Feature(featureName);
133 feature = featuresRegistry.putIfAbsent(featureName, createdFeature);
134 if (feature == null) {
135 feature = createdFeature;
136 }
137 }
138 return feature;
139 }
140 }
141
142 /**
143 * Implementation of a class to represent the Feature portion of a Metric's
144 * name.
145 */
146 private static final class Feature implements MetricsFeature {
147 private final String name;
148
149 /**
150 * Constructs a Feature from a name.
151 *
152 * @param newName name of the Feature
153 */
Ray Milkey40eb9c82014-07-18 10:28:11 -0700154 Feature(final String newName) {
Ray Milkey71cd2c82014-07-16 15:02:33 -0700155 name = newName;
156 }
157
158 @Override
159 public String getName() {
Ray Milkey49d67be2014-07-10 13:47:01 -0700160 return name;
161 }
162 }
163
Ray Milkey71cd2c82014-07-16 15:02:33 -0700164 /**
Ray Milkey71cd2c82014-07-16 15:02:33 -0700165 * Registers a component.
166 *
167 * @param name name of the Component to register
168 * @return MetricsComponent object that can be used to create Metrics.
169 */
170 public static MetricsComponent registerComponent(final String name) {
171 MetricsComponent component = componentsRegistry.get(name);
172 if (component == null) {
173 final MetricsComponent createdComponent = new Component(name);
174 component = componentsRegistry.putIfAbsent(name, createdComponent);
175 if (component == null) {
176 component = createdComponent;
177 }
178 }
179 return component;
180 }
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
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700205 * @return the created Counter Meteric
Ray Milkey49d67be2014-07-10 13:47:01 -0700206 */
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
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700220 * @return the created Histogram Metric
Ray Milkey49d67be2014-07-10 13:47:01 -0700221 */
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
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700235 * @return the created Timer Metric
Ray Milkey49d67be2014-07-10 13:47:01 -0700236 */
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
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700250 * @return the created Meter Metric
Ray Milkey49d67be2014-07-10 13:47:01 -0700251 */
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
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700265 * @param feature feature the Metric is defined in
Ray Milkey49d67be2014-07-10 13:47:01 -0700266 * @param metricName local name of the metric
267 * @param metric Metric to register
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700268 * @return the registered Metric
Ray Milkey49d67be2014-07-10 13:47:01 -0700269 */
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700270 public static <T extends Metric> T registerMetric(
271 final MetricsComponent component,
272 final MetricsFeature feature,
273 final String metricName,
274 final T metric) {
Ray Milkey49d67be2014-07-10 13:47:01 -0700275 final String name = generateName(component, feature, metricName);
276 METRICS_REGISTRY.register(name, metric);
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700277 return metric;
Ray Milkey49d67be2014-07-10 13:47:01 -0700278 }
279
280 /**
Ray Milkey128651a2014-07-14 11:24:28 -0700281 * Fetches the existing Timers.
Ray Milkey26921af2014-06-30 16:27:40 -0700282 *
Ray Milkey128651a2014-07-14 11:24:28 -0700283 * @param filter filter to use to select Timers
284 * @return a map of the Timers that match the filter, with the key as the
285 * name String to the Timer.
Ray Milkey26921af2014-06-30 16:27:40 -0700286 */
Ray Milkey128651a2014-07-14 11:24:28 -0700287 public static Map<String, Timer> getTimers(final MetricFilter filter) {
288 return METRICS_REGISTRY.getTimers(filter);
289 }
290
291 /**
292 * Fetches the existing Gauges.
293 *
294 * @param filter filter to use to select Gauges
295 * @return a map of the Gauges that match the filter, with the key as the
296 * name String to the Gauge.
297 */
298 @SuppressWarnings("rawtypes")
299 public static Map<String, Gauge> getGauges(final MetricFilter filter) {
300 return METRICS_REGISTRY.getGauges(filter);
301 }
302
303 /**
304 * Fetches the existing Counters.
305 *
306 * @param filter filter to use to select Counters
307 * @return a map of the Counters that match the filter, with the key as the
308 * name String to the Counter.
309 */
310 public static Map<String, Counter> getCounters(final MetricFilter filter) {
311 return METRICS_REGISTRY.getCounters(filter);
312 }
313
314 /**
315 * Fetches the existing Meters.
316 *
317 * @param filter filter to use to select Meters
318 * @return a map of the Meters that match the filter, with the key as the
319 * name String to the Meter.
320 */
321 public static Map<String, Meter> getMeters(final MetricFilter filter) {
322 return METRICS_REGISTRY.getMeters(filter);
323 }
324
325 /**
326 * Fetches the existing Histograms.
327 *
328 * @param filter filter to use to select Histograms
329 * @return a map of the Histograms that match the filter, with the key as the
330 * name String to the Histogram.
331 */
332 public static Map<String, Histogram> getHistograms(final MetricFilter filter) {
333 return METRICS_REGISTRY.getHistograms(filter);
334 }
335
336 /**
337 * Removes all Metrics that match a given filter.
338 *
339 * @param filter filter to use to select the Metrics to remove.
340 */
341 public static void removeMatching(final MetricFilter filter) {
342 METRICS_REGISTRY.removeMatching(filter);
Ray Milkey26921af2014-06-30 16:27:40 -0700343 }
344}
345