blob: 4d26466b68b1ef8ffb7eb39d24d726b89bcb4e84 [file] [log] [blame]
HIGUCHI Yuta9092db82016-01-03 18:45:01 -08001/*
2 * Copyright 2016 Open Networking Laboratory
3 *
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
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080018import java.io.PrintWriter;
19import java.io.StringWriter;
20import java.util.List;
21import java.util.function.Predicate;
22import java.util.stream.Collector;
23import java.util.stream.Stream;
24
25import org.apache.karaf.shell.commands.Command;
26import org.apache.karaf.shell.commands.Option;
27import org.joda.time.LocalDateTime;
28import org.onosproject.cli.AbstractShellCommand;
29import org.onosproject.cluster.ClusterEvent;
30import org.onosproject.event.Event;
31import org.onosproject.mastership.MastershipEvent;
32import org.onosproject.net.Link;
33import org.onosproject.net.device.DeviceEvent;
34import org.onosproject.net.host.HostEvent;
35import org.onosproject.net.link.LinkEvent;
36import org.onosproject.net.topology.Topology;
37import org.onosproject.net.topology.TopologyEvent;
38
39import com.fasterxml.jackson.core.JsonProcessingException;
40import com.fasterxml.jackson.databind.JsonNode;
41import com.fasterxml.jackson.databind.node.ArrayNode;
42import com.fasterxml.jackson.databind.node.ObjectNode;
43import com.google.common.base.MoreObjects;
44import com.google.common.collect.ImmutableList;
45
Ray Milkey9f87e512016-01-05 10:00:22 -080046import static java.util.stream.Collectors.toList;
47import static org.onlab.util.SonarSuppressionConstants.SONAR_PRINT_STACK_TRACE;
48
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080049/**
50 * Command to print history of instance local ONOS Events.
51 */
52@Command(scope = "onos", name = "events",
53 description = "Command to print history of instance local ONOS Events")
54public class EventsCommand
55 extends AbstractShellCommand {
56
57 @Option(name = "--all", aliases = "-a",
58 description = "Include all Events (default behavior)",
59 required = false)
60 private boolean all = false;
61
62 @Option(name = "--mastership", aliases = "-m",
63 description = "Include MastershipEvent",
64 required = false)
65 private boolean mastership = false;
66
67 @Option(name = "--device", aliases = "-d",
68 description = "Include DeviceEvent",
69 required = false)
70 private boolean device = false;
71
72 @Option(name = "--link", aliases = "-l",
73 description = "Include LinkEvent",
74 required = false)
75 private boolean link = false;
76
77 @Option(name = "--topology", aliases = "-t",
78 description = "Include TopologyEvent",
79 required = false)
80 private boolean topology = false;
81
82 @Option(name = "--host", aliases = "-t",
83 description = "Include HostEvent",
84 required = false)
85 private boolean host = false;
86
87 @Option(name = "--cluster", aliases = "-c",
88 description = "Include ClusterEvent",
89 required = false)
90 private boolean cluster = false;
91
92 @Option(name = "--max-events", aliases = "-n",
93 description = "Maximum number of events to print",
94 required = false,
95 valueToShowInHelp = "-1 [no limit]")
96 private long maxSize = -1;
97
98 @Override
99 protected void execute() {
100 EventHistoryService eventHistoryService = get(EventHistoryService.class);
101
102 Stream<Event<?, ?>> events = eventHistoryService.history().stream();
103
104 boolean dumpAll = all || !(mastership || device || link || topology || host);
105
106 if (!dumpAll) {
107 Predicate<Event<?, ?>> filter = (defaultIs) -> false;
108
109 if (mastership) {
110 filter = filter.or(evt -> evt instanceof MastershipEvent);
111 }
112 if (device) {
113 filter = filter.or(evt -> evt instanceof DeviceEvent);
114 }
115 if (link) {
116 filter = filter.or(evt -> evt instanceof LinkEvent);
117 }
118 if (topology) {
119 filter = filter.or(evt -> evt instanceof TopologyEvent);
120 }
121 if (host) {
122 filter = filter.or(evt -> evt instanceof HostEvent);
123 }
124 if (cluster) {
125 filter = filter.or(evt -> evt instanceof ClusterEvent);
126 }
127
128 events = events.filter(filter);
129 }
130
131 if (maxSize > 0) {
132 events = events.limit(maxSize);
133 }
134
135 if (outputJson()) {
136 ArrayNode jsonEvents = events.map(this::json).collect(toArrayNode());
137 printJson(jsonEvents);
138 } else {
139 events.forEach(this::printEvent);
140 }
141
142 }
143
144 private Collector<JsonNode, ArrayNode, ArrayNode> toArrayNode() {
145 return Collector.of(() -> mapper().createArrayNode(),
146 ArrayNode::add,
147 ArrayNode::addAll);
148 }
149
150 private ObjectNode json(Event<?, ?> event) {
151 ObjectNode result = mapper().createObjectNode();
152
153 result.put("time", event.time())
154 .put("type", event.type().toString())
155 .put("event", event.toString());
156
157 return result;
158 }
159
160 /**
161 * Print JsonNode using default pretty printer.
162 *
163 * @param json JSON node to print
164 */
Ray Milkey9f87e512016-01-05 10:00:22 -0800165 @java.lang.SuppressWarnings(SONAR_PRINT_STACK_TRACE)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800166 private void printJson(JsonNode json) {
167 try {
168 print("%s", mapper().writerWithDefaultPrettyPrinter().writeValueAsString(json));
169 } catch (JsonProcessingException e) {
170 StringWriter sw = new StringWriter();
171 e.printStackTrace(new PrintWriter(sw));
172 print("[ERROR] %s\n%s", e.getMessage(), sw.toString());
173 }
174 }
175
176 private void printEvent(Event<?, ?> event) {
177 if (event instanceof DeviceEvent) {
178 DeviceEvent deviceEvent = (DeviceEvent) event;
179 if (event.type().toString().startsWith("PORT")) {
180 // Port event
181 print("%s %s\t%s/%s [%s]",
182 new LocalDateTime(event.time()),
183 event.type(),
184 deviceEvent.subject().id(), deviceEvent.port().number(),
185 deviceEvent.port()
186 );
187 } else {
188 // Device event
189 print("%s %s\t%s [%s]",
190 new LocalDateTime(event.time()),
191 event.type(),
192 deviceEvent.subject().id(),
193 deviceEvent.subject()
194 );
195 }
196
197 } else if (event instanceof MastershipEvent) {
198 print("%s %s\t%s [%s]",
199 new LocalDateTime(event.time()),
200 event.type(),
201 event.subject(),
202 ((MastershipEvent) event).roleInfo());
203
204 } else if (event instanceof LinkEvent) {
205 LinkEvent linkEvent = (LinkEvent) event;
206 Link link = linkEvent.subject();
207 print("%s %s\t%s/%s-%s/%s [%s]",
208 new LocalDateTime(event.time()),
209 event.type(),
210 link.src().deviceId(), link.src().port(), link.dst().deviceId(), link.dst().port(),
211 link);
212
213 } else if (event instanceof HostEvent) {
214 HostEvent hostEvent = (HostEvent) event;
215 print("%s %s\t%s [%s->%s]",
216 new LocalDateTime(event.time()),
217 event.type(),
218 hostEvent.subject().id(),
219 hostEvent.prevSubject(), hostEvent.subject());
220
221 } else if (event instanceof TopologyEvent) {
222 TopologyEvent topoEvent = (TopologyEvent) event;
Ray Milkeyc18d0e32016-01-04 16:10:59 -0800223 List<Event> reasons = MoreObjects.firstNonNull(topoEvent.reasons(),
224 ImmutableList.<Event>of());
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800225 Topology topo = topoEvent.subject();
226 String summary = String.format("(d=%d,l=%d,c=%d)",
227 topo.deviceCount(),
228 topo.linkCount(),
229 topo.clusterCount());
230 print("%s %s%s [%s]",
231 new LocalDateTime(event.time()),
232 event.type(),
233 summary,
234 reasons.stream().map(e -> e.type()).collect(toList()));
235
236 } else if (event instanceof ClusterEvent) {
237 print("%s %s\t%s [%s]",
238 new LocalDateTime(event.time()),
239 event.type(),
240 ((ClusterEvent) event).subject().id(),
241 event.subject());
242
243 } else {
244 // Unknown Event?
245 print("%s %s\t%s [%s]",
246 new LocalDateTime(event.time()),
247 event.type(),
248 event.subject(),
249 event);
250 }
251 }
252
253}