blob: a54093f015e7859869abf5f3c74760811f0afd55 [file] [log] [blame]
pankaj390abbc2014-10-01 17:01:05 -07001package org.onlab.metrics;
2
pankaj5de84112014-10-02 15:33:28 -07003import java.io.File;
4import java.util.Locale;
pankaj390abbc2014-10-01 17:01:05 -07005import java.util.Map;
pankaj5de84112014-10-02 15:33:28 -07006import java.util.concurrent.ConcurrentHashMap;
pankaj390abbc2014-10-01 17:01:05 -07007import java.util.concurrent.ConcurrentMap;
pankaj5de84112014-10-02 15:33:28 -07008import java.util.concurrent.TimeUnit;
pankaj390abbc2014-10-01 17:01:05 -07009
10import com.codahale.metrics.Counter;
pankaj5de84112014-10-02 15:33:28 -070011import com.codahale.metrics.CsvReporter;
pankaj390abbc2014-10-01 17:01:05 -070012import com.codahale.metrics.Gauge;
13import com.codahale.metrics.Histogram;
14import com.codahale.metrics.Meter;
15import com.codahale.metrics.Metric;
16import com.codahale.metrics.MetricFilter;
17import com.codahale.metrics.MetricRegistry;
18import com.codahale.metrics.Timer;
19
20/**
21 * This class holds the Metrics registry for ONOS.
22 * All metrics (Counter, Histogram, Timer, Meter, Gauge) use a hierarchical
23 * string-based naming scheme: COMPONENT.FEATURE.NAME.
24 * Example: "Topology.Counters.TopologyUpdates".
25 * The COMPONENT and FEATURE names have to be registered in advance before
26 * a metric can be created. Example:
27 * <pre>
28 * <code>
29 * private final MetricsManager.MetricsComponent COMPONENT =
30 * MetricsManager.registerComponent("Topology");
31 * private final MetricsManager.MetricsFeature FEATURE =
32 * COMPONENT.registerFeature("Counters");
33 * private final Counter counterTopologyUpdates =
34 * MetricsManager.createCounter(COMPONENT, FEATURE, "TopologyUpdates");
35 * </code>
36 * </pre>
37 * Gauges are slightly different because they are not created directly in
38 * this class, but are allocated by the caller and passed in for registration:
39 * <pre>
40 * <code>
41 * private final Gauge<Long> gauge =
42 * new {@literal Gauge<Long>}() {
43 * {@literal @}Override
44 * public Long getValue() {
45 * return gaugeValue;
46 * }
47 * };
48 * MetricsManager.registerMetric(COMPONENT, FEATURE, GAUGE_NAME, gauge);
49 * </code>
50 * </pre>
51 */
52public final class MetricsManager implements MetricsService {
53
54 /**
55 * Registry to hold the Components defined in the system.
56 */
pankaje138e272014-10-02 15:17:11 -070057 private ConcurrentMap<String, MetricsComponent> componentsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070058
59 /**
60 * Registry for the Metrics objects created in the system.
61 */
pankaj5de84112014-10-02 15:33:28 -070062 private final MetricRegistry metricsRegistry;
pankaj390abbc2014-10-01 17:01:05 -070063
pankaj5de84112014-10-02 15:33:28 -070064 /**
65 * Default Reporter for this metrics manager.
66 */
67 private final CsvReporter reporter;
pankaje138e272014-10-02 15:17:11 -070068
pankaj5de84112014-10-02 15:33:28 -070069 public MetricsManager() {
70 this.componentsRegistry = new ConcurrentHashMap<>();
71 this.metricsRegistry = new MetricRegistry();
72
73 this.reporter = CsvReporter.forRegistry(metricsRegistry)
74 .formatFor(Locale.US)
75 .convertRatesTo(TimeUnit.SECONDS)
76 .convertDurationsTo(TimeUnit.MICROSECONDS)
77 .build(new File("/tmp/"));
78
79 reporter.start(10, TimeUnit.SECONDS);
pankaje138e272014-10-02 15:17:11 -070080 }
pankaj390abbc2014-10-01 17:01:05 -070081
82 /**
83 * Registers a component.
84 *
85 * @param name name of the Component to register
86 * @return MetricsComponent object that can be used to create Metrics.
87 */
pankaj3855bcb2014-10-01 18:17:31 -070088 @Override
pankaj390abbc2014-10-01 17:01:05 -070089 public MetricsComponent registerComponent(final String name) {
90 MetricsComponent component = componentsRegistry.get(name);
91 if (component == null) {
92 final MetricsComponent createdComponent = new MetricsComponent(name);
93 component = componentsRegistry.putIfAbsent(name, createdComponent);
94 if (component == null) {
95 component = createdComponent;
96 }
97 }
98 return component;
99 }
100
101 /**
102 * Generates a name for a Metric from its component and feature.
103 *
104 * @param component component the metric is defined in
105 * @param feature feature the metric is defined in
106 * @param metricName local name of the metric
107 *
108 * @return full name of the metric
109 */
pankaj3855bcb2014-10-01 18:17:31 -0700110 private String generateName(final MetricsComponent component,
pankaj390abbc2014-10-01 17:01:05 -0700111 final MetricsFeature feature,
112 final String metricName) {
113 return MetricRegistry.name(component.getName(),
114 feature.getName(),
115 metricName);
116 }
117
118 /**
119 * Creates a Counter metric.
120 *
121 * @param component component the Counter is defined in
122 * @param feature feature the Counter is defined in
123 * @param metricName local name of the metric
124 * @return the created Counter Meteric
125 */
pankaj3855bcb2014-10-01 18:17:31 -0700126 @Override
pankaj390abbc2014-10-01 17:01:05 -0700127 public Counter createCounter(final MetricsComponent component,
128 final MetricsFeature feature,
129 final String metricName) {
130 final String name = generateName(component, feature, metricName);
131 return metricsRegistry.counter(name);
132 }
133
134 /**
135 * Creates a Histogram metric.
136 *
137 * @param component component the Histogram is defined in
138 * @param feature feature the Histogram is defined in
139 * @param metricName local name of the metric
140 * @return the created Histogram Metric
141 */
pankaj3855bcb2014-10-01 18:17:31 -0700142 @Override
pankaj390abbc2014-10-01 17:01:05 -0700143 public Histogram createHistogram(final MetricsComponent component,
144 final MetricsFeature feature,
145 final String metricName) {
146 final String name = generateName(component, feature, metricName);
147 return metricsRegistry.histogram(name);
148 }
149
150 /**
151 * Creates a Timer metric.
152 *
153 * @param component component the Timer is defined in
154 * @param feature feature the Timeer is defined in
155 * @param metricName local name of the metric
156 * @return the created Timer Metric
157 */
pankaj3855bcb2014-10-01 18:17:31 -0700158 @Override
pankaj390abbc2014-10-01 17:01:05 -0700159 public Timer createTimer(final MetricsComponent component,
160 final MetricsFeature feature,
161 final String metricName) {
162 final String name = generateName(component, feature, metricName);
163 return metricsRegistry.timer(name);
164 }
165
166 /**
167 * Creates a Meter metric.
168 *
169 * @param component component the Meter is defined in
170 * @param feature feature the Meter is defined in
171 * @param metricName local name of the metric
172 * @return the created Meter Metric
173 */
pankaj3855bcb2014-10-01 18:17:31 -0700174 @Override
pankaj390abbc2014-10-01 17:01:05 -0700175 public Meter createMeter(final MetricsComponent component,
176 final MetricsFeature feature,
177 final String metricName) {
178 final String name = generateName(component, feature, metricName);
179 return metricsRegistry.meter(name);
180 }
181
182 /**
183 * Registers an already created Metric. This is used for situation where a
184 * caller needs to allocate its own Metric, but still register it with the
185 * system.
186 *
187 * @param <T> Metric type
188 * @param component component the Metric is defined in
189 * @param feature feature the Metric is defined in
190 * @param metricName local name of the metric
191 * @param metric Metric to register
192 * @return the registered Metric
193 */
pankaj3855bcb2014-10-01 18:17:31 -0700194 @Override
pankaj390abbc2014-10-01 17:01:05 -0700195 public <T extends Metric> T registerMetric(
196 final MetricsComponent component,
197 final MetricsFeature feature,
198 final String metricName,
199 final T metric) {
200 final String name = generateName(component, feature, metricName);
201 metricsRegistry.register(name, metric);
202 return metric;
203 }
204
205 /**
206 * Fetches the existing Timers.
207 *
208 * @param filter filter to use to select Timers
209 * @return a map of the Timers that match the filter, with the key as the
210 * name String to the Timer.
211 */
pankaj3855bcb2014-10-01 18:17:31 -0700212 @Override
pankaj390abbc2014-10-01 17:01:05 -0700213 public Map<String, Timer> getTimers(final MetricFilter filter) {
214 return metricsRegistry.getTimers(filter);
215 }
216
217 /**
218 * Fetches the existing Gauges.
219 *
220 * @param filter filter to use to select Gauges
221 * @return a map of the Gauges that match the filter, with the key as the
222 * name String to the Gauge.
223 */
pankaj3855bcb2014-10-01 18:17:31 -0700224 @Override
pankaj390abbc2014-10-01 17:01:05 -0700225 public Map<String, Gauge> getGauges(final MetricFilter filter) {
226 return metricsRegistry.getGauges(filter);
227 }
228
229 /**
230 * Fetches the existing Counters.
231 *
232 * @param filter filter to use to select Counters
233 * @return a map of the Counters that match the filter, with the key as the
234 * name String to the Counter.
235 */
pankaj3855bcb2014-10-01 18:17:31 -0700236 @Override
pankaj390abbc2014-10-01 17:01:05 -0700237 public Map<String, Counter> getCounters(final MetricFilter filter) {
238 return metricsRegistry.getCounters(filter);
239 }
240
241 /**
242 * Fetches the existing Meters.
243 *
244 * @param filter filter to use to select Meters
245 * @return a map of the Meters that match the filter, with the key as the
246 * name String to the Meter.
247 */
pankaj3855bcb2014-10-01 18:17:31 -0700248 @Override
pankaj390abbc2014-10-01 17:01:05 -0700249 public Map<String, Meter> getMeters(final MetricFilter filter) {
250 return metricsRegistry.getMeters(filter);
251 }
252
253 /**
254 * Fetches the existing Histograms.
255 *
256 * @param filter filter to use to select Histograms
257 * @return a map of the Histograms that match the filter, with the key as the
258 * name String to the Histogram.
259 */
pankaj3855bcb2014-10-01 18:17:31 -0700260 @Override
pankaj390abbc2014-10-01 17:01:05 -0700261 public Map<String, Histogram> getHistograms(final MetricFilter filter) {
262 return metricsRegistry.getHistograms(filter);
263 }
264
265 /**
266 * Removes all Metrics that match a given filter.
267 *
268 * @param filter filter to use to select the Metrics to remove.
269 */
pankaj3855bcb2014-10-01 18:17:31 -0700270 @Override
pankaj390abbc2014-10-01 17:01:05 -0700271 public void removeMatching(final MetricFilter filter) {
272 metricsRegistry.removeMatching(filter);
273 }
274}
275