blob: 7749bae93756b5fa4d3b685e5a399e13a461345b [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 *
Ray Milkey4d1992b2014-07-30 11:25:25 -0700264 * @param <T> Metric type
Ray Milkey49d67be2014-07-10 13:47:01 -0700265 * @param component component the Metric is defined in
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700266 * @param feature feature the Metric is defined in
Ray Milkey49d67be2014-07-10 13:47:01 -0700267 * @param metricName local name of the metric
268 * @param metric Metric to register
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700269 * @return the registered Metric
Ray Milkey49d67be2014-07-10 13:47:01 -0700270 */
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700271 public static <T extends Metric> T registerMetric(
272 final MetricsComponent component,
273 final MetricsFeature feature,
274 final String metricName,
275 final T metric) {
Ray Milkey49d67be2014-07-10 13:47:01 -0700276 final String name = generateName(component, feature, metricName);
277 METRICS_REGISTRY.register(name, metric);
Pavlin Radoslavov95caf262014-07-18 12:53:42 -0700278 return metric;
Ray Milkey49d67be2014-07-10 13:47:01 -0700279 }
280
281 /**
Ray Milkey128651a2014-07-14 11:24:28 -0700282 * Fetches the existing Timers.
Ray Milkey26921af2014-06-30 16:27:40 -0700283 *
Ray Milkey128651a2014-07-14 11:24:28 -0700284 * @param filter filter to use to select Timers
285 * @return a map of the Timers that match the filter, with the key as the
286 * name String to the Timer.
Ray Milkey26921af2014-06-30 16:27:40 -0700287 */
Ray Milkey128651a2014-07-14 11:24:28 -0700288 public static Map<String, Timer> getTimers(final MetricFilter filter) {
289 return METRICS_REGISTRY.getTimers(filter);
290 }
291
292 /**
293 * Fetches the existing Gauges.
294 *
295 * @param filter filter to use to select Gauges
296 * @return a map of the Gauges that match the filter, with the key as the
297 * name String to the Gauge.
298 */
299 @SuppressWarnings("rawtypes")
300 public static Map<String, Gauge> getGauges(final MetricFilter filter) {
301 return METRICS_REGISTRY.getGauges(filter);
302 }
303
304 /**
305 * Fetches the existing Counters.
306 *
307 * @param filter filter to use to select Counters
308 * @return a map of the Counters that match the filter, with the key as the
309 * name String to the Counter.
310 */
311 public static Map<String, Counter> getCounters(final MetricFilter filter) {
312 return METRICS_REGISTRY.getCounters(filter);
313 }
314
315 /**
316 * Fetches the existing Meters.
317 *
318 * @param filter filter to use to select Meters
319 * @return a map of the Meters that match the filter, with the key as the
320 * name String to the Meter.
321 */
322 public static Map<String, Meter> getMeters(final MetricFilter filter) {
323 return METRICS_REGISTRY.getMeters(filter);
324 }
325
326 /**
327 * Fetches the existing Histograms.
328 *
329 * @param filter filter to use to select Histograms
330 * @return a map of the Histograms that match the filter, with the key as the
331 * name String to the Histogram.
332 */
333 public static Map<String, Histogram> getHistograms(final MetricFilter filter) {
334 return METRICS_REGISTRY.getHistograms(filter);
335 }
336
337 /**
338 * Removes all Metrics that match a given filter.
339 *
340 * @param filter filter to use to select the Metrics to remove.
341 */
342 public static void removeMatching(final MetricFilter filter) {
343 METRICS_REGISTRY.removeMatching(filter);
Ray Milkey26921af2014-06-30 16:27:40 -0700344 }
345}
346