blob: 8f6674f80781e80b12254fb200d831d7e3a3cb65 [file] [log] [blame]
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.metrics.topology;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.LinkedList;
import java.util.List;
import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.metrics.EventMetric;
import org.onlab.metrics.MetricsService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.Event;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;
/**
* ONOS Topology Metrics Application that collects topology-related metrics.
*/
@Component(immediate = true)
@Service
public class TopologyMetrics implements TopologyMetricsService {
private static final Logger log = getLogger(TopologyMetrics.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LinkService linkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MetricsService metricsService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
private ApplicationId appId;
private LinkedList<Event> lastEvents = new LinkedList<>();
private static final int LAST_EVENTS_MAX_N = 100;
private final DeviceListener deviceListener = new InnerDeviceListener();
private final HostListener hostListener = new InnerHostListener();
private final LinkListener linkListener = new InnerLinkListener();
private final TopologyListener topologyListener =
new InnerTopologyListener();
//
// Metrics
//
private static final String COMPONENT_NAME = "Topology";
private static final String FEATURE_DEVICE_NAME = "DeviceEvent";
private static final String FEATURE_HOST_NAME = "HostEvent";
private static final String FEATURE_LINK_NAME = "LinkEvent";
private static final String FEATURE_GRAPH_NAME = "GraphEvent";
private static final String FEATURE_GRAPH_REASONS_NAME = "GraphReasonsEvent";
//
// Event metrics:
// - Device events
// - Host events
// - Link events
// - Topology Graph events
// - Topology Graph Reasons events
//
private EventMetric topologyDeviceEventMetric;
private EventMetric topologyHostEventMetric;
private EventMetric topologyLinkEventMetric;
private EventMetric topologyGraphEventMetric;
private EventMetric topologyGraphReasonsEventMetric;
@Activate
protected void activate() {
appId = coreService.registerApplication("org.onosproject.metrics");
clear();
registerMetrics();
// Register for all topology-related events
deviceService.addListener(deviceListener);
hostService.addListener(hostListener);
linkService.addListener(linkListener);
topologyService.addListener(topologyListener);
log.info("Started with Application ID {}", appId.id());
}
@Deactivate
public void deactivate() {
// De-register from all topology-related events
deviceService.removeListener(deviceListener);
hostService.removeListener(hostListener);
linkService.removeListener(linkListener);
topologyService.removeListener(topologyListener);
removeMetrics();
clear();
log.info("Stopped");
}
@Override
public List<Event> getEvents() {
synchronized (lastEvents) {
return ImmutableList.<Event>copyOf(lastEvents);
}
}
@Override
public EventMetric topologyDeviceEventMetric() {
return topologyDeviceEventMetric;
}
@Override
public EventMetric topologyHostEventMetric() {
return topologyHostEventMetric;
}
@Override
public EventMetric topologyLinkEventMetric() {
return topologyLinkEventMetric;
}
@Override
public EventMetric topologyGraphEventMetric() {
return topologyGraphEventMetric;
}
@Override
public EventMetric topologyGraphReasonsEventMetric() {
return topologyGraphReasonsEventMetric;
}
/**
* Records an event.
*
* @param event the event to record
* @param eventMetric the Event Metric to use
*/
private void recordEvent(Event event, EventMetric eventMetric) {
synchronized (lastEvents) {
eventMetric.eventReceived();
//
// Keep only the last N events, where N = LAST_EVENTS_MAX_N
//
while (lastEvents.size() >= LAST_EVENTS_MAX_N) {
lastEvents.remove();
}
lastEvents.add(event);
}
}
/**
* Inner Device Event Listener class.
*/
private class InnerDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
recordEvent(event, topologyDeviceEventMetric);
log.debug("Device Event: time = {} type = {} event = {}",
event.time(), event.type(), event);
}
}
/**
* Inner Host Event Listener class.
*/
private class InnerHostListener implements HostListener {
@Override
public void event(HostEvent event) {
recordEvent(event, topologyHostEventMetric);
log.debug("Host Event: time = {} type = {} event = {}",
event.time(), event.type(), event);
}
}
/**
* Inner Link Event Listener class.
*/
private class InnerLinkListener implements LinkListener {
@Override
public void event(LinkEvent event) {
recordEvent(event, topologyLinkEventMetric);
log.debug("Link Event: time = {} type = {} event = {}",
event.time(), event.type(), event);
}
}
/**
* Inner Topology Event Listener class.
*/
private class InnerTopologyListener implements TopologyListener {
@Override
public void event(TopologyEvent event) {
recordEvent(event, topologyGraphEventMetric);
log.debug("Topology Event: time = {} type = {} event = {}",
event.time(), event.type(), event);
for (Event reason : event.reasons()) {
recordEvent(event, topologyGraphReasonsEventMetric);
log.debug("Topology Event Reason: time = {} type = {} event = {}",
reason.time(), reason.type(), reason);
}
}
}
/**
* Clears the internal state.
*/
private void clear() {
synchronized (lastEvents) {
lastEvents.clear();
}
}
/**
* Registers the metrics.
*/
private void registerMetrics() {
topologyDeviceEventMetric =
new EventMetric(metricsService, COMPONENT_NAME,
FEATURE_DEVICE_NAME);
topologyHostEventMetric =
new EventMetric(metricsService, COMPONENT_NAME,
FEATURE_HOST_NAME);
topologyLinkEventMetric =
new EventMetric(metricsService, COMPONENT_NAME,
FEATURE_LINK_NAME);
topologyGraphEventMetric =
new EventMetric(metricsService, COMPONENT_NAME,
FEATURE_GRAPH_NAME);
topologyGraphReasonsEventMetric =
new EventMetric(metricsService, COMPONENT_NAME,
FEATURE_GRAPH_REASONS_NAME);
topologyDeviceEventMetric.registerMetrics();
topologyHostEventMetric.registerMetrics();
topologyLinkEventMetric.registerMetrics();
topologyGraphEventMetric.registerMetrics();
topologyGraphReasonsEventMetric.registerMetrics();
}
/**
* Removes the metrics.
*/
private void removeMetrics() {
topologyDeviceEventMetric.removeMetrics();
topologyHostEventMetric.removeMetrics();
topologyLinkEventMetric.removeMetrics();
topologyGraphEventMetric.removeMetrics();
topologyGraphReasonsEventMetric.removeMetrics();
}
}