blob: a2f0d5c5c963aac08944fcc9fff3f17aa7312ff2 [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 */
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() {
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800111 appId =
Brian O'Connorabafb502014-12-02 22:26:20 -0800112 coreService.registerApplication("org.onosproject.metrics.topology");
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800113
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700114 clear();
115 registerMetrics();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700116
117 // Register for all topology-related events
118 deviceService.addListener(deviceListener);
119 hostService.addListener(hostListener);
120 linkService.addListener(linkListener);
121 topologyService.addListener(topologyListener);
122
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800123 log.info("Started with Application ID {}", appId.id());
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700124 }
125
126 @Deactivate
127 public void deactivate() {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700128 // De-register from all topology-related events
129 deviceService.removeListener(deviceListener);
130 hostService.removeListener(hostListener);
131 linkService.removeListener(linkListener);
132 topologyService.removeListener(topologyListener);
133
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700134 removeMetrics();
135 clear();
Pavlin Radoslavov3a46e482014-11-06 15:57:06 -0800136 log.info("Stopped");
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700137 }
138
139 @Override
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700140 public List<Event> getEvents() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700141 synchronized (lastEvents) {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700142 return ImmutableList.<Event>copyOf(lastEvents);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700143 }
144 }
145
146 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700147 public EventMetric topologyDeviceEventMetric() {
148 return topologyDeviceEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700149 }
150
151 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700152 public EventMetric topologyHostEventMetric() {
153 return topologyHostEventMetric;
154 }
155
156 @Override
157 public EventMetric topologyLinkEventMetric() {
158 return topologyLinkEventMetric;
159 }
160
161 @Override
162 public EventMetric topologyGraphEventMetric() {
163 return topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700164 }
165
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700166 @Override
167 public EventMetric topologyGraphReasonsEventMetric() {
168 return topologyGraphReasonsEventMetric;
169 }
170
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700171 /**
172 * Records an event.
173 *
174 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700175 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700176 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700177 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700178 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700179 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700180
181 //
182 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
183 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700184 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
185 lastEvents.remove();
186 }
187 lastEvents.add(event);
188 }
189 }
190
191 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700192 * Inner Device Event Listener class.
193 */
194 private class InnerDeviceListener implements DeviceListener {
195 @Override
196 public void event(DeviceEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700197 recordEvent(event, topologyDeviceEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700198 log.debug("Device Event: time = {} type = {} event = {}",
199 event.time(), event.type(), event);
200 }
201 }
202
203 /**
204 * Inner Host Event Listener class.
205 */
206 private class InnerHostListener implements HostListener {
207 @Override
208 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700209 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700210 log.debug("Host Event: time = {} type = {} event = {}",
211 event.time(), event.type(), event);
212 }
213 }
214
215 /**
216 * Inner Link Event Listener class.
217 */
218 private class InnerLinkListener implements LinkListener {
219 @Override
220 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700221 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700222 log.debug("Link Event: time = {} type = {} event = {}",
223 event.time(), event.type(), event);
224 }
225 }
226
227 /**
228 * Inner Topology Event Listener class.
229 */
230 private class InnerTopologyListener implements TopologyListener {
231 @Override
232 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700233 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700234 log.debug("Topology Event: time = {} type = {} event = {}",
235 event.time(), event.type(), event);
236 for (Event reason : event.reasons()) {
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700237 recordEvent(event, topologyGraphReasonsEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700238 log.debug("Topology Event Reason: time = {} type = {} event = {}",
239 reason.time(), reason.type(), reason);
240 }
241 }
242 }
243
244 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700245 * Clears the internal state.
246 */
247 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700248 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700249 lastEvents.clear();
250 }
251 }
252
253 /**
254 * Registers the metrics.
255 */
256 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700257 topologyDeviceEventMetric =
258 new EventMetric(metricsService, COMPONENT_NAME,
259 FEATURE_DEVICE_NAME);
260 topologyHostEventMetric =
261 new EventMetric(metricsService, COMPONENT_NAME,
262 FEATURE_HOST_NAME);
263 topologyLinkEventMetric =
264 new EventMetric(metricsService, COMPONENT_NAME,
265 FEATURE_LINK_NAME);
266 topologyGraphEventMetric =
267 new EventMetric(metricsService, COMPONENT_NAME,
268 FEATURE_GRAPH_NAME);
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700269 topologyGraphReasonsEventMetric =
270 new EventMetric(metricsService, COMPONENT_NAME,
271 FEATURE_GRAPH_REASONS_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700272
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700273 topologyDeviceEventMetric.registerMetrics();
274 topologyHostEventMetric.registerMetrics();
275 topologyLinkEventMetric.registerMetrics();
276 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700277 topologyGraphReasonsEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700278 }
279
280 /**
281 * Removes the metrics.
282 */
283 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700284 topologyDeviceEventMetric.removeMetrics();
285 topologyHostEventMetric.removeMetrics();
286 topologyLinkEventMetric.removeMetrics();
287 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov6aaa1e02015-03-18 11:12:06 -0700288 topologyGraphReasonsEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700289 }
290}