blob: 08f8b116e791cee635bf2717d920b76152ea9537 [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 */
73 public MetricsComponent registerComponent(final String name) {
74 MetricsComponent component = componentsRegistry.get(name);
75 if (component == null) {
76 final MetricsComponent createdComponent = new MetricsComponent(name);
77 component = componentsRegistry.putIfAbsent(name, createdComponent);
78 if (component == null) {
79 component = createdComponent;
80 }
81 }
82 return component;
83 }
84
85 /**
86 * Generates a name for a Metric from its component and feature.
87 *
88 * @param component component the metric is defined in
89 * @param feature feature the metric is defined in
90 * @param metricName local name of the metric
91 *
92 * @return full name of the metric
93 */
94 public String generateName(final MetricsComponent component,
95 final MetricsFeature feature,
96 final String metricName) {
97 return MetricRegistry.name(component.getName(),
98 feature.getName(),
99 metricName);
100 }
101
102 /**
103 * Creates a Counter metric.
104 *
105 * @param component component the Counter is defined in
106 * @param feature feature the Counter is defined in
107 * @param metricName local name of the metric
108 * @return the created Counter Meteric
109 */
110 public Counter createCounter(final MetricsComponent component,
111 final MetricsFeature feature,
112 final String metricName) {
113 final String name = generateName(component, feature, metricName);
114 return metricsRegistry.counter(name);
115 }
116
117 /**
118 * Creates a Histogram metric.
119 *
120 * @param component component the Histogram is defined in
121 * @param feature feature the Histogram is defined in
122 * @param metricName local name of the metric
123 * @return the created Histogram Metric
124 */
125 public Histogram createHistogram(final MetricsComponent component,
126 final MetricsFeature feature,
127 final String metricName) {
128 final String name = generateName(component, feature, metricName);
129 return metricsRegistry.histogram(name);
130 }
131
132 /**
133 * Creates a Timer metric.
134 *
135 * @param component component the Timer is defined in
136 * @param feature feature the Timeer is defined in
137 * @param metricName local name of the metric
138 * @return the created Timer Metric
139 */
140 public Timer createTimer(final MetricsComponent component,
141 final MetricsFeature feature,
142 final String metricName) {
143 final String name = generateName(component, feature, metricName);
144 return metricsRegistry.timer(name);
145 }
146
147 /**
148 * Creates a Meter metric.
149 *
150 * @param component component the Meter is defined in
151 * @param feature feature the Meter is defined in
152 * @param metricName local name of the metric
153 * @return the created Meter Metric
154 */
155 public Meter createMeter(final MetricsComponent component,
156 final MetricsFeature feature,
157 final String metricName) {
158 final String name = generateName(component, feature, metricName);
159 return metricsRegistry.meter(name);
160 }
161
162 /**
163 * Registers an already created Metric. This is used for situation where a
164 * caller needs to allocate its own Metric, but still register it with the
165 * system.
166 *
167 * @param <T> Metric type
168 * @param component component the Metric is defined in
169 * @param feature feature the Metric is defined in
170 * @param metricName local name of the metric
171 * @param metric Metric to register
172 * @return the registered Metric
173 */
174 public <T extends Metric> T registerMetric(
175 final MetricsComponent component,
176 final MetricsFeature feature,
177 final String metricName,
178 final T metric) {
179 final String name = generateName(component, feature, metricName);
180 metricsRegistry.register(name, metric);
181 return metric;
182 }
183
184 /**
185 * Fetches the existing Timers.
186 *
187 * @param filter filter to use to select Timers
188 * @return a map of the Timers that match the filter, with the key as the
189 * name String to the Timer.
190 */
191 public Map<String, Timer> getTimers(final MetricFilter filter) {
192 return metricsRegistry.getTimers(filter);
193 }
194
195 /**
196 * Fetches the existing Gauges.
197 *
198 * @param filter filter to use to select Gauges
199 * @return a map of the Gauges that match the filter, with the key as the
200 * name String to the Gauge.
201 */
202 @SuppressWarnings("rawtypes")
203 public Map<String, Gauge> getGauges(final MetricFilter filter) {
204 return metricsRegistry.getGauges(filter);
205 }
206
207 /**
208 * Fetches the existing Counters.
209 *
210 * @param filter filter to use to select Counters
211 * @return a map of the Counters that match the filter, with the key as the
212 * name String to the Counter.
213 */
214 public Map<String, Counter> getCounters(final MetricFilter filter) {
215 return metricsRegistry.getCounters(filter);
216 }
217
218 /**
219 * Fetches the existing Meters.
220 *
221 * @param filter filter to use to select Meters
222 * @return a map of the Meters that match the filter, with the key as the
223 * name String to the Meter.
224 */
225 public Map<String, Meter> getMeters(final MetricFilter filter) {
226 return metricsRegistry.getMeters(filter);
227 }
228
229 /**
230 * Fetches the existing Histograms.
231 *
232 * @param filter filter to use to select Histograms
233 * @return a map of the Histograms that match the filter, with the key as the
234 * name String to the Histogram.
235 */
236 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
237 return metricsRegistry.getHistograms(filter);
238 }
239
240 /**
241 * Removes all Metrics that match a given filter.
242 *
243 * @param filter filter to use to select the Metrics to remove.
244 */
245 public void removeMatching(final MetricFilter filter) {
246 metricsRegistry.removeMatching(filter);
247 }
248}
249