blob: 77d8d5ecd0126a89d9f0442b479f8a6dad4cd917 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070018import com.google.common.collect.ImmutableList;
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070019import org.onlab.metrics.EventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070020import org.onlab.metrics.MetricsService;
Brian O'Connorabafb502014-12-02 22:26:20 -080021import org.onosproject.core.ApplicationId;
22import org.onosproject.core.CoreService;
23import org.onosproject.event.Event;
24import org.onosproject.net.device.DeviceEvent;
25import org.onosproject.net.device.DeviceListener;
26import org.onosproject.net.device.DeviceService;
27import org.onosproject.net.host.HostEvent;
28import org.onosproject.net.host.HostListener;
29import org.onosproject.net.host.HostService;
30import org.onosproject.net.link.LinkEvent;
31import org.onosproject.net.link.LinkListener;
32import org.onosproject.net.link.LinkService;
33import org.onosproject.net.topology.TopologyEvent;
34import org.onosproject.net.topology.TopologyListener;
35import org.onosproject.net.topology.TopologyService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070036import org.osgi.service.component.annotations.Activate;
37import org.osgi.service.component.annotations.Component;
38import org.osgi.service.component.annotations.Deactivate;
39import org.osgi.service.component.annotations.Reference;
40import org.osgi.service.component.annotations.ReferenceCardinality;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070041import org.slf4j.Logger;
42
Ray Milkeyd84f89b2018-08-17 14:54:17 -070043import java.util.LinkedList;
44import java.util.List;
45
46import static org.slf4j.LoggerFactory.getLogger;
47
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070048/**
49 * ONOS Topology Metrics Application that collects topology-related metrics.
50 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070051@Component(immediate = true, service = TopologyMetricsService.class)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070052public class TopologyMetrics implements TopologyMetricsService {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070053 private static final Logger log = getLogger(TopologyMetrics.class);
54
Ray Milkeyd84f89b2018-08-17 14:54:17 -070055 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080056 protected CoreService coreService;
57
Ray Milkeyd84f89b2018-08-17 14:54:17 -070058 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070059 protected DeviceService deviceService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080060
Ray Milkeyd84f89b2018-08-17 14:54:17 -070061 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070062 protected HostService hostService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080063
Ray Milkeyd84f89b2018-08-17 14:54:17 -070064 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070065 protected LinkService linkService;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080066
Ray Milkeyd84f89b2018-08-17 14:54:17 -070067 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070068 protected MetricsService metricsService;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070069
Ray Milkeyd84f89b2018-08-17 14:54:17 -070070 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080071 protected TopologyService topologyService;
72
73 private ApplicationId appId;
74
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070075 private LinkedList<Event> lastEvents = new LinkedList<>();
76 private static final int LAST_EVENTS_MAX_N = 100;
77
78 private final DeviceListener deviceListener = new InnerDeviceListener();
79 private final HostListener hostListener = new InnerHostListener();
80 private final LinkListener linkListener = new InnerLinkListener();
81 private final TopologyListener topologyListener =
82 new InnerTopologyListener();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070083
84 //
85 // Metrics
86 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070087 private static final String COMPONENT_NAME = "Topology";
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070088 private static final String FEATURE_DEVICE_NAME = "DeviceEvent";
89 private static final String FEATURE_HOST_NAME = "HostEvent";
90 private static final String FEATURE_LINK_NAME = "LinkEvent";
91 private static final String FEATURE_GRAPH_NAME = "GraphEvent";
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -070092 private static final String FEATURE_GRAPH_REASONS_NAME = "GraphReasonsEvent";
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070093 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070094 // Event metrics:
95 // - Device events
96 // - Host events
97 // - Link events
98 // - Topology Graph events
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -070099 // - Topology Graph Reasons events
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700100 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700101 private EventMetric topologyDeviceEventMetric;
102 private EventMetric topologyHostEventMetric;
103 private EventMetric topologyLinkEventMetric;
104 private EventMetric topologyGraphEventMetric;
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700105 private EventMetric topologyGraphReasonsEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700106
107 @Activate
108 protected void activate() {
Thomas Vachuskafba28572015-03-25 18:48:59 -0700109 appId = coreService.registerApplication("org.onosproject.metrics");
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800110
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700111 clear();
112 registerMetrics();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700113
114 // Register for all topology-related events
115 deviceService.addListener(deviceListener);
116 hostService.addListener(hostListener);
117 linkService.addListener(linkListener);
118 topologyService.addListener(topologyListener);
119
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800120 log.info("Started with Application ID {}", appId.id());
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700121 }
122
123 @Deactivate
124 public void deactivate() {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700125 // De-register from all topology-related events
126 deviceService.removeListener(deviceListener);
127 hostService.removeListener(hostListener);
128 linkService.removeListener(linkListener);
129 topologyService.removeListener(topologyListener);
130
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700131 removeMetrics();
132 clear();
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800133 log.info("Stopped");
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700134 }
135
136 @Override
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700137 public List<Event> getEvents() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700138 synchronized (lastEvents) {
Sho SHIMIZUfd0933b2015-09-11 15:17:48 -0700139 return ImmutableList.copyOf(lastEvents);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700140 }
141 }
142
143 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700144 public EventMetric topologyDeviceEventMetric() {
145 return topologyDeviceEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700146 }
147
148 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700149 public EventMetric topologyHostEventMetric() {
150 return topologyHostEventMetric;
151 }
152
153 @Override
154 public EventMetric topologyLinkEventMetric() {
155 return topologyLinkEventMetric;
156 }
157
158 @Override
159 public EventMetric topologyGraphEventMetric() {
160 return topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700161 }
162
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700163 @Override
164 public EventMetric topologyGraphReasonsEventMetric() {
165 return topologyGraphReasonsEventMetric;
166 }
167
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700168 /**
169 * Records an event.
170 *
171 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700172 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700173 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700174 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700175 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700176 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700177
178 //
179 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
180 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700181 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
182 lastEvents.remove();
183 }
184 lastEvents.add(event);
185 }
186 }
187
188 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700189 * Inner Device Event Listener class.
190 */
191 private class InnerDeviceListener implements DeviceListener {
192 @Override
193 public void event(DeviceEvent event) {
andrew@onlab.us88d22822015-04-23 18:07:17 -0400194 // Ignore PORT_STATS_UPDATED probe event from interfering with
195 // other device event timestamps
196 if (event.type() == DeviceEvent.Type.PORT_STATS_UPDATED) {
HIGUCHI Yutaaa4196f2015-10-15 11:54:43 -0700197 log.debug("PORT_STATS_UPDATED event ignored from metrics");
andrew@onlab.us88d22822015-04-23 18:07:17 -0400198 } else {
199 recordEvent(event, topologyDeviceEventMetric);
HIGUCHI Yutaaa4196f2015-10-15 11:54:43 -0700200 log.debug("Device Event: time = {} type = {} event = {}",
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700201 event.time(), event.type(), event);
andrew@onlab.us88d22822015-04-23 18:07:17 -0400202 }
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700203 }
204 }
205
206 /**
207 * Inner Host Event Listener class.
208 */
209 private class InnerHostListener implements HostListener {
210 @Override
211 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700212 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700213 log.debug("Host Event: time = {} type = {} event = {}",
214 event.time(), event.type(), event);
215 }
216 }
217
218 /**
219 * Inner Link Event Listener class.
220 */
221 private class InnerLinkListener implements LinkListener {
222 @Override
223 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700224 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700225 log.debug("Link Event: time = {} type = {} event = {}",
226 event.time(), event.type(), event);
227 }
228 }
229
230 /**
231 * Inner Topology Event Listener class.
232 */
233 private class InnerTopologyListener implements TopologyListener {
234 @Override
235 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700236 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700237 log.debug("Topology Event: time = {} type = {} event = {}",
238 event.time(), event.type(), event);
239 for (Event reason : event.reasons()) {
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700240 recordEvent(event, topologyGraphReasonsEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700241 log.debug("Topology Event Reason: time = {} type = {} event = {}",
242 reason.time(), reason.type(), reason);
243 }
244 }
245 }
246
247 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700248 * Clears the internal state.
249 */
250 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700251 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700252 lastEvents.clear();
253 }
254 }
255
256 /**
257 * Registers the metrics.
258 */
259 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700260 topologyDeviceEventMetric =
261 new EventMetric(metricsService, COMPONENT_NAME,
262 FEATURE_DEVICE_NAME);
263 topologyHostEventMetric =
264 new EventMetric(metricsService, COMPONENT_NAME,
265 FEATURE_HOST_NAME);
266 topologyLinkEventMetric =
267 new EventMetric(metricsService, COMPONENT_NAME,
268 FEATURE_LINK_NAME);
269 topologyGraphEventMetric =
270 new EventMetric(metricsService, COMPONENT_NAME,
271 FEATURE_GRAPH_NAME);
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700272 topologyGraphReasonsEventMetric =
273 new EventMetric(metricsService, COMPONENT_NAME,
274 FEATURE_GRAPH_REASONS_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700275
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700276 topologyDeviceEventMetric.registerMetrics();
277 topologyHostEventMetric.registerMetrics();
278 topologyLinkEventMetric.registerMetrics();
279 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700280 topologyGraphReasonsEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700281 }
282
283 /**
284 * Removes the metrics.
285 */
286 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700287 topologyDeviceEventMetric.removeMetrics();
288 topologyHostEventMetric.removeMetrics();
289 topologyLinkEventMetric.removeMetrics();
290 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700291 topologyGraphReasonsEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700292 }
293}