blob: fcd9f810b65affceb35d3f51cceeae4818fb6c38 [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;
32import org.onlab.onos.event.Event;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070033import org.onlab.onos.net.device.DeviceEvent;
34import org.onlab.onos.net.device.DeviceListener;
35import org.onlab.onos.net.device.DeviceService;
36import org.onlab.onos.net.host.HostEvent;
37import org.onlab.onos.net.host.HostListener;
38import org.onlab.onos.net.host.HostService;
39import org.onlab.onos.net.link.LinkEvent;
40import org.onlab.onos.net.link.LinkListener;
41import org.onlab.onos.net.link.LinkService;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070042import org.onlab.onos.net.topology.TopologyEvent;
43import org.onlab.onos.net.topology.TopologyListener;
44import org.onlab.onos.net.topology.TopologyService;
45import org.slf4j.Logger;
46
47/**
48 * ONOS Topology Metrics Application that collects topology-related metrics.
49 */
50@Component(immediate = true)
51@Service
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
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070056 protected DeviceService deviceService;
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected HostService hostService;
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected LinkService linkService;
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070062 protected TopologyService topologyService;
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070063 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected MetricsService metricsService;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070065
66 private LinkedList<Event> lastEvents = new LinkedList<>();
67 private static final int LAST_EVENTS_MAX_N = 100;
68
69 private final DeviceListener deviceListener = new InnerDeviceListener();
70 private final HostListener hostListener = new InnerHostListener();
71 private final LinkListener linkListener = new InnerLinkListener();
72 private final TopologyListener topologyListener =
73 new InnerTopologyListener();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070074
75 //
76 // Metrics
77 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070078 private static final String COMPONENT_NAME = "Topology";
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070079 private static final String FEATURE_DEVICE_NAME = "DeviceEvent";
80 private static final String FEATURE_HOST_NAME = "HostEvent";
81 private static final String FEATURE_LINK_NAME = "LinkEvent";
82 private static final String FEATURE_GRAPH_NAME = "GraphEvent";
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070083 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070084 // Event metrics:
85 // - Device events
86 // - Host events
87 // - Link events
88 // - Topology Graph events
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070089 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070090 private EventMetric topologyDeviceEventMetric;
91 private EventMetric topologyHostEventMetric;
92 private EventMetric topologyLinkEventMetric;
93 private EventMetric topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070094
95 @Activate
96 protected void activate() {
97 clear();
98 registerMetrics();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070099
100 // Register for all topology-related events
101 deviceService.addListener(deviceListener);
102 hostService.addListener(hostListener);
103 linkService.addListener(linkListener);
104 topologyService.addListener(topologyListener);
105
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700106 log.info("ONOS Topology Metrics started.");
107 }
108
109 @Deactivate
110 public void deactivate() {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700111 // De-register from all topology-related events
112 deviceService.removeListener(deviceListener);
113 hostService.removeListener(hostListener);
114 linkService.removeListener(linkListener);
115 topologyService.removeListener(topologyListener);
116
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700117 removeMetrics();
118 clear();
119 log.info("ONOS Topology Metrics stopped.");
120 }
121
122 @Override
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700123 public List<Event> getEvents() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700124 synchronized (lastEvents) {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700125 return ImmutableList.<Event>copyOf(lastEvents);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700126 }
127 }
128
129 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700130 public EventMetric topologyDeviceEventMetric() {
131 return topologyDeviceEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700132 }
133
134 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700135 public EventMetric topologyHostEventMetric() {
136 return topologyHostEventMetric;
137 }
138
139 @Override
140 public EventMetric topologyLinkEventMetric() {
141 return topologyLinkEventMetric;
142 }
143
144 @Override
145 public EventMetric topologyGraphEventMetric() {
146 return topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700147 }
148
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700149 /**
150 * Records an event.
151 *
152 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700153 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700154 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700155 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700156 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700157 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700158
159 //
160 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
161 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700162 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
163 lastEvents.remove();
164 }
165 lastEvents.add(event);
166 }
167 }
168
169 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700170 * Inner Device Event Listener class.
171 */
172 private class InnerDeviceListener implements DeviceListener {
173 @Override
174 public void event(DeviceEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700175 recordEvent(event, topologyDeviceEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700176 log.debug("Device Event: time = {} type = {} event = {}",
177 event.time(), event.type(), event);
178 }
179 }
180
181 /**
182 * Inner Host Event Listener class.
183 */
184 private class InnerHostListener implements HostListener {
185 @Override
186 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700187 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700188 log.debug("Host Event: time = {} type = {} event = {}",
189 event.time(), event.type(), event);
190 }
191 }
192
193 /**
194 * Inner Link Event Listener class.
195 */
196 private class InnerLinkListener implements LinkListener {
197 @Override
198 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700199 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700200 log.debug("Link Event: time = {} type = {} event = {}",
201 event.time(), event.type(), event);
202 }
203 }
204
205 /**
206 * Inner Topology Event Listener class.
207 */
208 private class InnerTopologyListener implements TopologyListener {
209 @Override
210 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700211 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700212 log.debug("Topology Event: time = {} type = {} event = {}",
213 event.time(), event.type(), event);
214 for (Event reason : event.reasons()) {
215 log.debug("Topology Event Reason: time = {} type = {} event = {}",
216 reason.time(), reason.type(), reason);
217 }
218 }
219 }
220
221 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700222 * Clears the internal state.
223 */
224 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700225 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700226 lastEvents.clear();
227 }
228 }
229
230 /**
231 * Registers the metrics.
232 */
233 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700234 topologyDeviceEventMetric =
235 new EventMetric(metricsService, COMPONENT_NAME,
236 FEATURE_DEVICE_NAME);
237 topologyHostEventMetric =
238 new EventMetric(metricsService, COMPONENT_NAME,
239 FEATURE_HOST_NAME);
240 topologyLinkEventMetric =
241 new EventMetric(metricsService, COMPONENT_NAME,
242 FEATURE_LINK_NAME);
243 topologyGraphEventMetric =
244 new EventMetric(metricsService, COMPONENT_NAME,
245 FEATURE_GRAPH_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700246
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700247 topologyDeviceEventMetric.registerMetrics();
248 topologyHostEventMetric.registerMetrics();
249 topologyLinkEventMetric.registerMetrics();
250 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700251 }
252
253 /**
254 * Removes the metrics.
255 */
256 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700257 topologyDeviceEventMetric.removeMetrics();
258 topologyHostEventMetric.removeMetrics();
259 topologyLinkEventMetric.removeMetrics();
260 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700261 }
262}