blob: b26ffdd193553ea22866af0c6c0937ad7e475e1d [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.metrics.topology;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070017
18import static org.slf4j.LoggerFactory.getLogger;
19
20import java.util.LinkedList;
21import java.util.List;
22
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070023import com.google.common.collect.ImmutableList;
24import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
29import org.apache.felix.scr.annotations.Service;
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070030import org.onlab.metrics.EventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070031import org.onlab.metrics.MetricsService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreService;
34import org.onosproject.event.Event;
35import org.onosproject.net.device.DeviceEvent;
36import org.onosproject.net.device.DeviceListener;
37import org.onosproject.net.device.DeviceService;
38import org.onosproject.net.host.HostEvent;
39import org.onosproject.net.host.HostListener;
40import org.onosproject.net.host.HostService;
41import org.onosproject.net.link.LinkEvent;
42import org.onosproject.net.link.LinkListener;
43import org.onosproject.net.link.LinkService;
44import org.onosproject.net.topology.TopologyEvent;
45import org.onosproject.net.topology.TopologyListener;
46import org.onosproject.net.topology.TopologyService;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070047import org.slf4j.Logger;
48
49/**
50 * ONOS Topology Metrics Application that collects topology-related metrics.
51 */
52@Component(immediate = true)
53@Service
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070054public class TopologyMetrics implements TopologyMetricsService {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070055 private static final Logger log = getLogger(TopologyMetrics.class);
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080058 protected CoreService coreService;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070061 protected DeviceService deviceService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080062
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070063 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected HostService hostService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080065
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected LinkService linkService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080068
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070069 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected MetricsService metricsService;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070071
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected TopologyService topologyService;
74
75 private ApplicationId appId;
76
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070077 private LinkedList<Event> lastEvents = new LinkedList<>();
78 private static final int LAST_EVENTS_MAX_N = 100;
79
80 private final DeviceListener deviceListener = new InnerDeviceListener();
81 private final HostListener hostListener = new InnerHostListener();
82 private final LinkListener linkListener = new InnerLinkListener();
83 private final TopologyListener topologyListener =
84 new InnerTopologyListener();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070085
86 //
87 // Metrics
88 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070089 private static final String COMPONENT_NAME = "Topology";
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070090 private static final String FEATURE_DEVICE_NAME = "DeviceEvent";
91 private static final String FEATURE_HOST_NAME = "HostEvent";
92 private static final String FEATURE_LINK_NAME = "LinkEvent";
93 private static final String FEATURE_GRAPH_NAME = "GraphEvent";
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -070094 private static final String FEATURE_GRAPH_REASONS_NAME = "GraphReasonsEvent";
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070095 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070096 // Event metrics:
97 // - Device events
98 // - Host events
99 // - Link events
100 // - Topology Graph events
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700101 // - Topology Graph Reasons events
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700102 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700103 private EventMetric topologyDeviceEventMetric;
104 private EventMetric topologyHostEventMetric;
105 private EventMetric topologyLinkEventMetric;
106 private EventMetric topologyGraphEventMetric;
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700107 private EventMetric topologyGraphReasonsEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700108
109 @Activate
110 protected void activate() {
Thomas Vachuskafba28572015-03-25 18:48:59 -0700111 appId = coreService.registerApplication("org.onosproject.metrics");
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800112
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700113 clear();
114 registerMetrics();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700115
116 // Register for all topology-related events
117 deviceService.addListener(deviceListener);
118 hostService.addListener(hostListener);
119 linkService.addListener(linkListener);
120 topologyService.addListener(topologyListener);
121
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800122 log.info("Started with Application ID {}", appId.id());
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700123 }
124
125 @Deactivate
126 public void deactivate() {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700127 // De-register from all topology-related events
128 deviceService.removeListener(deviceListener);
129 hostService.removeListener(hostListener);
130 linkService.removeListener(linkListener);
131 topologyService.removeListener(topologyListener);
132
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700133 removeMetrics();
134 clear();
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800135 log.info("Stopped");
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700136 }
137
138 @Override
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700139 public List<Event> getEvents() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700140 synchronized (lastEvents) {
Sho SHIMIZUfd0933b2015-09-11 15:17:48 -0700141 return ImmutableList.copyOf(lastEvents);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700142 }
143 }
144
145 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700146 public EventMetric topologyDeviceEventMetric() {
147 return topologyDeviceEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700148 }
149
150 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700151 public EventMetric topologyHostEventMetric() {
152 return topologyHostEventMetric;
153 }
154
155 @Override
156 public EventMetric topologyLinkEventMetric() {
157 return topologyLinkEventMetric;
158 }
159
160 @Override
161 public EventMetric topologyGraphEventMetric() {
162 return topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700163 }
164
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700165 @Override
166 public EventMetric topologyGraphReasonsEventMetric() {
167 return topologyGraphReasonsEventMetric;
168 }
169
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700170 /**
171 * Records an event.
172 *
173 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700174 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700175 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700176 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700177 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700178 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700179
180 //
181 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
182 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700183 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
184 lastEvents.remove();
185 }
186 lastEvents.add(event);
187 }
188 }
189
190 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700191 * Inner Device Event Listener class.
192 */
193 private class InnerDeviceListener implements DeviceListener {
194 @Override
195 public void event(DeviceEvent event) {
andrew@onlab.us88d22822015-04-23 18:07:17 -0400196 // Ignore PORT_STATS_UPDATED probe event from interfering with
197 // other device event timestamps
198 if (event.type() == DeviceEvent.Type.PORT_STATS_UPDATED) {
HIGUCHI Yutaaa4196f2015-10-15 11:54:43 -0700199 log.debug("PORT_STATS_UPDATED event ignored from metrics");
andrew@onlab.us88d22822015-04-23 18:07:17 -0400200 } else {
201 recordEvent(event, topologyDeviceEventMetric);
HIGUCHI Yutaaa4196f2015-10-15 11:54:43 -0700202 log.debug("Device Event: time = {} type = {} event = {}",
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700203 event.time(), event.type(), event);
andrew@onlab.us88d22822015-04-23 18:07:17 -0400204 }
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700205 }
206 }
207
208 /**
209 * Inner Host Event Listener class.
210 */
211 private class InnerHostListener implements HostListener {
212 @Override
213 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700214 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700215 log.debug("Host Event: time = {} type = {} event = {}",
216 event.time(), event.type(), event);
217 }
218 }
219
220 /**
221 * Inner Link Event Listener class.
222 */
223 private class InnerLinkListener implements LinkListener {
224 @Override
225 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700226 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700227 log.debug("Link Event: time = {} type = {} event = {}",
228 event.time(), event.type(), event);
229 }
230 }
231
232 /**
233 * Inner Topology Event Listener class.
234 */
235 private class InnerTopologyListener implements TopologyListener {
236 @Override
237 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700238 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700239 log.debug("Topology Event: time = {} type = {} event = {}",
240 event.time(), event.type(), event);
241 for (Event reason : event.reasons()) {
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700242 recordEvent(event, topologyGraphReasonsEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700243 log.debug("Topology Event Reason: time = {} type = {} event = {}",
244 reason.time(), reason.type(), reason);
245 }
246 }
247 }
248
249 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700250 * Clears the internal state.
251 */
252 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700253 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700254 lastEvents.clear();
255 }
256 }
257
258 /**
259 * Registers the metrics.
260 */
261 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700262 topologyDeviceEventMetric =
263 new EventMetric(metricsService, COMPONENT_NAME,
264 FEATURE_DEVICE_NAME);
265 topologyHostEventMetric =
266 new EventMetric(metricsService, COMPONENT_NAME,
267 FEATURE_HOST_NAME);
268 topologyLinkEventMetric =
269 new EventMetric(metricsService, COMPONENT_NAME,
270 FEATURE_LINK_NAME);
271 topologyGraphEventMetric =
272 new EventMetric(metricsService, COMPONENT_NAME,
273 FEATURE_GRAPH_NAME);
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700274 topologyGraphReasonsEventMetric =
275 new EventMetric(metricsService, COMPONENT_NAME,
276 FEATURE_GRAPH_REASONS_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700277
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700278 topologyDeviceEventMetric.registerMetrics();
279 topologyHostEventMetric.registerMetrics();
280 topologyLinkEventMetric.registerMetrics();
281 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700282 topologyGraphReasonsEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700283 }
284
285 /**
286 * Removes the metrics.
287 */
288 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700289 topologyDeviceEventMetric.removeMetrics();
290 topologyHostEventMetric.removeMetrics();
291 topologyLinkEventMetric.removeMetrics();
292 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700293 topologyGraphReasonsEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700294 }
295}