blob: b590f200c3222cf1debba4ce464dcb061fa158cb [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070019package org.onlab.onos.metrics.topology;
20
21import static org.slf4j.LoggerFactory.getLogger;
22
23import java.util.LinkedList;
24import java.util.List;
25
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070026import com.google.common.collect.ImmutableList;
27import org.apache.felix.scr.annotations.Activate;
28import org.apache.felix.scr.annotations.Component;
29import org.apache.felix.scr.annotations.Deactivate;
30import org.apache.felix.scr.annotations.Reference;
31import org.apache.felix.scr.annotations.ReferenceCardinality;
32import org.apache.felix.scr.annotations.Service;
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070033import org.onlab.metrics.EventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070034import org.onlab.metrics.MetricsService;
35import org.onlab.onos.event.Event;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070036import org.onlab.onos.net.device.DeviceEvent;
37import org.onlab.onos.net.device.DeviceListener;
38import org.onlab.onos.net.device.DeviceService;
39import org.onlab.onos.net.host.HostEvent;
40import org.onlab.onos.net.host.HostListener;
41import org.onlab.onos.net.host.HostService;
42import org.onlab.onos.net.link.LinkEvent;
43import org.onlab.onos.net.link.LinkListener;
44import org.onlab.onos.net.link.LinkService;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070045import org.onlab.onos.net.topology.TopologyEvent;
46import org.onlab.onos.net.topology.TopologyListener;
47import org.onlab.onos.net.topology.TopologyService;
48import org.slf4j.Logger;
49
50/**
51 * ONOS Topology Metrics Application that collects topology-related metrics.
52 */
53@Component(immediate = true)
54@Service
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070055public class TopologyMetrics implements TopologyMetricsService {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070056 private static final Logger log = getLogger(TopologyMetrics.class);
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070059 protected DeviceService deviceService;
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected HostService hostService;
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected LinkService linkService;
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070065 protected TopologyService topologyService;
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070066 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected MetricsService metricsService;
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -070068
69 private LinkedList<Event> lastEvents = new LinkedList<>();
70 private static final int LAST_EVENTS_MAX_N = 100;
71
72 private final DeviceListener deviceListener = new InnerDeviceListener();
73 private final HostListener hostListener = new InnerHostListener();
74 private final LinkListener linkListener = new InnerLinkListener();
75 private final TopologyListener topologyListener =
76 new InnerTopologyListener();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070077
78 //
79 // Metrics
80 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070081 private static final String COMPONENT_NAME = "Topology";
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070082 private static final String FEATURE_DEVICE_NAME = "DeviceEvent";
83 private static final String FEATURE_HOST_NAME = "HostEvent";
84 private static final String FEATURE_LINK_NAME = "LinkEvent";
85 private static final String FEATURE_GRAPH_NAME = "GraphEvent";
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070086 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070087 // Event metrics:
88 // - Device events
89 // - Host events
90 // - Link events
91 // - Topology Graph events
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070092 //
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -070093 private EventMetric topologyDeviceEventMetric;
94 private EventMetric topologyHostEventMetric;
95 private EventMetric topologyLinkEventMetric;
96 private EventMetric topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -070097
98 @Activate
99 protected void activate() {
100 clear();
101 registerMetrics();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700102
103 // Register for all topology-related events
104 deviceService.addListener(deviceListener);
105 hostService.addListener(hostListener);
106 linkService.addListener(linkListener);
107 topologyService.addListener(topologyListener);
108
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700109 log.info("ONOS Topology Metrics started.");
110 }
111
112 @Deactivate
113 public void deactivate() {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700114 // De-register from all topology-related events
115 deviceService.removeListener(deviceListener);
116 hostService.removeListener(hostListener);
117 linkService.removeListener(linkListener);
118 topologyService.removeListener(topologyListener);
119
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700120 removeMetrics();
121 clear();
122 log.info("ONOS Topology Metrics stopped.");
123 }
124
125 @Override
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700126 public List<Event> getEvents() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700127 synchronized (lastEvents) {
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700128 return ImmutableList.<Event>copyOf(lastEvents);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700129 }
130 }
131
132 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700133 public EventMetric topologyDeviceEventMetric() {
134 return topologyDeviceEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700135 }
136
137 @Override
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700138 public EventMetric topologyHostEventMetric() {
139 return topologyHostEventMetric;
140 }
141
142 @Override
143 public EventMetric topologyLinkEventMetric() {
144 return topologyLinkEventMetric;
145 }
146
147 @Override
148 public EventMetric topologyGraphEventMetric() {
149 return topologyGraphEventMetric;
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700150 }
151
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700152 /**
153 * Records an event.
154 *
155 * @param event the event to record
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700156 * @param eventMetric the Event Metric to use
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700157 */
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700158 private void recordEvent(Event event, EventMetric eventMetric) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700159 synchronized (lastEvents) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700160 eventMetric.eventReceived();
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700161
162 //
163 // Keep only the last N events, where N = LAST_EVENTS_MAX_N
164 //
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700165 while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
166 lastEvents.remove();
167 }
168 lastEvents.add(event);
169 }
170 }
171
172 /**
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700173 * Inner Device Event Listener class.
174 */
175 private class InnerDeviceListener implements DeviceListener {
176 @Override
177 public void event(DeviceEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700178 recordEvent(event, topologyDeviceEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700179 log.debug("Device Event: time = {} type = {} event = {}",
180 event.time(), event.type(), event);
181 }
182 }
183
184 /**
185 * Inner Host Event Listener class.
186 */
187 private class InnerHostListener implements HostListener {
188 @Override
189 public void event(HostEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700190 recordEvent(event, topologyHostEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700191 log.debug("Host Event: time = {} type = {} event = {}",
192 event.time(), event.type(), event);
193 }
194 }
195
196 /**
197 * Inner Link Event Listener class.
198 */
199 private class InnerLinkListener implements LinkListener {
200 @Override
201 public void event(LinkEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700202 recordEvent(event, topologyLinkEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700203 log.debug("Link Event: time = {} type = {} event = {}",
204 event.time(), event.type(), event);
205 }
206 }
207
208 /**
209 * Inner Topology Event Listener class.
210 */
211 private class InnerTopologyListener implements TopologyListener {
212 @Override
213 public void event(TopologyEvent event) {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700214 recordEvent(event, topologyGraphEventMetric);
Pavlin Radoslavov5ba8b282014-10-23 01:03:10 -0700215 log.debug("Topology Event: time = {} type = {} event = {}",
216 event.time(), event.type(), event);
217 for (Event reason : event.reasons()) {
218 log.debug("Topology Event Reason: time = {} type = {} event = {}",
219 reason.time(), reason.type(), reason);
220 }
221 }
222 }
223
224 /**
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700225 * Clears the internal state.
226 */
227 private void clear() {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700228 synchronized (lastEvents) {
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700229 lastEvents.clear();
230 }
231 }
232
233 /**
234 * Registers the metrics.
235 */
236 private void registerMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700237 topologyDeviceEventMetric =
238 new EventMetric(metricsService, COMPONENT_NAME,
239 FEATURE_DEVICE_NAME);
240 topologyHostEventMetric =
241 new EventMetric(metricsService, COMPONENT_NAME,
242 FEATURE_HOST_NAME);
243 topologyLinkEventMetric =
244 new EventMetric(metricsService, COMPONENT_NAME,
245 FEATURE_LINK_NAME);
246 topologyGraphEventMetric =
247 new EventMetric(metricsService, COMPONENT_NAME,
248 FEATURE_GRAPH_NAME);
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700249
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700250 topologyDeviceEventMetric.registerMetrics();
251 topologyHostEventMetric.registerMetrics();
252 topologyLinkEventMetric.registerMetrics();
253 topologyGraphEventMetric.registerMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700254 }
255
256 /**
257 * Removes the metrics.
258 */
259 private void removeMetrics() {
Pavlin Radoslavovccc2e332014-10-23 13:46:28 -0700260 topologyDeviceEventMetric.removeMetrics();
261 topologyHostEventMetric.removeMetrics();
262 topologyLinkEventMetric.removeMetrics();
263 topologyGraphEventMetric.removeMetrics();
Pavlin Radoslavov64d9e472014-10-21 22:01:08 -0700264 }
265}