blob: 8f6674f80781e80b12254fb200d831d7e3a3cb65 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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) {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700141 return ImmutableList.<Event>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) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700196 recordEvent(event, topologyDeviceEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700197 log.debug("Device Event: time = {} type = {} event = {}",
198 event.time(), event.type(), event);
199 }
200 }
201
202 /**
203 * Inner Host Event Listener class.
204 */
205 private class InnerHostListener implements HostListener {
206 @Override
207 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700208 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700209 log.debug("Host Event: time = {} type = {} event = {}",
210 event.time(), event.type(), event);
211 }
212 }
213
214 /**
215 * Inner Link Event Listener class.
216 */
217 private class InnerLinkListener implements LinkListener {
218 @Override
219 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700220 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700221 log.debug("Link Event: time = {} type = {} event = {}",
222 event.time(), event.type(), event);
223 }
224 }
225
226 /**
227 * Inner Topology Event Listener class.
228 */
229 private class InnerTopologyListener implements TopologyListener {
230 @Override
231 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700232 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700233 log.debug("Topology Event: time = {} type = {} event = {}",
234 event.time(), event.type(), event);
235 for (Event reason : event.reasons()) {
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700236 recordEvent(event, topologyGraphReasonsEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700237 log.debug("Topology Event Reason: time = {} type = {} event = {}",
238 reason.time(), reason.type(), reason);
239 }
240 }
241 }
242
243 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700244 * Clears the internal state.
245 */
246 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700247 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700248 lastEvents.clear();
249 }
250 }
251
252 /**
253 * Registers the metrics.
254 */
255 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700256 topologyDeviceEventMetric =
257 new EventMetric(metricsService, COMPONENT_NAME,
258 FEATURE_DEVICE_NAME);
259 topologyHostEventMetric =
260 new EventMetric(metricsService, COMPONENT_NAME,
261 FEATURE_HOST_NAME);
262 topologyLinkEventMetric =
263 new EventMetric(metricsService, COMPONENT_NAME,
264 FEATURE_LINK_NAME);
265 topologyGraphEventMetric =
266 new EventMetric(metricsService, COMPONENT_NAME,
267 FEATURE_GRAPH_NAME);
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700268 topologyGraphReasonsEventMetric =
269 new EventMetric(metricsService, COMPONENT_NAME,
270 FEATURE_GRAPH_REASONS_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700271
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700272 topologyDeviceEventMetric.registerMetrics();
273 topologyHostEventMetric.registerMetrics();
274 topologyLinkEventMetric.registerMetrics();
275 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700276 topologyGraphReasonsEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700277 }
278
279 /**
280 * Removes the metrics.
281 */
282 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700283 topologyDeviceEventMetric.removeMetrics();
284 topologyHostEventMetric.removeMetrics();
285 topologyLinkEventMetric.removeMetrics();
286 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700287 topologyGraphReasonsEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700288 }
289}