blob: fa05dabc23fff3e492d5851eba0aa117afe2ccbe [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 */
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070016package org.onlab.onos.metrics.topology;
17
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;
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -080032import org.onlab.onos.core.ApplicationId;
33import org.onlab.onos.core.CoreService;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070034import org.onlab.onos.event.Event;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070035import org.onlab.onos.net.device.DeviceEvent;
36import org.onlab.onos.net.device.DeviceListener;
37import org.onlab.onos.net.device.DeviceService;
38import org.onlab.onos.net.host.HostEvent;
39import org.onlab.onos.net.host.HostListener;
40import org.onlab.onos.net.host.HostService;
41import org.onlab.onos.net.link.LinkEvent;
42import org.onlab.onos.net.link.LinkListener;
43import org.onlab.onos.net.link.LinkService;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070044import org.onlab.onos.net.topology.TopologyEvent;
45import org.onlab.onos.net.topology.TopologyListener;
46import org.onlab.onos.net.topology.TopologyService;
47import 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 Radoslavov64d9e472014-10-21 22:01:08 -070094 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070095 // Event metrics:
96 // - Device events
97 // - Host events
98 // - Link events
99 // - Topology Graph 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 Radoslavov64d9e472014-10-21 22:01:08 -0700105
106 @Activate
107 protected void activate() {
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800108 appId =
109 coreService.registerApplication("org.onlab.onos.metrics.topology");
110
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) {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700139 return ImmutableList.<Event>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 Radoslavov5ba8b282014-10-23 01:03:10 -0700163 /**
164 * Records an event.
165 *
166 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700167 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700168 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700169 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700170 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700171 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700172
173 //
174 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
175 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700176 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
177 lastEvents.remove();
178 }
179 lastEvents.add(event);
180 }
181 }
182
183 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700184 * Inner Device Event Listener class.
185 */
186 private class InnerDeviceListener implements DeviceListener {
187 @Override
188 public void event(DeviceEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700189 recordEvent(event, topologyDeviceEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700190 log.debug("Device Event: time = {} type = {} event = {}",
191 event.time(), event.type(), event);
192 }
193 }
194
195 /**
196 * Inner Host Event Listener class.
197 */
198 private class InnerHostListener implements HostListener {
199 @Override
200 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700201 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700202 log.debug("Host Event: time = {} type = {} event = {}",
203 event.time(), event.type(), event);
204 }
205 }
206
207 /**
208 * Inner Link Event Listener class.
209 */
210 private class InnerLinkListener implements LinkListener {
211 @Override
212 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700213 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700214 log.debug("Link Event: time = {} type = {} event = {}",
215 event.time(), event.type(), event);
216 }
217 }
218
219 /**
220 * Inner Topology Event Listener class.
221 */
222 private class InnerTopologyListener implements TopologyListener {
223 @Override
224 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700225 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700226 log.debug("Topology Event: time = {} type = {} event = {}",
227 event.time(), event.type(), event);
228 for (Event reason : event.reasons()) {
229 log.debug("Topology Event Reason: time = {} type = {} event = {}",
230 reason.time(), reason.type(), reason);
231 }
232 }
233 }
234
235 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700236 * Clears the internal state.
237 */
238 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700239 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700240 lastEvents.clear();
241 }
242 }
243
244 /**
245 * Registers the metrics.
246 */
247 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700248 topologyDeviceEventMetric =
249 new EventMetric(metricsService, COMPONENT_NAME,
250 FEATURE_DEVICE_NAME);
251 topologyHostEventMetric =
252 new EventMetric(metricsService, COMPONENT_NAME,
253 FEATURE_HOST_NAME);
254 topologyLinkEventMetric =
255 new EventMetric(metricsService, COMPONENT_NAME,
256 FEATURE_LINK_NAME);
257 topologyGraphEventMetric =
258 new EventMetric(metricsService, COMPONENT_NAME,
259 FEATURE_GRAPH_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700260
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700261 topologyDeviceEventMetric.registerMetrics();
262 topologyHostEventMetric.registerMetrics();
263 topologyLinkEventMetric.registerMetrics();
264 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700265 }
266
267 /**
268 * Removes the metrics.
269 */
270 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700271 topologyDeviceEventMetric.removeMetrics();
272 topologyHostEventMetric.removeMetrics();
273 topologyLinkEventMetric.removeMetrics();
274 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700275 }
276}