blob: 0bdd94be270b3cf144f9c2b1cc84e0b5ce08e1c5 [file] [log] [blame]
HIGUCHI Yuta9092db82016-01-03 18:45:01 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
HIGUCHI Yuta9092db82016-01-03 18:45:01 -08003 *
4 * 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
7 *
8 * 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.
15 */
16package org.onosproject.events;
17
18import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
19import static org.onlab.util.Tools.groupedThreads;
20import static org.onlab.util.Tools.minPriority;
21
22import java.util.Deque;
23import java.util.concurrent.ConcurrentLinkedDeque;
24import java.util.concurrent.ScheduledExecutorService;
25import java.util.concurrent.TimeUnit;
26
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.Property;
31import org.apache.felix.scr.annotations.Reference;
32import org.apache.felix.scr.annotations.ReferenceCardinality;
33import org.apache.felix.scr.annotations.Service;
34import org.onlab.util.UnmodifiableDeque;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080035import org.onosproject.cluster.ClusterService;
36import org.onosproject.core.ApplicationId;
37import org.onosproject.core.CoreService;
38import org.onosproject.event.Event;
39import org.onosproject.event.ListenerTracker;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080040import org.onosproject.mastership.MastershipService;
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080041import org.onosproject.net.config.NetworkConfigService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080042import org.onosproject.net.device.DeviceEvent;
43import org.onosproject.net.device.DeviceListener;
44import org.onosproject.net.device.DeviceService;
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070045import org.onosproject.net.edge.EdgePortService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080046import org.onosproject.net.host.HostService;
Jon Halld66228c2017-08-09 11:24:24 -070047import org.onosproject.net.intent.IntentService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080048import org.onosproject.net.link.LinkService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080049import org.onosproject.net.topology.TopologyService;
50import org.slf4j.Logger;
51import org.slf4j.LoggerFactory;
52
53/**
54 * Application to store history of instance local ONOS Events.
55 */
56@Component(immediate = true)
57@Service
58public class EventHistoryManager
59 implements EventHistoryService {
60
61 private final Logger log = LoggerFactory.getLogger(getClass());
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected CoreService coreService;
65
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected MastershipService mastershipService;
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected DeviceService deviceService;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected LinkService linkService;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected TopologyService topologyService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected HostService hostService;
80
81 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 protected ClusterService clusterService;
83
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070084 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected EdgePortService edgeService;
86
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080087 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jon Halld66228c2017-08-09 11:24:24 -070088 protected IntentService intentService;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080091 protected NetworkConfigService netcfgService;
92
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080093 @Property(name = "excludeStatsEvent", boolValue = true,
94 label = "Exclude stats related events")
95 private boolean excludeStatsEvent = true;
96
97 @Property(name = "sizeLimit", intValue = 10_000,
98 label = "Number of event history to store")
99 private int sizeLimit = 10_000;
100
101 private ApplicationId appId;
102
103 private ListenerTracker listeners;
104
105 // Using Deque so that it'll be possible to iterate from both ends
106 // (Tail-end is the most recent event)
107 private final Deque<Event<?, ?>> history = new ConcurrentLinkedDeque<>();
108
109 private ScheduledExecutorService pruner;
110
111 // pruneEventHistoryTask() execution interval in seconds
112 private long pruneInterval = 5;
113
114
115 @Activate
116 protected void activate() {
117 appId = coreService.registerApplication("org.onosproject.events");
118 log.debug("Registered as {}", appId);
119
HIGUCHI Yuta060da9a2016-03-11 19:16:35 -0800120 pruner = newSingleThreadScheduledExecutor(
121 minPriority(groupedThreads("onos/events", "history-pruner", log)));
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800122
123 pruner.scheduleWithFixedDelay(this::pruneEventHistoryTask,
Jian Li68c4fc42016-01-11 16:07:03 -0800124 pruneInterval, pruneInterval, TimeUnit.SECONDS);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800125
126 listeners = new ListenerTracker();
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700127 listeners.addListener(mastershipService, this::addEvent)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800128 .addListener(deviceService, new InternalDeviceListener())
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700129 .addListener(linkService, this::addEvent)
130 .addListener(topologyService, this::addEvent)
131 .addListener(hostService, this::addEvent)
132 .addListener(clusterService, this::addEvent)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -0800133 .addListener(edgeService, this::addEvent)
Jon Halld66228c2017-08-09 11:24:24 -0700134 .addListener(intentService, this::addEvent)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -0800135 .addListener(netcfgService, this::addEvent);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800136
137 log.info("Started");
138 }
139
140 @Deactivate
141 protected void deactivate() {
142 listeners.removeListeners();
143
144 pruner.shutdownNow();
145 history.clear();
146
147 log.info("Stopped");
148 }
149
150 @Override
151 public Deque<Event<?, ?>> history() {
152 return UnmodifiableDeque.unmodifiableDeque(history);
153 }
154
155 @Override
156 public void clear() {
157 history.clear();
158 }
159
160 // This method assumes only 1 call is in flight at the same time.
161 private void pruneEventHistoryTask() {
162 int size = history.size();
163 int overflows = size - sizeLimit;
164 if (overflows > 0) {
165 for (int i = 0; i < overflows; ++i) {
166 history.poll();
167 }
168 }
169 }
170
171 private void addEvent(Event<?, ?> event) {
Jon Halld66228c2017-08-09 11:24:24 -0700172 if (log.isTraceEnabled()) {
173 log.trace(event.toString());
174 }
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800175 history.offer(event);
176 }
177
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800178 class InternalDeviceListener
179 implements DeviceListener {
180
181 @Override
182 public boolean isRelevant(DeviceEvent event) {
183 if (excludeStatsEvent) {
184 return event.type() != DeviceEvent.Type.PORT_STATS_UPDATED;
185 } else {
186 return true;
187 }
188 }
189
190 @Override
191 public void event(DeviceEvent event) {
192 addEvent(event);
193 }
194 }
195
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800196}