blob: c1be6f60d2b9adff0e4eea01f9d0e430c74bddd3 [file] [log] [blame]
Jian Lie1d97c92016-03-22 10:21:44 -07001/*
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 */
16package org.onosproject.influxdbmetrics;
17
18import com.codahale.metrics.MetricRegistry;
19import com.izettle.metrics.influxdb.InfluxDbHttpSender;
20import com.izettle.metrics.influxdb.InfluxDbReporter;
21import org.apache.commons.lang.StringUtils;
22import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
25import org.apache.felix.scr.annotations.Modified;
26import org.apache.felix.scr.annotations.Property;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
29import org.apache.felix.scr.annotations.Service;
30import org.onlab.metrics.MetricsService;
31import org.onlab.util.Tools;
32import org.onosproject.cfg.ComponentConfigService;
33import org.onosproject.cluster.ClusterService;
34import org.onosproject.cluster.ControllerNode;
35import org.onosproject.core.CoreService;
36import org.osgi.service.component.ComponentContext;
37import org.slf4j.Logger;
38
39import java.util.Dictionary;
40import java.util.concurrent.TimeUnit;
41
42import static org.slf4j.LoggerFactory.getLogger;
43
44/**
45 * A Metric reporter that reports all metrics value to influxDB server.
46 */
47@Component(immediate = true)
48@Service
49public class DefaultInfluxDbMetricsReporter implements InfluxDbMetricsReporter {
50 private final Logger log = getLogger(getClass());
51
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_PROTOCOL = "http";
56 private static final String DEFAULT_METRIC_NAMES = "default";
57 private static final String SEPARATOR = ":";
58 private static final int DEFAULT_CONN_TIMEOUT = 1000;
59 private static final int DEFAULT_READ_TIMEOUT = 1000;
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 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected ClusterService clusterService;
72
73 @Property(name = "monitorAll", boolValue = true,
74 label = "Enable to monitor all of metrics stored in metric registry " +
75 "default is true")
76 protected boolean monitorAll = true;
77
78 @Property(name = "metricNames", value = DEFAULT_METRIC_NAMES,
79 label = "Names of metric to be monitored in third party monitoring " +
80 "server; default metric names are 'default'")
81 protected String metricNames = DEFAULT_METRIC_NAMES;
82
83 protected String address;
84 protected int port;
85 protected String database;
86 protected String username;
87 protected String password;
88
89 private InfluxDbReporter influxDbReporter;
90 private InfluxDbHttpSender influxDbHttpSender;
91
92 @Activate
93 public void activate() {
94 cfgService.registerProperties(getClass());
95 coreService.registerApplication("org.onosproject.influxdbmetrics");
96
97 log.info("Started");
98 }
99
100 @Deactivate
101 public void deactivate() {
102 cfgService.unregisterProperties(getClass(), false);
103
104 log.info("Stopped");
105 }
106
107 @Modified
108 public void modified(ComponentContext context) {
109 readComponentConfiguration(context);
110 restartReport();
111 }
112
113 @Override
114 public void startReport() {
115 try {
116 influxDbHttpSender = new InfluxDbHttpSender(DEFAULT_PROTOCOL, address,
117 port, database, username + SEPARATOR + password, REPORT_TIME_UNIT,
118 DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
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 }
130
131 @Override
132 public void stopReport() {
133 influxDbReporter.stop();
134 influxDbHttpSender = null;
135 influxDbReporter = null;
136 log.info("Stop reporting metrics to influxDB.");
137 }
138
139 @Override
140 public void restartReport() {
141 stopReport();
142 startReport();
143 }
144
145 @Override
146 public void config(String address, int port, String database,
147 String username, String password) {
148 this.address = address;
149 this.port = port;
150 this.database = database;
151 this.username = username;
152 this.password = password;
153 }
154
155 /**
156 * Filters the metrics to only include a set of the given metrics.
157 *
158 * @param metricRegistry original metric registry
159 * @return filtered metric registry
160 */
161 protected MetricRegistry filter(MetricRegistry metricRegistry) {
162 if (!monitorAll) {
163 final MetricRegistry filtered = new MetricRegistry();
164 metricRegistry.getNames().stream().filter(name ->
165 containsName(name, metricNames)).forEach(name ->
166 filtered.register(name, metricRegistry.getMetrics().get(name)));
167 return filtered;
168 } else {
169 return metricRegistry;
170 }
171 }
172
173 /**
174 * Appends node IP prefix to all performance metrics.
175 *
176 * @param metricRegistry original metric registry
177 * @return prefix added metric registry
178 */
179 protected MetricRegistry addHostPrefix(MetricRegistry metricRegistry) {
180 MetricRegistry moddedRegistry = new MetricRegistry();
181 ControllerNode node = clusterService.getLocalNode();
182 String prefix = node.id().id() + ".";
183 metricRegistry.getNames().stream().forEach(name ->
184 moddedRegistry.register(prefix + name, metricRegistry.getMetrics().get(name)));
185
186 return moddedRegistry;
187 }
188
189 /**
190 * Looks up whether the metric name contains the given prefix keywords.
191 * Note that the keywords are separated with comma as delimiter.
192 *
193 * @param full the original metric name that to be compared with
194 * @param prefixes the prefix keywords that are matched against with the metric name
195 * @return boolean value that denotes whether the metric name starts with the given prefix
196 */
197 protected boolean containsName(String full, String prefixes) {
198 String[] prefixArray = StringUtils.split(prefixes, ",");
199 for (String prefix : prefixArray) {
200 if (StringUtils.startsWith(full, StringUtils.trimToEmpty(prefix))) {
201 return true;
202 }
203 }
204 return false;
205 }
206
207 /**
208 * Extracts properties from the component configuration context.
209 *
210 * @param context the component context
211 */
212 private void readComponentConfiguration(ComponentContext context) {
213 Dictionary<?, ?> properties = context.getProperties();
214
215 String metricNameStr = Tools.get(properties, "metricNames");
216 metricNames = metricNameStr != null ? metricNameStr : DEFAULT_METRIC_NAMES;
217 log.info("Configured. Metric name is {}", metricNames);
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}