blob: 2b13efb1259b7916e0d9e439f331f304563c089a [file] [log] [blame]
pankaj390abbc2014-10-01 17:01:05 -07001package org.onlab.metrics;
2
3import java.util.Map;
4import java.util.concurrent.ConcurrentHashMap;
5import java.util.concurrent.ConcurrentMap;
6
7import com.codahale.metrics.Counter;
8import com.codahale.metrics.Gauge;
9import com.codahale.metrics.Histogram;
10import com.codahale.metrics.Meter;
11import com.codahale.metrics.Metric;
12import com.codahale.metrics.MetricFilter;
13import com.codahale.metrics.MetricRegistry;
14import com.codahale.metrics.Timer;
15
16/**
17 * This class holds the Metrics registry for ONOS.
18 * 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 final MetricsManager.MetricsComponent COMPONENT =
26 * MetricsManager.registerComponent("Topology");
27 * private final MetricsManager.MetricsFeature FEATURE =
28 * COMPONENT.registerFeature("Counters");
29 * private final Counter counterTopologyUpdates =
30 * MetricsManager.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 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
45 * </code>
46 * </pre>
47 */
48public final class MetricsManager implements MetricsService {
49
50 /**
51 * Registry to hold the Components defined in the system.
52 */
53 private ConcurrentMap<String, MetricsComponent> componentsRegistry =
54 new ConcurrentHashMap<>();
55
56 /**
57 * Registry for the Metrics objects created in the system.
58 */
59 private final MetricRegistry metricsRegistry = new MetricRegistry();
60
61 /**
62 * Hide constructor. The only way to get the registry is through the
63 * singleton getter.
64 */
65 private MetricsManager() {}
66
67 /**
68 * Registers a component.
69 *
70 * @param name name of the Component to register
71 * @return MetricsComponent object that can be used to create Metrics.
72 */
pankaj3855bcb2014-10-01 18:17:31 -070073 @Override
pankaj390abbc2014-10-01 17:01:05 -070074 public MetricsComponent registerComponent(final String name) {
75 MetricsComponent component = componentsRegistry.get(name);
76 if (component == null) {
77 final MetricsComponent createdComponent = new MetricsComponent(name);
78 component = componentsRegistry.putIfAbsent(name, createdComponent);
79 if (component == null) {
80 component = createdComponent;
81 }
82 }
83 return component;
84 }
85
86 /**
87 * Generates a name for a Metric from its component and feature.
88 *
89 * @param component component the metric is defined in
90 * @param feature feature the metric is defined in
91 * @param metricName local name of the metric
92 *
93 * @return full name of the metric
94 */
pankaj3855bcb2014-10-01 18:17:31 -070095 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -070096 final MetricsFeature feature,
97 final String metricName) {
98 return MetricRegistry.name(component.getName(),
99 feature.getName(),
100 metricName);
101 }
102
103 /**
104 * Creates a Counter metric.
105 *
106 * @param component component the Counter is defined in
107 * @param feature feature the Counter is defined in
108 * @param metricName local name of the metric
109 * @return the created Counter Meteric
110 */
pankaj3855bcb2014-10-01 18:17:31 -0700111 @Override
pankaj390abbc2014-10-01 17:01:05 -0700112 public Counter createCounter(final MetricsComponent component,
113 final MetricsFeature feature,
114 final String metricName) {
115 final String name = generateName(component, feature, metricName);
116 return metricsRegistry.counter(name);
117 }
118
119 /**
120 * Creates a Histogram metric.
121 *
122 * @param component component the Histogram is defined in
123 * @param feature feature the Histogram is defined in
124 * @param metricName local name of the metric
125 * @return the created Histogram Metric
126 */
pankaj3855bcb2014-10-01 18:17:31 -0700127 @Override
pankaj390abbc2014-10-01 17:01:05 -0700128 public Histogram createHistogram(final MetricsComponent component,
129 final MetricsFeature feature,
130 final String metricName) {
131 final String name = generateName(component, feature, metricName);
132 return metricsRegistry.histogram(name);
133 }
134
135 /**
136 * Creates a Timer metric.
137 *
138 * @param component component the Timer is defined in
139 * @param feature feature the Timeer is defined in
140 * @param metricName local name of the metric
141 * @return the created Timer Metric
142 */
pankaj3855bcb2014-10-01 18:17:31 -0700143 @Override
pankaj390abbc2014-10-01 17:01:05 -0700144 public Timer createTimer(final MetricsComponent component,
145 final MetricsFeature feature,
146 final String metricName) {
147 final String name = generateName(component, feature, metricName);
148 return metricsRegistry.timer(name);
149 }
150
151 /**
152 * Creates a Meter metric.
153 *
154 * @param component component the Meter is defined in
155 * @param feature feature the Meter is defined in
156 * @param metricName local name of the metric
157 * @return the created Meter Metric
158 */
pankaj3855bcb2014-10-01 18:17:31 -0700159 @Override
pankaj390abbc2014-10-01 17:01:05 -0700160 public Meter createMeter(final MetricsComponent component,
161 final MetricsFeature feature,
162 final String metricName) {
163 final String name = generateName(component, feature, metricName);
164 return metricsRegistry.meter(name);
165 }
166
167 /**
168 * Registers an already created Metric. This is used for situation where a
169 * caller needs to allocate its own Metric, but still register it with the
170 * system.
171 *
172 * @param <T> Metric type
173 * @param component component the Metric is defined in
174 * @param feature feature the Metric is defined in
175 * @param metricName local name of the metric
176 * @param metric Metric to register
177 * @return the registered Metric
178 */
pankaj3855bcb2014-10-01 18:17:31 -0700179 @Override
pankaj390abbc2014-10-01 17:01:05 -0700180 public <T extends Metric> T registerMetric(
181 final MetricsComponent component,
182 final MetricsFeature feature,
183 final String metricName,
184 final T metric) {
185 final String name = generateName(component, feature, metricName);
186 metricsRegistry.register(name, metric);
187 return metric;
188 }
189
190 /**
191 * Fetches the existing Timers.
192 *
193 * @param filter filter to use to select Timers
194 * @return a map of the Timers that match the filter, with the key as the
195 * name String to the Timer.
196 */
pankaj3855bcb2014-10-01 18:17:31 -0700197 @Override
pankaj390abbc2014-10-01 17:01:05 -0700198 public Map<String, Timer> getTimers(final MetricFilter filter) {
199 return metricsRegistry.getTimers(filter);
200 }
201
202 /**
203 * Fetches the existing Gauges.
204 *
205 * @param filter filter to use to select Gauges
206 * @return a map of the Gauges that match the filter, with the key as the
207 * name String to the Gauge.
208 */
pankaj3855bcb2014-10-01 18:17:31 -0700209 @Override
pankaj390abbc2014-10-01 17:01:05 -0700210 public Map<String, Gauge> getGauges(final MetricFilter filter) {
211 return metricsRegistry.getGauges(filter);
212 }
213
214 /**
215 * Fetches the existing Counters.
216 *
217 * @param filter filter to use to select Counters
218 * @return a map of the Counters that match the filter, with the key as the
219 * name String to the Counter.
220 */
pankaj3855bcb2014-10-01 18:17:31 -0700221 @Override
pankaj390abbc2014-10-01 17:01:05 -0700222 public Map<String, Counter> getCounters(final MetricFilter filter) {
223 return metricsRegistry.getCounters(filter);
224 }
225
226 /**
227 * Fetches the existing Meters.
228 *
229 * @param filter filter to use to select Meters
230 * @return a map of the Meters that match the filter, with the key as the
231 * name String to the Meter.
232 */
pankaj3855bcb2014-10-01 18:17:31 -0700233 @Override
pankaj390abbc2014-10-01 17:01:05 -0700234 public Map<String, Meter> getMeters(final MetricFilter filter) {
235 return metricsRegistry.getMeters(filter);
236 }
237
238 /**
239 * Fetches the existing Histograms.
240 *
241 * @param filter filter to use to select Histograms
242 * @return a map of the Histograms that match the filter, with the key as the
243 * name String to the Histogram.
244 */
pankaj3855bcb2014-10-01 18:17:31 -0700245 @Override
pankaj390abbc2014-10-01 17:01:05 -0700246 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
247 return metricsRegistry.getHistograms(filter);
248 }
249
250 /**
251 * Removes all Metrics that match a given filter.
252 *
253 * @param filter filter to use to select the Metrics to remove.
254 */
pankaj3855bcb2014-10-01 18:17:31 -0700255 @Override
pankaj390abbc2014-10-01 17:01:05 -0700256 public void removeMatching(final MetricFilter filter) {
257 metricsRegistry.removeMatching(filter);
258 }
259}
260