Jian Li
Committed by Gerrit Code Review

Notify all metric reporters when metric registry has been changed

With existing implementation, it is difficult to notify the
metric reports on metric registry changes. With this commit,
we can spontaneously notify all reporters about the metric
registry changes, so that newly added metrics can be automatically
reported to third party monitoring system.

Change-Id: I1273194553900f6bb03e2ef6bb1b54838af1da00
Showing 16 changed files with 689 additions and 591 deletions
...@@ -28,6 +28,7 @@ import org.junit.Before; ...@@ -28,6 +28,7 @@ import org.junit.Before;
28 import org.junit.Test; 28 import org.junit.Test;
29 import org.onlab.metrics.MetricsComponent; 29 import org.onlab.metrics.MetricsComponent;
30 import org.onlab.metrics.MetricsFeature; 30 import org.onlab.metrics.MetricsFeature;
31 +import org.onlab.metrics.MetricsReporter;
31 import org.onlab.metrics.MetricsService; 32 import org.onlab.metrics.MetricsService;
32 import org.onlab.osgi.ServiceDirectory; 33 import org.onlab.osgi.ServiceDirectory;
33 import org.onlab.osgi.TestServiceDirectory; 34 import org.onlab.osgi.TestServiceDirectory;
...@@ -220,6 +221,18 @@ public class ControlMetricsCollectorResourceTest extends ResourceTest { ...@@ -220,6 +221,18 @@ public class ControlMetricsCollectorResourceTest extends ResourceTest {
220 } 221 }
221 222
222 @Override 223 @Override
224 + public void registerReporter(MetricsReporter reporter) {
225 + }
226 +
227 + @Override
228 + public void unregisterReporter(MetricsReporter reporter) {
229 + }
230 +
231 + @Override
232 + public void notifyReporters() {
233 + }
234 +
235 + @Override
223 public boolean removeMetric(MetricsComponent component, 236 public boolean removeMetric(MetricsComponent component,
224 MetricsFeature feature, String metricName) { 237 MetricsFeature feature, String metricName) {
225 return false; 238 return false;
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.gangliametrics;
17 +
18 +import com.codahale.metrics.MetricRegistry;
19 +import com.codahale.metrics.ganglia.GangliaReporter;
20 +import info.ganglia.gmetric4j.gmetric.GMetric;
21 +import org.apache.commons.lang.StringUtils;
22 +import org.apache.felix.scr.annotations.Activate;
23 +import org.apache.felix.scr.annotations.Component;
24 +import org.apache.felix.scr.annotations.Deactivate;
25 +import org.apache.felix.scr.annotations.Modified;
26 +import org.apache.felix.scr.annotations.Property;
27 +import org.apache.felix.scr.annotations.Reference;
28 +import org.apache.felix.scr.annotations.ReferenceCardinality;
29 +import org.onlab.metrics.MetricsService;
30 +import org.onlab.util.Tools;
31 +import org.onosproject.cfg.ComponentConfigService;
32 +import org.onosproject.core.CoreService;
33 +import org.osgi.service.component.ComponentContext;
34 +import org.slf4j.Logger;
35 +
36 +import java.io.IOException;
37 +import java.util.Dictionary;
38 +import java.util.concurrent.TimeUnit;
39 +
40 +import static org.slf4j.LoggerFactory.getLogger;
41 +
42 +/**
43 + * A metric report that reports all metrics value to ganglia monitoring server.
44 + */
45 +@Component(immediate = true)
46 +public class DefaultGangliaMetricsReporter implements GangliaMetricsReporter {
47 + private final Logger log = getLogger(getClass());
48 +
49 + // we will use uni-cast mode to transfer the metrics value by default
50 + private static final GMetric.UDPAddressingMode GANGLIA_MODE =
51 + GMetric.UDPAddressingMode.UNICAST;
52 + private static final int REPORT_PERIOD = 1;
53 + private static final TimeUnit REPORT_TIME_UNIT = TimeUnit.MINUTES;
54 +
55 + private static final String DEFAULT_ADDRESS = "localhost";
56 + private static final int DEFAULT_PORT = 8649;
57 + private static final int DEFAULT_TTL = 1;
58 + private static final String DEFAULT_METRIC_NAMES = "default";
59 +
60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + protected CoreService coreService;
62 +
63 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 + protected MetricsService metricsService;
65 +
66 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 + protected ComponentConfigService cfgService;
68 +
69 + @Property(name = "monitorAll", boolValue = true,
70 + label = "Enable to monitor all of metrics stored in metric registry default is true")
71 + protected boolean monitorAll = true;
72 +
73 + @Property(name = "metricNames", value = DEFAULT_METRIC_NAMES,
74 + label = "Names of metric to be monitored; default metric names are 'default'")
75 + protected String metricNames = DEFAULT_METRIC_NAMES;
76 +
77 + @Property(name = "address", value = DEFAULT_ADDRESS,
78 + label = "IP address of ganglia monitoring server; default is localhost")
79 + protected String address = DEFAULT_ADDRESS;
80 +
81 + @Property(name = "port", intValue = DEFAULT_PORT,
82 + label = "Port number of ganglia monitoring server; default is 8649")
83 + protected int port = DEFAULT_PORT;
84 +
85 + @Property(name = "ttl", intValue = DEFAULT_TTL,
86 + label = "TTL value of ganglia monitoring server; default is 1")
87 + protected int ttl = DEFAULT_TTL;
88 +
89 + private GMetric ganglia;
90 + private GangliaReporter gangliaReporter;
91 +
92 + @Activate
93 + public void activate() {
94 + cfgService.registerProperties(getClass());
95 + coreService.registerApplication("org.onosproject.metrics.reporter");
96 + metricsService.registerReporter(this);
97 +
98 + startReport();
99 + log.info("Started");
100 + }
101 +
102 + @Deactivate
103 + public void deactivate() {
104 + cfgService.unregisterProperties(getClass(), false);
105 +
106 + stopReport();
107 + metricsService.unregisterReporter(this);
108 +
109 + log.info("Stopped");
110 + }
111 +
112 + @Modified
113 + public void modified(ComponentContext context) {
114 + readComponentConfiguration(context);
115 + stopReport();
116 + startReport();
117 + }
118 +
119 + @Override
120 + public void startReport() {
121 + configGMetric();
122 + gangliaReporter = buildReporter(ganglia);
123 + gangliaReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
124 + log.info("Start to report metrics to ganglia server.");
125 + }
126 +
127 + @Override
128 + public void stopReport() {
129 + gangliaReporter.stop();
130 + ganglia = null;
131 + gangliaReporter = null;
132 + log.info("Stop reporting metrics to ganglia server.");
133 + }
134 +
135 + @Override
136 + public void restartReport() {
137 + stopReport();
138 + startReport();
139 + }
140 +
141 + @Override
142 + public void notifyMetricsChange() {
143 + gangliaReporter.stop();
144 + gangliaReporter = buildReporter(ganglia);
145 + gangliaReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
146 + log.info("Metric registry has been changed, apply changes.");
147 + }
148 +
149 + /**
150 + * Filters the metrics to only include a set of the given metrics.
151 + *
152 + * @param metricRegistry original metric registry
153 + * @return filtered metric registry
154 + */
155 + protected MetricRegistry filter(MetricRegistry metricRegistry) {
156 + if (!monitorAll) {
157 + final MetricRegistry filtered = new MetricRegistry();
158 + metricRegistry.getNames().stream().filter(name ->
159 + containsName(name, metricNames)).forEach(name ->
160 + filtered.register(name, metricRegistry.getMetrics().get(name)));
161 + return filtered;
162 + } else {
163 + return metricRegistry;
164 + }
165 + }
166 +
167 + /**
168 + * Looks up whether the metric name contains the given prefix keywords.
169 + * Note that the keywords are separated with comma as delimiter
170 + *
171 + * @param full the original metric name that to be compared with
172 + * @param prefixes the prefix keywords that are matched against with the metric name
173 + * @return boolean value that denotes whether the metric name starts with the given prefix
174 + */
175 + protected boolean containsName(String full, String prefixes) {
176 + String[] prefixArray = StringUtils.split(prefixes, ",");
177 + for (String prefix : prefixArray) {
178 + if (StringUtils.startsWith(full, StringUtils.trimToEmpty(prefix))) {
179 + return true;
180 + }
181 + }
182 + return false;
183 + }
184 +
185 + /**
186 + * Extracts properties from the component configuration context.
187 + *
188 + * @param context the component context
189 + */
190 + private void readComponentConfiguration(ComponentContext context) {
191 + Dictionary<?, ?> properties = context.getProperties();
192 +
193 + String addressStr = Tools.get(properties, "address");
194 + address = addressStr != null ? addressStr : DEFAULT_ADDRESS;
195 + log.info("Configured. Ganglia server address is {}", address);
196 +
197 + String metricNameStr = Tools.get(properties, "metricNames");
198 + metricNames = metricNameStr != null ? metricNameStr : DEFAULT_METRIC_NAMES;
199 + log.info("Configured. Metric name is {}", metricNames);
200 +
201 + Integer portConfigured = Tools.getIntegerProperty(properties, "port");
202 + if (portConfigured == null) {
203 + port = DEFAULT_PORT;
204 + log.info("Ganglia port is not configured, default value is {}", port);
205 + } else {
206 + port = portConfigured;
207 + log.info("Configured. Ganglia port is configured to {}", port);
208 + }
209 +
210 + Integer ttlConfigured = Tools.getIntegerProperty(properties, "ttl");
211 + if (ttlConfigured == null) {
212 + ttl = DEFAULT_TTL;
213 + log.info("Ganglia TTL is not configured, default value is {}", ttl);
214 + } else {
215 + ttl = ttlConfigured;
216 + log.info("Configured. Ganglia TTL is configured to {}", ttl);
217 + }
218 +
219 + Boolean monitorAllEnabled = Tools.isPropertyEnabled(properties, "monitorAll");
220 + if (monitorAllEnabled == null) {
221 + log.info("Monitor all metrics is not configured, " +
222 + "using current value of {}", monitorAll);
223 + } else {
224 + monitorAll = monitorAllEnabled;
225 + log.info("Configured. Monitor all metrics is {}",
226 + monitorAll ? "enabled" : "disabled");
227 + }
228 + }
229 +
230 + /**
231 + * Configures parameters for GMetric.
232 + */
233 + private void configGMetric() {
234 + try {
235 + ganglia = new GMetric(address, port, GANGLIA_MODE, ttl);
236 + } catch (IOException e) {
237 + log.error("Fail to connect to given ganglia server!");
238 + }
239 + }
240 +
241 + /**
242 + * Builds reporter with the given ganglia metric.
243 + *
244 + * @param gMetric ganglia metric
245 + * @return reporter
246 + */
247 + private GangliaReporter buildReporter(GMetric gMetric) {
248 + MetricRegistry mr = metricsService.getMetricRegistry();
249 +
250 + return GangliaReporter.forRegistry(filter(mr))
251 + .convertRatesTo(TimeUnit.SECONDS)
252 + .convertDurationsTo(TimeUnit.MILLISECONDS)
253 + .build(gMetric);
254 + }
255 +}
...@@ -15,208 +15,10 @@ ...@@ -15,208 +15,10 @@
15 */ 15 */
16 package org.onosproject.gangliametrics; 16 package org.onosproject.gangliametrics;
17 17
18 -import com.codahale.metrics.MetricRegistry; 18 +import org.onlab.metrics.MetricsReporter;
19 -import com.codahale.metrics.ganglia.GangliaReporter;
20 -import info.ganglia.gmetric4j.gmetric.GMetric;
21 -import org.apache.commons.lang.StringUtils;
22 -import org.apache.felix.scr.annotations.Activate;
23 -import org.apache.felix.scr.annotations.Component;
24 -import org.apache.felix.scr.annotations.Deactivate;
25 -import org.apache.felix.scr.annotations.Modified;
26 -import org.apache.felix.scr.annotations.Property;
27 -import org.apache.felix.scr.annotations.Reference;
28 -import org.apache.felix.scr.annotations.ReferenceCardinality;
29 -import org.onlab.metrics.MetricsService;
30 -import org.onlab.util.Tools;
31 -import org.onosproject.cfg.ComponentConfigService;
32 -import org.onosproject.core.ApplicationId;
33 -import org.onosproject.core.CoreService;
34 -import org.osgi.service.component.ComponentContext;
35 -import org.slf4j.Logger;
36 -
37 -import java.io.IOException;
38 -import java.util.Dictionary;
39 -import java.util.concurrent.TimeUnit;
40 -
41 -import static org.slf4j.LoggerFactory.getLogger;
42 19
43 /** 20 /**
44 - * A metric report that reports all metrics value to ganglia monitoring server. 21 + * Interface of ganglia reporter that reports all metrics value to ganglia server.
45 */ 22 */
46 -@Component(immediate = true) 23 +public interface GangliaMetricsReporter extends MetricsReporter {
47 -public class GangliaMetricsReporter implements MetricsReporter {
48 - private final Logger log = getLogger(getClass());
49 -
50 - // we will use uni-cast mode to transfer the metrics value by default
51 - private static final GMetric.UDPAddressingMode GANGLIA_MODE =
52 - GMetric.UDPAddressingMode.UNICAST;
53 - private static final int REPORT_PERIOD = 1;
54 - private static final TimeUnit REPORT_TIME_UNIT = TimeUnit.MINUTES;
55 -
56 - private static final String DEFAULT_ADDRESS = "localhost";
57 - private static final int DEFAULT_PORT = 8649;
58 - private static final int DEFAULT_TTL = 1;
59 - private static final String DEFAULT_METRIC_NAMES = "default";
60 -
61 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 - protected CoreService coreService;
63 -
64 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 - protected MetricsService metricsService;
66 -
67 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 - protected ComponentConfigService cfgService;
69 -
70 - @Property(name = "monitorAll", boolValue = true,
71 - label = "Enable to monitor all of metrics stored in metric registry default is true")
72 - protected boolean monitorAll = true;
73 -
74 - @Property(name = "metricNames", value = DEFAULT_METRIC_NAMES,
75 - label = "Names of metric to be monitored; default metric names are 'default'")
76 - protected String metricNames = DEFAULT_METRIC_NAMES;
77 -
78 - @Property(name = "address", value = DEFAULT_ADDRESS,
79 - label = "IP address of ganglia monitoring server; default is localhost")
80 - protected String address = DEFAULT_ADDRESS;
81 -
82 - @Property(name = "port", intValue = DEFAULT_PORT,
83 - label = "Port number of ganglia monitoring server; default is 8649")
84 - protected int port = DEFAULT_PORT;
85 -
86 - @Property(name = "ttl", intValue = DEFAULT_TTL,
87 - label = "TTL value of ganglia monitoring server; default is 1")
88 - protected int ttl = DEFAULT_TTL;
89 -
90 - private ApplicationId appId;
91 - private GMetric ganglia;
92 - private GangliaReporter gangliaReporter;
93 -
94 - @Activate
95 - public void activate() {
96 - cfgService.registerProperties(getClass());
97 - appId = coreService.registerApplication("org.onosproject.metrics.reporter");
98 -
99 - startReport();
100 - log.info("Started");
101 - }
102 -
103 - @Deactivate
104 - public void deactivate() {
105 - cfgService.unregisterProperties(getClass(), false);
106 -
107 - stopReport();
108 - log.info("Stopped");
109 - }
110 -
111 - @Modified
112 - public void modified(ComponentContext context) {
113 - readComponentConfiguration(context);
114 - stopReport();
115 - startReport();
116 - }
117 -
118 - @Override
119 - public void startReport() {
120 - try {
121 - ganglia = new GMetric(address, port, GANGLIA_MODE, ttl);
122 -
123 - MetricRegistry mr = metricsService.getMetricRegistry();
124 -
125 - gangliaReporter = GangliaReporter.forRegistry(filter(mr))
126 - .convertRatesTo(TimeUnit.SECONDS)
127 - .convertDurationsTo(TimeUnit.MILLISECONDS)
128 - .build(ganglia);
129 - gangliaReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
130 - } catch (IOException e) {
131 - log.error("Fail to connect to given ganglia server!");
132 - }
133 - }
134 -
135 - @Override
136 - public void stopReport() {
137 - gangliaReporter.stop();
138 - ganglia = null;
139 - gangliaReporter = null;
140 - }
141 -
142 - /**
143 - * Filters the metrics to only include a set of the given metrics.
144 - *
145 - * @param metricRegistry original metric registry
146 - * @return filtered metric registry
147 - */
148 - protected MetricRegistry filter(MetricRegistry metricRegistry) {
149 - if (!monitorAll) {
150 - final MetricRegistry filtered = new MetricRegistry();
151 - metricRegistry.getNames().stream().filter(name ->
152 - containsName(name, metricNames)).forEach(name ->
153 - filtered.register(name, metricRegistry.getMetrics().get(name)));
154 - return filtered;
155 - } else {
156 - return metricRegistry;
157 - }
158 - }
159 -
160 - /**
161 - * Looks up whether the metric name contains the given prefix keywords.
162 - * Note that the keywords are separated with comma as delimiter
163 - *
164 - * @param full the original metric name that to be compared with
165 - * @param prefixes the prefix keywords that are matched against with the metric name
166 - * @return boolean value that denotes whether the metric name starts with the given prefix
167 - */
168 - protected boolean containsName(String full, String prefixes) {
169 - String[] prefixArray = StringUtils.split(prefixes, ",");
170 - for (String prefix : prefixArray) {
171 - if (StringUtils.startsWith(full, StringUtils.trimToEmpty(prefix))) {
172 - return true;
173 - }
174 - }
175 - return false;
176 - }
177 -
178 - /**
179 - * Extracts properties from the component configuration context.
180 - *
181 - * @param context the component context
182 - */
183 - private void readComponentConfiguration(ComponentContext context) {
184 - Dictionary<?, ?> properties = context.getProperties();
185 -
186 - String addressStr = Tools.get(properties, "address");
187 - address = addressStr != null ? addressStr : DEFAULT_ADDRESS;
188 - log.info("Configured. Ganglia server address is {}", address);
189 -
190 - String metricNameStr = Tools.get(properties, "metricNames");
191 - metricNames = metricNameStr != null ? metricNameStr : DEFAULT_METRIC_NAMES;
192 - log.info("Configured. Metric name is {}", metricNames);
193 -
194 - Integer portConfigured = Tools.getIntegerProperty(properties, "port");
195 - if (portConfigured == null) {
196 - port = DEFAULT_PORT;
197 - log.info("Ganglia port is not configured, default value is {}", port);
198 - } else {
199 - port = portConfigured;
200 - log.info("Configured. Ganglia port is configured to {}", port);
201 - }
202 -
203 - Integer ttlConfigured = Tools.getIntegerProperty(properties, "ttl");
204 - if (ttlConfigured == null) {
205 - ttl = DEFAULT_TTL;
206 - log.info("Ganglia TTL is not configured, default value is {}", ttl);
207 - } else {
208 - ttl = ttlConfigured;
209 - log.info("Configured. Ganglia TTL is configured to {}", ttl);
210 - }
211 -
212 - Boolean monitorAllEnabled = Tools.isPropertyEnabled(properties, "monitorAll");
213 - if (monitorAllEnabled == null) {
214 - log.info("Monitor all metrics is not configured, " +
215 - "using current value of {}", monitorAll);
216 - } else {
217 - monitorAll = monitorAllEnabled;
218 - log.info("Configured. Monitor all metrics is {}",
219 - monitorAll ? "enabled" : "disabled");
220 - }
221 - }
222 } 24 }
......
...@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue; ...@@ -28,7 +28,7 @@ import static org.junit.Assert.assertTrue;
28 */ 28 */
29 public class GangliaMetricsReporterTest { 29 public class GangliaMetricsReporterTest {
30 30
31 - private GangliaMetricsReporter gmr; 31 + private DefaultGangliaMetricsReporter gmr;
32 32
33 private static final String METRIC_NAME1 = "consistentMap.onos-app-ids.putIfAbsent"; 33 private static final String METRIC_NAME1 = "consistentMap.onos-app-ids.putIfAbsent";
34 private static final String METRIC_NAME2 = "consistentMap.onos-hosts.entrySet"; 34 private static final String METRIC_NAME2 = "consistentMap.onos-hosts.entrySet";
...@@ -45,7 +45,7 @@ public class GangliaMetricsReporterTest { ...@@ -45,7 +45,7 @@ public class GangliaMetricsReporterTest {
45 */ 45 */
46 @Before 46 @Before
47 public void setUp() { 47 public void setUp() {
48 - gmr = new GangliaMetricsReporter(); 48 + gmr = new DefaultGangliaMetricsReporter();
49 } 49 }
50 50
51 /** 51 /**
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.graphitemetrics;
17 +
18 +
19 +import com.codahale.metrics.MetricRegistry;
20 +import com.codahale.metrics.graphite.Graphite;
21 +import com.codahale.metrics.graphite.GraphiteReporter;
22 +import org.apache.commons.lang.StringUtils;
23 +import org.apache.felix.scr.annotations.Activate;
24 +import org.apache.felix.scr.annotations.Component;
25 +import org.apache.felix.scr.annotations.Deactivate;
26 +import org.apache.felix.scr.annotations.Modified;
27 +import org.apache.felix.scr.annotations.Property;
28 +import org.apache.felix.scr.annotations.Reference;
29 +import org.apache.felix.scr.annotations.ReferenceCardinality;
30 +import org.onlab.metrics.MetricsService;
31 +import org.onlab.util.Tools;
32 +import org.onosproject.cfg.ComponentConfigService;
33 +import org.onosproject.core.CoreService;
34 +import org.osgi.service.component.ComponentContext;
35 +import org.slf4j.Logger;
36 +
37 +import java.net.InetSocketAddress;
38 +import java.util.Dictionary;
39 +import java.util.concurrent.TimeUnit;
40 +
41 +import static org.slf4j.LoggerFactory.getLogger;
42 +
43 +/**
44 + * A metric report that reports all metrics value to graphite monitoring server.
45 + */
46 +@Component(immediate = true)
47 +public class DefaultGraphiteMetricsReporter implements GraphiteMetricsReporter {
48 +
49 + private final Logger log = getLogger(getClass());
50 +
51 + private static final TimeUnit REPORT_TIME_UNIT = TimeUnit.MINUTES;
52 + private static final int DEFAULT_REPORT_PERIOD = 1;
53 +
54 + private static final String DEFAULT_METRIC_NAMES = "default";
55 + private static final String DEFAULT_ADDRESS = "localhost";
56 + private static final int DEFAULT_PORT = 2003;
57 + private static final String DEFAULT_METRIC_NAME_PREFIX = "onos";
58 +
59 +
60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + protected CoreService coreService;
62 +
63 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 + protected MetricsService metricsService;
65 +
66 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 + protected ComponentConfigService cfgService;
68 +
69 + @Property(name = "monitorAll", boolValue = true,
70 + label = "Enable to monitor all of metrics stored in metric registry default is true")
71 + protected boolean monitorAll = true;
72 +
73 + @Property(name = "metricNames", value = DEFAULT_METRIC_NAMES,
74 + label = "Names of metric to be monitored; default metric names are 'default'")
75 + protected String metricNames = DEFAULT_METRIC_NAMES;
76 +
77 + @Property(name = "address", value = DEFAULT_ADDRESS,
78 + label = "IP address of graphite monitoring server; default is localhost")
79 + protected String address = DEFAULT_ADDRESS;
80 +
81 + @Property(name = "port", intValue = DEFAULT_PORT,
82 + label = "Port number of graphite monitoring server; default is 2003")
83 + protected int port = DEFAULT_PORT;
84 +
85 + @Property(name = "reportPeriod", intValue = DEFAULT_REPORT_PERIOD,
86 + label = "Reporting period of graphite monitoring server; default is 1")
87 + protected int reportPeriod = DEFAULT_REPORT_PERIOD;
88 +
89 + @Property(name = "metricNamePrefix", value = DEFAULT_METRIC_NAME_PREFIX,
90 + label = "Prefix of metric name for graphite back-end server; default is 'onos'")
91 + protected String metricNamePrefix = DEFAULT_METRIC_NAME_PREFIX;
92 +
93 + private Graphite graphite;
94 + private GraphiteReporter graphiteReporter;
95 +
96 + @Activate
97 + public void activate() {
98 + cfgService.registerProperties(getClass());
99 + coreService.registerApplication("org.onosproject.graphitemetrics");
100 + metricsService.registerReporter(this);
101 +
102 + startReport();
103 + log.info("Started");
104 + }
105 +
106 + @Deactivate
107 + public void deactivate() {
108 + cfgService.unregisterProperties(getClass(), false);
109 +
110 + stopReport();
111 + metricsService.unregisterReporter(this);
112 +
113 + log.info("Stopped");
114 + }
115 +
116 + @Modified
117 + public void modified(ComponentContext context) {
118 + readComponentConfiguration(context);
119 +
120 + // Restarts reporting
121 + stopReport();
122 + startReport();
123 + }
124 +
125 + public void startReport() {
126 + configGraphite();
127 + graphiteReporter = buildReporter(graphite);
128 + graphiteReporter.start(reportPeriod, REPORT_TIME_UNIT);
129 + log.info("Start to report metrics to graphite server.");
130 + }
131 +
132 + public void stopReport() {
133 + graphiteReporter.stop();
134 + graphite = null;
135 + graphiteReporter = null;
136 + log.info("Stop reporting metrics to graphite server.");
137 + }
138 +
139 + @Override
140 + public void restartReport() {
141 + stopReport();
142 + startReport();
143 + }
144 +
145 + @Override
146 + public void notifyMetricsChange() {
147 + graphiteReporter.stop();
148 + graphiteReporter = buildReporter(graphite);
149 + graphiteReporter.start(DEFAULT_REPORT_PERIOD, REPORT_TIME_UNIT);
150 + log.info("Metric registry has been changed, apply changes.");
151 + }
152 +
153 + /**
154 + * Filters the metrics to only include a set of the given metrics.
155 + *
156 + * @param metricRegistry original metric registry
157 + * @return filtered metric registry
158 + */
159 + protected MetricRegistry filter(MetricRegistry metricRegistry) {
160 + if (!monitorAll) {
161 + final MetricRegistry filtered = new MetricRegistry();
162 + metricRegistry.getNames().stream().filter(name ->
163 + containsName(name, metricNames)).forEach(name ->
164 + filtered.register(name, metricRegistry.getMetrics().get(name)));
165 + return filtered;
166 + } else {
167 + return metricRegistry;
168 + }
169 + }
170 +
171 + /**
172 + * Looks up whether the metric name contains the given prefix keywords.
173 + * Note that the keywords are separated with comma as delimiter
174 + *
175 + * @param full the original metric name that to be compared with
176 + * @param prefixes the prefix keywords that are matched against with the metric name
177 + * @return boolean value that denotes whether the metric name starts with the given prefix
178 + */
179 + protected boolean containsName(String full, String prefixes) {
180 + String[] prefixArray = StringUtils.split(prefixes, ",");
181 + for (String prefix : prefixArray) {
182 + if (StringUtils.startsWith(full, StringUtils.trimToEmpty(prefix))) {
183 + return true;
184 + }
185 + }
186 + return false;
187 + }
188 +
189 + /**
190 + * Extracts properties from the component configuration context.
191 + *
192 + * @param context the component context
193 + */
194 + private void readComponentConfiguration(ComponentContext context) {
195 + Dictionary<?, ?> properties = context.getProperties();
196 +
197 + Boolean newMonitorAll = Tools.isPropertyEnabled(properties, "monitorAll");
198 + if (newMonitorAll == null) {
199 + log.info("Monitor all metrics is not configured, " +
200 + "using current value of {}", monitorAll);
201 + } else {
202 + monitorAll = newMonitorAll;
203 + log.info("Configured. Monitor all metrics is {}, ",
204 + monitorAll ? "enabled" : "disabled");
205 + }
206 +
207 + String newMetricNames = Tools.get(properties, "metricNames");
208 + metricNames = newMetricNames != null ? newMetricNames : DEFAULT_METRIC_NAMES;
209 + log.info("Configured. Metric name is {}", metricNames);
210 +
211 + String newAddress = Tools.get(properties, "address");
212 + address = newAddress != null ? newAddress : DEFAULT_ADDRESS;
213 + log.info("Configured. Graphite monitoring server address is {}", address);
214 +
215 + Integer newPort = Tools.getIntegerProperty(properties, "port");
216 + if (newPort == null) {
217 + port = DEFAULT_PORT;
218 + log.info("Graphite port is not configured, default value is {}", port);
219 + } else {
220 + port = newPort;
221 + log.info("Configured. Graphite port is configured to {}", port);
222 + }
223 +
224 + Integer newReportPeriod = Tools.getIntegerProperty(properties, "reportPeriod");
225 + if (newReportPeriod == null) {
226 + reportPeriod = DEFAULT_REPORT_PERIOD;
227 + log.info("Report period of graphite server is not configured, " +
228 + "default value is {}", reportPeriod);
229 + } else {
230 + reportPeriod = newReportPeriod;
231 + log.info("Configured. Report period of graphite server" +
232 + " is configured to {}", reportPeriod);
233 + }
234 +
235 + String newMetricNamePrefix = Tools.get(properties, "metricNamePrefix");
236 + metricNamePrefix = newMetricNamePrefix != null ?
237 + newMetricNamePrefix : DEFAULT_METRIC_NAME_PREFIX;
238 +
239 + }
240 +
241 + /**
242 + * Configures parameters for graphite config.
243 + */
244 + private void configGraphite() {
245 + try {
246 + graphite = new Graphite(new InetSocketAddress(address, port));
247 + } catch (Exception e) {
248 + log.error("Fail to connect to given graphite server! : " + e.getMessage());
249 + }
250 + }
251 +
252 + /**
253 + * Builds reporter with the given graphite config.
254 + *
255 + * @param graphiteCfg graphite config
256 + * @return reporter
257 + */
258 + private GraphiteReporter buildReporter(Graphite graphiteCfg) {
259 + MetricRegistry metricRegistry = metricsService.getMetricRegistry();
260 + return GraphiteReporter.forRegistry(filter(metricRegistry))
261 + .prefixedWith(metricNamePrefix)
262 + .convertRatesTo(TimeUnit.SECONDS)
263 + .convertDurationsTo(TimeUnit.MILLISECONDS)
264 + .build(graphiteCfg);
265 + }
266 +}
...@@ -15,222 +15,10 @@ ...@@ -15,222 +15,10 @@
15 */ 15 */
16 package org.onosproject.graphitemetrics; 16 package org.onosproject.graphitemetrics;
17 17
18 - 18 +import org.onlab.metrics.MetricsReporter;
19 -import com.codahale.metrics.MetricRegistry;
20 -import com.codahale.metrics.graphite.Graphite;
21 -import com.codahale.metrics.graphite.GraphiteReporter;
22 -import org.apache.commons.lang.StringUtils;
23 -import org.apache.felix.scr.annotations.Activate;
24 -import org.apache.felix.scr.annotations.Component;
25 -import org.apache.felix.scr.annotations.Deactivate;
26 -import org.apache.felix.scr.annotations.Modified;
27 -import org.apache.felix.scr.annotations.Property;
28 -import org.apache.felix.scr.annotations.Reference;
29 -import org.apache.felix.scr.annotations.ReferenceCardinality;
30 -import org.onlab.util.Tools;
31 -import org.onosproject.core.ApplicationId;
32 -import org.onosproject.core.CoreService;
33 -import org.onlab.metrics.MetricsService;
34 -import org.onosproject.cfg.ComponentConfigService;
35 -import org.osgi.service.component.ComponentContext;
36 -import org.slf4j.Logger;
37 -import java.net.InetSocketAddress;
38 -import java.util.Dictionary;
39 -import java.util.concurrent.TimeUnit;
40 -
41 -import static org.slf4j.LoggerFactory.getLogger;
42 19
43 /** 20 /**
44 - * A metric report that reports all metrics value to graphite monitoring server. 21 + * Interface of graphite reporter that reports all metrics value to graphite server.
45 */ 22 */
46 -@Component(immediate = true)
47 -public class GraphiteMetricsReporter {
48 -
49 - private final Logger log = getLogger(getClass());
50 -
51 - private static final TimeUnit REPORT_TIME_UNIT = TimeUnit.MINUTES;
52 - private static final int DEFAULT_REPORT_PERIOD = 1;
53 -
54 - private static final String DEFAULT_METRIC_NAMES = "default";
55 - private static final String DEFAULT_ADDRESS = "localhost";
56 - private static final int DEFAULT_PORT = 2003;
57 - private static final String DEFAULT_METRIC_NAME_PREFIX = "onos";
58 -
59 -
60 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 - protected CoreService coreService;
62 -
63 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 - protected MetricsService metricsService;
65 -
66 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 - protected ComponentConfigService cfgService;
68 -
69 - @Property(name = "monitorAll", boolValue = true,
70 - label = "Enable to monitor all of metrics stored in metric registry default is true")
71 - protected boolean monitorAll = true;
72 -
73 - @Property(name = "metricNames", value = DEFAULT_METRIC_NAMES,
74 - label = "Names of metric to be monitored; default metric names are 'default'")
75 - protected String metricNames = DEFAULT_METRIC_NAMES;
76 -
77 - @Property(name = "address", value = DEFAULT_ADDRESS,
78 - label = "IP address of graphite monitoring server; default is localhost")
79 - protected String address = DEFAULT_ADDRESS;
80 -
81 - @Property(name = "port", intValue = DEFAULT_PORT,
82 - label = "Port number of graphite monitoring server; default is 2003")
83 - protected int port = DEFAULT_PORT;
84 -
85 - @Property(name = "reportPeriod", intValue = DEFAULT_REPORT_PERIOD,
86 - label = "Reporting period of graphite monitoring server; default is 1")
87 - protected int reportPeriod = DEFAULT_REPORT_PERIOD;
88 -
89 - @Property(name = "metricNamePrefix", value = DEFAULT_METRIC_NAME_PREFIX,
90 - label = "Prefix of metric name for graphite back-end server; default is 'onos'")
91 - protected String metricNamePrefix = DEFAULT_METRIC_NAME_PREFIX;
92 -
93 -
94 - private ApplicationId appId;
95 - private Graphite graphite;
96 - private GraphiteReporter graphiteReporter;
97 -
98 - @Activate
99 - public void activate() {
100 - cfgService.registerProperties(getClass());
101 - appId = coreService.registerApplication("org.onosproject.metrics.reporter");
102 -
103 - startReport();
104 - log.info("Started");
105 - }
106 -
107 - @Deactivate
108 - public void deactivate() {
109 - cfgService.unregisterProperties(getClass(), false);
110 -
111 - stopReport();
112 - log.info("Stopped");
113 - }
114 -
115 - @Modified
116 - public void modified(ComponentContext context) {
117 - readComponentConfiguration(context);
118 -
119 - // Restarts reporting
120 - stopReport();
121 - startReport();
122 - }
123 -
124 - public void startReport() {
125 - try {
126 - graphite = new Graphite(new InetSocketAddress(address, port));
127 -
128 - MetricRegistry metricRegistry = metricsService.getMetricRegistry();
129 -
130 - graphiteReporter = GraphiteReporter.forRegistry(filter(metricRegistry))
131 - .prefixedWith(metricNamePrefix)
132 - .convertRatesTo(TimeUnit.SECONDS)
133 - .convertDurationsTo(TimeUnit.MILLISECONDS)
134 - .build(graphite);
135 -
136 - graphiteReporter.start(reportPeriod, REPORT_TIME_UNIT);
137 - log.info("Start to report metrics to graphite.");
138 - } catch (Exception e) {
139 - log.error("Fail to connect to given graphite server! : " + e.getMessage());
140 - }
141 - }
142 -
143 - public void stopReport() {
144 - graphiteReporter.stop();
145 - graphite = null;
146 - graphiteReporter = null;
147 - }
148 -
149 - /**
150 - * Filters the metrics to only include a set of the given metrics.
151 - *
152 - * @param metricRegistry original metric registry
153 - * @return filtered metric registry
154 - */
155 - protected MetricRegistry filter(MetricRegistry metricRegistry) {
156 - if (!monitorAll) {
157 - final MetricRegistry filtered = new MetricRegistry();
158 - metricRegistry.getNames().stream().filter(name ->
159 - containsName(name, metricNames)).forEach(name ->
160 - filtered.register(name, metricRegistry.getMetrics().get(name)));
161 - return filtered;
162 - } else {
163 - return metricRegistry;
164 - }
165 - }
166 -
167 - /**
168 - * Looks up whether the metric name contains the given prefix keywords.
169 - * Note that the keywords are separated with comma as delimiter
170 - *
171 - * @param full the original metric name that to be compared with
172 - * @param prefixes the prefix keywords that are matched against with the metric name
173 - * @return boolean value that denotes whether the metric name starts with the given prefix
174 - */
175 - protected boolean containsName(String full, String prefixes) {
176 - String[] prefixArray = StringUtils.split(prefixes, ",");
177 - for (String prefix : prefixArray) {
178 - if (StringUtils.startsWith(full, StringUtils.trimToEmpty(prefix))) {
179 - return true;
180 - }
181 - }
182 - return false;
183 - }
184 -
185 - /**
186 - * Extracts properties from the component configuration context.
187 - *
188 - * @param context the component context
189 - */
190 - private void readComponentConfiguration(ComponentContext context) {
191 - Dictionary<?, ?> properties = context.getProperties();
192 -
193 - Boolean newMonitorAll = Tools.isPropertyEnabled(properties, "monitorAll");
194 - if (newMonitorAll == null) {
195 - log.info("Monitor all metrics is not configured, " +
196 - "using current value of {}", monitorAll);
197 - } else {
198 - monitorAll = newMonitorAll;
199 - log.info("Configured. Monitor all metrics is {}, ",
200 - monitorAll ? "enabled" : "disabled");
201 - }
202 -
203 - String newMetricNames = Tools.get(properties, "metricNames");
204 - metricNames = newMetricNames != null ? newMetricNames : DEFAULT_METRIC_NAMES;
205 - log.info("Configured. Metric name is {}", metricNames);
206 -
207 - String newAddress = Tools.get(properties, "address");
208 - address = newAddress != null ? newAddress : DEFAULT_ADDRESS;
209 - log.info("Configured. Graphite monitoring server address is {}", address);
210 -
211 - Integer newPort = Tools.getIntegerProperty(properties, "port");
212 - if (newPort == null) {
213 - port = DEFAULT_PORT;
214 - log.info("Graphite port is not configured, default value is {}", port);
215 - } else {
216 - port = newPort;
217 - log.info("Configured. Graphite port is configured to {}", port);
218 - }
219 -
220 - Integer newReportPeriod = Tools.getIntegerProperty(properties, "reportPeriod");
221 - if (newReportPeriod == null) {
222 - reportPeriod = DEFAULT_REPORT_PERIOD;
223 - log.info("Report period of graphite server is not configured, " +
224 - "default value is {}", reportPeriod);
225 - } else {
226 - reportPeriod = newReportPeriod;
227 - log.info("Configured. Report period of graphite server" +
228 - " is configured to {}", reportPeriod);
229 - }
230 -
231 - String newMetricNamePrefix = Tools.get(properties, "metricNamePrefix");
232 - metricNamePrefix = newMetricNamePrefix != null ?
233 - newMetricNamePrefix : DEFAULT_METRIC_NAME_PREFIX;
234 -
235 - }
236 -}
...\ No newline at end of file ...\ No newline at end of file
23 +public interface GraphiteMetricsReporter extends MetricsReporter {
24 +}
......
...@@ -15,35 +15,20 @@ ...@@ -15,35 +15,20 @@
15 */ 15 */
16 package org.onosproject.graphitemetrics; 16 package org.onosproject.graphitemetrics;
17 17
18 -import com.codahale.metrics.Counter;
19 -import com.codahale.metrics.Gauge;
20 -import com.codahale.metrics.Histogram;
21 -import com.codahale.metrics.Meter;
22 -import com.codahale.metrics.Metric;
23 -import com.codahale.metrics.MetricFilter;
24 import com.codahale.metrics.MetricRegistry; 18 import com.codahale.metrics.MetricRegistry;
25 -import com.codahale.metrics.Timer;
26 import com.google.common.collect.ImmutableSet; 19 import com.google.common.collect.ImmutableSet;
27 import org.junit.Before; 20 import org.junit.Before;
28 import org.junit.Test; 21 import org.junit.Test;
29 -import org.onlab.metrics.MetricsComponent;
30 -import org.onlab.metrics.MetricsFeature;
31 -import org.onlab.metrics.MetricsService;
32 -import org.onosproject.cfg.ComponentConfigAdapter;
33 -import org.onosproject.core.CoreServiceAdapter;
34 -
35 -import java.util.Map;
36 22
37 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertFalse;
38 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.assertTrue;
39 -import static org.junit.Assert.assertNotNull;
40 25
41 /** 26 /**
42 * Unit test for metrics reporter of graphite. 27 * Unit test for metrics reporter of graphite.
43 */ 28 */
44 public class GraphiteMetricsReporterTest { 29 public class GraphiteMetricsReporterTest {
45 30
46 - private GraphiteMetricsReporter gmr; 31 + private DefaultGraphiteMetricsReporter gmr;
47 32
48 private static final String METRIC_NAME1 = "consistentMap.onos-app-ids.putIfAbsent"; 33 private static final String METRIC_NAME1 = "consistentMap.onos-app-ids.putIfAbsent";
49 private static final String METRIC_NAME2 = "consistentMap.onos-hosts.entrySet"; 34 private static final String METRIC_NAME2 = "consistentMap.onos-hosts.entrySet";
...@@ -60,11 +45,7 @@ public class GraphiteMetricsReporterTest { ...@@ -60,11 +45,7 @@ public class GraphiteMetricsReporterTest {
60 */ 45 */
61 @Before 46 @Before
62 public void setUp() { 47 public void setUp() {
63 - gmr = new GraphiteMetricsReporter(); 48 + gmr = new DefaultGraphiteMetricsReporter();
64 - gmr.coreService = new CoreServiceAdapter();
65 - gmr.cfgService = new ComponentConfigAdapter();
66 - gmr.metricsService = new TestMetricsService();
67 - gmr.activate();
68 } 49 }
69 50
70 /** 51 /**
...@@ -135,116 +116,4 @@ public class GraphiteMetricsReporterTest { ...@@ -135,116 +116,4 @@ public class GraphiteMetricsReporterTest {
135 .containsAll(ImmutableSet.of(METRIC_NAME1, METRIC_NAME2, 116 .containsAll(ImmutableSet.of(METRIC_NAME1, METRIC_NAME2,
136 METRIC_NAME3, METRIC_NAME4))); 117 METRIC_NAME3, METRIC_NAME4)));
137 } 118 }
138 -
139 - /**
140 - * Tests whether the methods of MetricsService receives null value parameter.
141 - */
142 - private class TestMetricsService implements MetricsService {
143 -
144 - @Override
145 - public MetricsComponent registerComponent(String name) {
146 - assertNotNull("Component name is null.", name);
147 - return null;
148 - }
149 -
150 - @Override
151 - public MetricRegistry getMetricRegistry() {
152 - return null;
153 - }
154 -
155 - @Override
156 - public Counter createCounter(MetricsComponent component,
157 - MetricsFeature feature, String metricName) {
158 - assertNotNull("MetricsComponent is null.", component);
159 - assertNotNull("MetricsFeature is null.", feature);
160 - assertNotNull("Metric name is null.", metricName);
161 - return null;
162 - }
163 -
164 - @Override
165 - public Histogram createHistogram(MetricsComponent component,
166 - MetricsFeature feature, String metricName) {
167 - assertNotNull("MetricsComponent is null.", component);
168 - assertNotNull("MetricsFeature is null.", feature);
169 - assertNotNull("Metric name is null.", metricName);
170 - return null;
171 - }
172 -
173 - @Override
174 - public Timer createTimer(MetricsComponent component,
175 - MetricsFeature feature, String metricName) {
176 - assertNotNull("MetricsComponent is null.", component);
177 - assertNotNull("MetricsFeature is null.", feature);
178 - assertNotNull("Metric name is null.", metricName);
179 - return null;
180 - }
181 -
182 - @Override
183 - public Meter createMeter(MetricsComponent component,
184 - MetricsFeature feature, String metricName) {
185 - assertNotNull("MetricsComponent is null.", component);
186 - assertNotNull("MetricsFeature is null.", feature);
187 - assertNotNull("Metric name is null.", metricName);
188 - return null;
189 - }
190 -
191 - @Override
192 - public <T extends Metric> T registerMetric(MetricsComponent component,
193 - MetricsFeature feature, String metricName, T metric) {
194 - assertNotNull("MetricsComponent is null.", component);
195 - assertNotNull("MetricsFeature is null.", feature);
196 - assertNotNull("Metric name is null.", metricName);
197 - assertNotNull("Metric is null.", metric);
198 - return null;
199 - }
200 -
201 - @Override
202 - public boolean removeMetric(MetricsComponent component,
203 - MetricsFeature feature, String metricName) {
204 - assertNotNull("MetricsComponent is null.", component);
205 - assertNotNull("MetricsFeature is null.", feature);
206 - assertNotNull("Metric name is null.", metricName);
207 - return false;
208 - }
209 -
210 - @Override
211 - public Map<String, Timer> getTimers(MetricFilter filter) {
212 - assertNotNull("MetricFilter is null.", filter);
213 - return null;
214 - }
215 -
216 - @Override
217 - public Map<String, Gauge> getGauges(MetricFilter filter) {
218 - assertNotNull("MetricFilter is null.", filter);
219 - return null;
220 - }
221 -
222 - @Override
223 - public Map<String, Counter> getCounters(MetricFilter filter) {
224 - assertNotNull("MetricFilter is null.", filter);
225 - return null;
226 - }
227 -
228 - @Override
229 - public Map<String, Meter> getMeters(MetricFilter filter) {
230 - assertNotNull("MetricFilter is null.", filter);
231 - return null;
232 - }
233 -
234 - @Override
235 - public Map<String, Histogram> getHistograms(MetricFilter filter) {
236 - assertNotNull("MetricFilter is null.", filter);
237 - return null;
238 - }
239 -
240 - @Override
241 - public Map<String, Metric> getMetrics() {
242 - return null;
243 - }
244 -
245 - @Override
246 - public void removeMatching(MetricFilter filter) {
247 - assertNotNull("MetricFilter is null.", filter);
248 - }
249 - }
250 } 119 }
......
...@@ -93,6 +93,9 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter { ...@@ -93,6 +93,9 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
93 public void activate() { 93 public void activate() {
94 cfgService.registerProperties(getClass()); 94 cfgService.registerProperties(getClass());
95 coreService.registerApplication("org.onosproject.influxdbmetrics"); 95 coreService.registerApplication("org.onosproject.influxdbmetrics");
96 + metricsService.registerReporter(this);
97 +
98 + startReport();
96 99
97 log.info("Started"); 100 log.info("Started");
98 } 101 }
...@@ -101,6 +104,9 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter { ...@@ -101,6 +104,9 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
101 public void deactivate() { 104 public void deactivate() {
102 cfgService.unregisterProperties(getClass(), false); 105 cfgService.unregisterProperties(getClass(), false);
103 106
107 + stopReport();
108 + metricsService.unregisterReporter(this);
109 +
104 log.info("Stopped"); 110 log.info("Stopped");
105 } 111 }
106 112
...@@ -112,20 +118,10 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter { ...@@ -112,20 +118,10 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
112 118
113 @Override 119 @Override
114 public void startReport() { 120 public void startReport() {
115 - try { 121 + configSender();
116 - influxDbHttpSender = new InfluxDbHttpSender(DEFAULT_PROTOCOL, address, 122 + influxDbReporter = buildReporter(influxDbHttpSender);
117 - port, database, username + SEPARATOR + password, REPORT_TIME_UNIT, 123 + influxDbReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
118 - DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT); 124 + log.info("Start to report metrics to influxDB.");
119 - MetricRegistry mr = metricsService.getMetricRegistry();
120 - influxDbReporter = InfluxDbReporter.forRegistry(addHostPrefix(filter(mr)))
121 - .convertRatesTo(TimeUnit.SECONDS)
122 - .convertDurationsTo(TimeUnit.MILLISECONDS)
123 - .build(influxDbHttpSender);
124 - influxDbReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
125 - log.info("Start to report metrics to influxDB.");
126 - } catch (Exception e) {
127 - log.error("Fail to connect to given influxDB server!");
128 - }
129 } 125 }
130 126
131 @Override 127 @Override
...@@ -143,6 +139,14 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter { ...@@ -143,6 +139,14 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
143 } 139 }
144 140
145 @Override 141 @Override
142 + public void notifyMetricsChange() {
143 + influxDbReporter.stop();
144 + influxDbReporter = buildReporter(influxDbHttpSender);
145 + influxDbReporter.start(REPORT_PERIOD, REPORT_TIME_UNIT);
146 + log.info("Metric registry has been changed, apply changes.");
147 + }
148 +
149 + @Override
146 public void config(String address, int port, String database, 150 public void config(String address, int port, String database,
147 String username, String password) { 151 String username, String password) {
148 this.address = address; 152 this.address = address;
...@@ -226,4 +230,31 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter { ...@@ -226,4 +230,31 @@ public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
226 monitorAll ? "enabled" : "disabled"); 230 monitorAll ? "enabled" : "disabled");
227 } 231 }
228 } 232 }
233 +
234 + /**
235 + * Configures parameters for sender.
236 + */
237 + private void configSender() {
238 + try {
239 + influxDbHttpSender = new InfluxDbHttpSender(DEFAULT_PROTOCOL, address,
240 + port, database, username + SEPARATOR + password, REPORT_TIME_UNIT,
241 + DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
242 + } catch (Exception e) {
243 + log.error("Fail to connect to given influxDB server!");
244 + }
245 + }
246 +
247 + /**
248 + * Builds reporter with the given sender.
249 + *
250 + * @param sender sender
251 + * @return reporter
252 + */
253 + private InfluxDbReporter buildReporter(InfluxDbHttpSender sender) {
254 + MetricRegistry mr = metricsService.getMetricRegistry();
255 + return InfluxDbReporter.forRegistry(addHostPrefix(filter(mr)))
256 + .convertRatesTo(TimeUnit.SECONDS)
257 + .convertDurationsTo(TimeUnit.MILLISECONDS)
258 + .build(sender);
259 + }
229 } 260 }
......
...@@ -86,8 +86,6 @@ public class InfluxDbMetricsConfig { ...@@ -86,8 +86,6 @@ public class InfluxDbMetricsConfig {
86 coreService.registerApplication("org.onosproject.influxdbmetrics"); 86 coreService.registerApplication("org.onosproject.influxdbmetrics");
87 87
88 configReporter(influxDbMetricsReporter); 88 configReporter(influxDbMetricsReporter);
89 - influxDbMetricsReporter.startReport();
90 -
91 configRetriever(influxDbMetricsRetriever); 89 configRetriever(influxDbMetricsRetriever);
92 90
93 log.info("Started"); 91 log.info("Started");
...@@ -97,7 +95,6 @@ public class InfluxDbMetricsConfig { ...@@ -97,7 +95,6 @@ public class InfluxDbMetricsConfig {
97 public void deactivate() { 95 public void deactivate() {
98 cfgService.unregisterProperties(getClass(), false); 96 cfgService.unregisterProperties(getClass(), false);
99 97
100 - influxDbMetricsReporter.stopReport();
101 log.info("Stopped"); 98 log.info("Stopped");
102 } 99 }
103 100
......
...@@ -15,25 +15,12 @@ ...@@ -15,25 +15,12 @@
15 */ 15 */
16 package org.onosproject.influxdbmetrics; 16 package org.onosproject.influxdbmetrics;
17 17
18 +import org.onlab.metrics.MetricsReporter;
19 +
18 /** 20 /**
19 * A Metric reporter interface for reporting all metrics to influxDB server. 21 * A Metric reporter interface for reporting all metrics to influxDB server.
20 */ 22 */
21 -public interface InfluxDbMetricsReporter { 23 +public interface InfluxDbMetricsReporter extends MetricsReporter {
22 -
23 - /**
24 - * Starts to report metrics to InfluxDB server.
25 - */
26 - void startReport();
27 -
28 - /**
29 - * Stops reporting metrics.
30 - */
31 - void stopReport();
32 -
33 - /**
34 - * Restarts metrics reporter.
35 - */
36 - void restartReport();
37 24
38 /** 25 /**
39 * Configures default parameters for influx database metrics reporter. 26 * Configures default parameters for influx database metrics reporter.
......
...@@ -26,6 +26,7 @@ import com.codahale.metrics.Timer; ...@@ -26,6 +26,7 @@ import com.codahale.metrics.Timer;
26 import org.junit.Before; 26 import org.junit.Before;
27 import org.onlab.metrics.MetricsComponent; 27 import org.onlab.metrics.MetricsComponent;
28 import org.onlab.metrics.MetricsFeature; 28 import org.onlab.metrics.MetricsFeature;
29 +import org.onlab.metrics.MetricsReporter;
29 import org.onlab.metrics.MetricsService; 30 import org.onlab.metrics.MetricsService;
30 import org.onosproject.cfg.ComponentConfigAdapter; 31 import org.onosproject.cfg.ComponentConfigAdapter;
31 import org.onosproject.cluster.ClusterServiceAdapter; 32 import org.onosproject.cluster.ClusterServiceAdapter;
...@@ -104,6 +105,18 @@ public class InfluxDbMetricsReporterTest { ...@@ -104,6 +105,18 @@ public class InfluxDbMetricsReporterTest {
104 } 105 }
105 106
106 @Override 107 @Override
108 + public void registerReporter(MetricsReporter reporter) {
109 + }
110 +
111 + @Override
112 + public void unregisterReporter(MetricsReporter reporter) {
113 + }
114 +
115 + @Override
116 + public void notifyReporters() {
117 + }
118 +
119 + @Override
107 public boolean removeMetric(MetricsComponent component, 120 public boolean removeMetric(MetricsComponent component,
108 MetricsFeature feature, String metricName) { 121 MetricsFeature feature, String metricName) {
109 return false; 122 return false;
......
...@@ -86,6 +86,7 @@ public class OpenFlowControlMessageAggregator implements Runnable { ...@@ -86,6 +86,7 @@ public class OpenFlowControlMessageAggregator implements Runnable {
86 86
87 this.deviceId = deviceId; 87 this.deviceId = deviceId;
88 this.providerService = providerService; 88 this.providerService = providerService;
89 + metricsService.notifyReporters();
89 } 90 }
90 91
91 /** 92 /**
......
...@@ -15,10 +15,6 @@ ...@@ -15,10 +15,6 @@
15 */ 15 */
16 package org.onlab.metrics; 16 package org.onlab.metrics;
17 17
18 -import java.util.Map;
19 -import java.util.concurrent.ConcurrentHashMap;
20 -import java.util.concurrent.ConcurrentMap;
21 -
22 import com.codahale.metrics.Counter; 18 import com.codahale.metrics.Counter;
23 import com.codahale.metrics.Gauge; 19 import com.codahale.metrics.Gauge;
24 import com.codahale.metrics.Histogram; 20 import com.codahale.metrics.Histogram;
...@@ -27,6 +23,12 @@ import com.codahale.metrics.Metric; ...@@ -27,6 +23,12 @@ import com.codahale.metrics.Metric;
27 import com.codahale.metrics.MetricFilter; 23 import com.codahale.metrics.MetricFilter;
28 import com.codahale.metrics.MetricRegistry; 24 import com.codahale.metrics.MetricRegistry;
29 import com.codahale.metrics.Timer; 25 import com.codahale.metrics.Timer;
26 +import com.google.common.collect.Sets;
27 +
28 +import java.util.Map;
29 +import java.util.Set;
30 +import java.util.concurrent.ConcurrentHashMap;
31 +import java.util.concurrent.ConcurrentMap;
30 32
31 /** 33 /**
32 * This class holds the Metrics registry for ONOS. 34 * This class holds the Metrics registry for ONOS.
...@@ -74,6 +76,11 @@ public class MetricsManager implements MetricsService { ...@@ -74,6 +76,11 @@ public class MetricsManager implements MetricsService {
74 private MetricRegistry metricsRegistry = new MetricRegistry(); 76 private MetricRegistry metricsRegistry = new MetricRegistry();
75 77
76 /** 78 /**
79 + * Reporter for exposing metrics objects to third party persistent system.
80 + */
81 + private Set<MetricsReporter> reporters = Sets.newConcurrentHashSet();
82 +
83 + /**
77 * Clears the internal state. 84 * Clears the internal state.
78 */ 85 */
79 protected void clear() { 86 protected void clear() {
...@@ -216,6 +223,34 @@ public class MetricsManager implements MetricsService { ...@@ -216,6 +223,34 @@ public class MetricsManager implements MetricsService {
216 } 223 }
217 224
218 /** 225 /**
226 + * Registers a reporter to receive any changes on metric registry.
227 + *
228 + * @param reporter metric reporter
229 + */
230 + @Override
231 + public void registerReporter(MetricsReporter reporter) {
232 + reporters.add(reporter);
233 + }
234 +
235 + /**
236 + * Unregisters the given metric reporter.
237 + *
238 + * @param reporter metric reporter
239 + */
240 + @Override
241 + public void unregisterReporter(MetricsReporter reporter) {
242 + reporters.remove(reporter);
243 + }
244 +
245 + /**
246 + * Notifies the changes on metric registry to all registered reporters.
247 + */
248 + @Override
249 + public void notifyReporters() {
250 + reporters.forEach(MetricsReporter::notifyMetricsChange);
251 + }
252 +
253 + /**
219 * Removes the metric with the given name. 254 * Removes the metric with the given name.
220 * 255 *
221 * @param component component the Metric is defined in 256 * @param component component the Metric is defined in
......
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.gangliametrics; 16 +package org.onlab.metrics;
17 17
18 /** 18 /**
19 - * A metric report that reports all metrics value to third party monitor. 19 + * Interface of reporter that reports all metrics value to third party monitor.
20 */ 20 */
21 public interface MetricsReporter { 21 public interface MetricsReporter {
22 22
...@@ -29,4 +29,14 @@ public interface MetricsReporter { ...@@ -29,4 +29,14 @@ public interface MetricsReporter {
29 * Stops reporting metrics. 29 * Stops reporting metrics.
30 */ 30 */
31 void stopReport(); 31 void stopReport();
32 +
33 + /**
34 + * Restarts metrics reporter.
35 + */
36 + void restartReport();
37 +
38 + /**
39 + * Notifies the changes on metric registry.
40 + */
41 + void notifyMetricsChange();
32 } 42 }
......
...@@ -113,6 +113,25 @@ public interface MetricsService { ...@@ -113,6 +113,25 @@ public interface MetricsService {
113 T metric); 113 T metric);
114 114
115 /** 115 /**
116 + * Registers a reporter to receive any changes on metric registry.
117 + *
118 + * @param reporter metric reporter
119 + */
120 + void registerReporter(MetricsReporter reporter);
121 +
122 + /**
123 + * Unregisters the given metric reporter.
124 + *
125 + * @param reporter metric reporter
126 + */
127 + void unregisterReporter(MetricsReporter reporter);
128 +
129 + /**
130 + * Notifies the changes on metric registry to all registered reporters.
131 + */
132 + void notifyReporters();
133 +
134 + /**
116 * Removes the metric with the given name. 135 * Removes the metric with the given name.
117 * 136 *
118 * @param component component the Metric is defined in 137 * @param component component the Metric is defined in
......
...@@ -75,6 +75,18 @@ public class MetricsServiceAdapter implements MetricsService { ...@@ -75,6 +75,18 @@ public class MetricsServiceAdapter implements MetricsService {
75 } 75 }
76 76
77 @Override 77 @Override
78 + public void registerReporter(MetricsReporter reporter) {
79 + }
80 +
81 + @Override
82 + public void unregisterReporter(MetricsReporter reporter) {
83 + }
84 +
85 + @Override
86 + public void notifyReporters() {
87 + }
88 +
89 + @Override
78 public boolean removeMetric(MetricsComponent component, 90 public boolean removeMetric(MetricsComponent component,
79 MetricsFeature feature, String metricName) { 91 MetricsFeature feature, String metricName) {
80 return false; 92 return false;
......