diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 9f2d5ded12f8cbedf5bab2239fdc208deb0660f6..6bfd413d38665ac9397375c9c6db05929e8bad2e 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -126,7 +126,7 @@ import com.bigswitch.floodlight.vendor.OFVendorActions; * The main controller class. Handles all setup and network listeners */ public class Controller implements IFloodlightProviderService, - IStorageSourceListener { + IStorageSourceListener, IInfoProvider { protected static final Logger log = LoggerFactory.getLogger(Controller.class); protected static final INotificationManager notifier = @@ -2361,6 +2361,8 @@ public class Controller implements IFloodlightProviderService, throw new FloodlightModuleException(e.getMessage()); } + addInfoProvider("summary", this); + registerControllerDebugEvents(); } @@ -2703,4 +2705,14 @@ public class Controller implements IFloodlightProviderService, IStoreListener<Long> getStoreListener() { return this.switchManager; } + + @Override + public Map<String, Object> getInfo(String type) { + if (!"summary".equals(type)) return null; + + Map<String, Object> info = new HashMap<String, Object>(); + + info.put("# Switches", this.getAllSwitchDpids().size()); + return info; + } } diff --git a/src/main/java/net/floodlightcontroller/debugevent/DebugEvent.java b/src/main/java/net/floodlightcontroller/debugevent/DebugEvent.java index 356e0a82d9da1560e3e8922f82f2cfd0bfed83a4..3442971aa1397e906424104656698d92e0db6764 100644 --- a/src/main/java/net/floodlightcontroller/debugevent/DebugEvent.java +++ b/src/main/java/net/floodlightcontroller/debugevent/DebugEvent.java @@ -513,6 +513,7 @@ public class DebugEvent implements IFloodlightModule, IDebugEventService { IRestApiService restService = context.getServiceImpl(IRestApiService.class); restService.addRestletRoutable(new DebugEventRoutable()); + DebugEventAppender.setDebugEventServiceImpl(this); } } diff --git a/src/main/java/net/floodlightcontroller/debugevent/DebugEventAppender.java b/src/main/java/net/floodlightcontroller/debugevent/DebugEventAppender.java new file mode 100644 index 0000000000000000000000000000000000000000..3429675d7b60829c0fa18b9e106ac1cd09b75534 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/debugevent/DebugEventAppender.java @@ -0,0 +1,96 @@ +package net.floodlightcontroller.debugevent; + +import net.floodlightcontroller.debugevent.IDebugEventService.EventColumn; +import net.floodlightcontroller.debugevent.IDebugEventService.EventFieldType; +import net.floodlightcontroller.debugevent.IDebugEventService.EventType; +import net.floodlightcontroller.debugevent.IDebugEventService.MaxEventsRegistered; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.UnsynchronizedAppenderBase; + +public class DebugEventAppender<E> extends UnsynchronizedAppenderBase<E> { + static IDebugEventService debugEvent; + static IEventUpdater<WarnErrorEvent> evWarnError; + static Thread debugEventRegistryTask = new Thread() { + @Override + public void run() { + while(DebugEventAppender.debugEvent == null) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + return; + } + } + //safe to register debugEvent + registerDebugEventQueue(); + } + }; + + @Override + public void start() { + DebugEventAppender.debugEventRegistryTask.start(); + super.start(); + } + + public static void setDebugEventServiceImpl(IDebugEventService debugEvent) { + DebugEventAppender.debugEvent = debugEvent; + // It is now ok to register an event Q - but letting this thread go + // since it was called from a startUp() routine + } + + /** + * The logging system calls append for every log message. This method filters + * out the WARN and ERROR message and adds to a debug event queue that can + * be accessed via cli or rest-api or gui. + */ + @Override + protected void append(E eventObject) { + if (!isStarted()) { + return; + } + if (evWarnError != null) { + ILoggingEvent ev = ((ILoggingEvent) eventObject); + if (ev.getLevel().equals(Level.ERROR) || ev.getLevel().equals(Level.WARN)) { + evWarnError.updateEventWithFlush( + new WarnErrorEvent(ev.getFormattedMessage(), ev.getLevel(), + ev.getThreadName(), ev.getLoggerName())); + } + } + } + + private static void registerDebugEventQueue() { + try { + evWarnError = debugEvent.registerEvent("net.floodlightcontroller.core", + "warn-error-queue", + "all WARN and ERROR logs", + EventType.ALWAYS_LOG, WarnErrorEvent.class, + 100); + } catch (MaxEventsRegistered e) { + e.printStackTrace(); + } + + } + + public static class WarnErrorEvent { + @EventColumn(name = "message", description = EventFieldType.STRING) + String message; + + @EventColumn(name = "level", description = EventFieldType.OBJECT) + Level level; + + @EventColumn(name = "threadName", description = EventFieldType.STRING) + String threadName; + + @EventColumn(name = "logger", description = EventFieldType.OBJECT) + String logger; + + public WarnErrorEvent(String message, Level level, String threadName, + String logger) { + this.message = message; + this.level = level; + this.threadName = threadName; + this.logger = logger; + } + } + +} diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index ddc4e77fd42d797c1bac9483b34e30c53ce70308..5223fb6ed1ad6a47749510bb1f7715dde9dfd2e0 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -899,6 +899,7 @@ IFlowReconcileListener, IInfoProvider { } catch (SyncException e) { throw new FloodlightModuleException("Error while setting up sync service", e); } + floodlightProvider.addInfoProvider("summary", this); } private void registerDeviceManagerDebugCounters() throws FloodlightModuleException { diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java index f73fe55663f2216e628834a36eb24d6e81e52ffa..b933724e137a975b39489cabd2bc7276b7f03513 100644 --- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java +++ b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java @@ -61,7 +61,6 @@ public class FlowReconcileManager protected IThreadPoolService threadPool; protected ICounterStoreService counterStore; protected IDebugCounterService debugCounters; - /** * The list of flow reconcile listeners that have registered to get * flow reconcile callbacks. Such callbacks are invoked, for example, when @@ -92,10 +91,12 @@ public class FlowReconcileManager /** Config to enable or disable flowReconcile */ protected static final String EnableConfigKey = "enable"; + /* + * Debug Counters + */ public static final String PACKAGE = FlowReconcileManager.class.getPackage().getName(); private IDebugCounter ctrFlowReconcileRequest; private IDebugCounter ctrReconciledFlows; - protected boolean flowReconcileEnabled; public AtomicInteger flowReconcileThreadRunCount; @@ -213,6 +214,7 @@ public class FlowReconcileManager enableValue.equalsIgnoreCase("false")) { flowReconcileEnabled = false; } + registerFlowReconcileManagerDebugCounters(); flowReconcileThreadRunCount = new AtomicInteger(0); lastReconcileTime = new Date(0); logger.debug("FlowReconcile is {}", flowReconcileEnabled); @@ -228,7 +230,7 @@ public class FlowReconcileManager "All flow reconcile request received by this module", CounterType.ALWAYS_COUNT); ctrReconciledFlows = debugCounters.registerCounter(PACKAGE, "reconciled-flows", - "All flows reconciled successfully", + "All flows reconciled successfully by this module", CounterType.ALWAYS_COUNT); } catch (CounterException e) { throw new FloodlightModuleException(e.getMessage()); diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java index 6bf90514df22fadf73de2fd15ff58d8bb4b5a762..fe9be26b1e78304370d770cd20a232d64adb6586 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java @@ -2261,10 +2261,16 @@ public class LinkDiscoveryManager implements IOFMessageListener, Map<String, Object> info = new HashMap<String, Object>(); - int num_links = 0; - for (Set<Link> links : switchLinks.values()) - num_links += links.size(); - info.put("# inter-switch links", num_links / 2); + int numDirectLinks = 0; + for (Set<Link> links : switchLinks.values()) { + for (Link link : links) { + LinkInfo linkInfo = this.getLinkInfo(link); + if (linkInfo.getLinkType() == LinkType.DIRECT_LINK) { + numDirectLinks++; + } + } + } + info.put("# inter-switch links", numDirectLinks / 2); info.put("# quarantine ports", quarantineQueue.size()); return info; }