From b5f57a09ff9024ef290d33d068648d0d4b03eefc Mon Sep 17 00:00:00 2001 From: nathanrsxtn Date: Mon, 4 Apr 2022 00:55:42 -0600 Subject: [PATCH] Send formatted DriverStation messages through HAL Check logging levels against HAL messages Add constant to disable console changes entirely --- .../edu/wpi/first/wpilibj/DriverStation.java | 78 ++++++++++--------- .../java/frc4388/utility/AnsiLogging.java | 9 ++- 2 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/main/java/edu/wpi/first/wpilibj/DriverStation.java b/src/main/java/edu/wpi/first/wpilibj/DriverStation.java index c9cab89..c223133 100644 --- a/src/main/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/src/main/java/edu/wpi/first/wpilibj/DriverStation.java @@ -563,46 +563,52 @@ public class DriverStation { boolean printTrace, StackTraceElement[] stackTrace, int stackTraceFirst) { - /* - String locString; - if (stackTrace.length >= stackTraceFirst + 1) { - locString = stackTrace[stackTraceFirst].toString(); + if (frc4388.utility.AnsiLogging.ENABLED) { + java.util.logging.LogRecord logRecord = new java.util.logging.LogRecord(isError ? java.util.logging.Level.SEVERE : java.util.logging.Level.FINER, error.stripTrailing()); + logRecord.setLoggerName("HAL"); + if (!frc4388.utility.AnsiLogging.halLoggerHandler.isLoggable(logRecord)) return; + java.util.Optional.ofNullable(stackTrace).filter(s -> s.length >= stackTraceFirst + 1).map(s -> java.util.Arrays.copyOfRange(s, Math.min(Math.max(0, stackTraceFirst), s.length - 1), s.length - 1)).ifPresent(presentStackTrace -> { + logRecord.setSourceMethodName(presentStackTrace[0].getMethodName()); + String throwableMessage; + if (presentStackTrace[0].toString().equals("edu.wpi.first.wpilibj.Tracer.lambda$printEpochs$0(Tracer.java:63)")) { + throwableMessage = "Epochs" + System.lineSeparator() + logRecord.getMessage(); + presentStackTrace = new java.lang.StackTraceElement[0]; + logRecord.setLevel(java.util.logging.Level.FINEST); + logRecord.setMessage("Execution times:"); + } else if (printTrace) { + long lineCount = logRecord.getMessage().lines().count(); + throwableMessage = (lineCount > 1 ? logRecord.getMessage().lines().findFirst().map(s -> s + " + " + lineCount + " more lines...").orElse("") : logRecord.getMessage()).stripLeading(); + } else return; + java.lang.Throwable throwable = new java.lang.Throwable(throwableMessage); + throwable.setStackTrace(presentStackTrace); + logRecord.setThrown(throwable); + }); + if (!frc4388.utility.AnsiLogging.halLoggerHandler.isLoggable(logRecord)) return; + // java.util.logging.Logger.getLogger(HAL.class.getSimpleName()).log(logRecord); + String msg = frc4388.utility.AnsiLogging.halLoggerHandler.getFormatter().format(logRecord); + HAL.sendError(isError, code, false, msg.substring(0, msg.length() - 1), "", "", true); } else { - locString = ""; - } - StringBuilder traceString = new StringBuilder(); - if (printTrace) { - boolean haveLoc = false; - for (int i = stackTraceFirst; i < stackTrace.length; i++) { - String loc = stackTrace[i].toString(); - traceString.append("\tat ").append(loc).append('\n'); - // get first user function - if (!haveLoc && !loc.startsWith("edu.wpi.first")) { - locString = loc; - haveLoc = true; + String locString; + if (stackTrace.length >= stackTraceFirst + 1) { + locString = stackTrace[stackTraceFirst].toString(); + } else { + locString = ""; + } + StringBuilder traceString = new StringBuilder(); + if (printTrace) { + boolean haveLoc = false; + for (int i = stackTraceFirst; i < stackTrace.length; i++) { + String loc = stackTrace[i].toString(); + traceString.append("\tat ").append(loc).append('\n'); + // get first user function + if (!haveLoc && !loc.startsWith("edu.wpi.first")) { + locString = loc; + haveLoc = true; + } } } + HAL.sendError(isError, code, false, error, locString, traceString.toString(), true); } - HAL.sendError(isError, code, false, error, locString, traceString.toString(), true); - */ - java.util.logging.LogRecord logRecord = new java.util.logging.LogRecord(isError ? java.util.logging.Level.SEVERE : java.util.logging.Level.FINER, error.stripTrailing()); - java.util.Optional.ofNullable(stackTrace).filter(s -> s.length >= stackTraceFirst + 1).map(s -> java.util.Arrays.copyOfRange(s, Math.min(Math.max(0, stackTraceFirst), s.length - 1), s.length - 1)).ifPresent(presentStackTrace -> { - logRecord.setSourceMethodName(presentStackTrace[0].getMethodName()); - String throwableMessage; - if (presentStackTrace[0].toString().equals("edu.wpi.first.wpilibj.Tracer.lambda$printEpochs$0(Tracer.java:63)")) { - throwableMessage = "Epochs" + System.lineSeparator() + logRecord.getMessage(); - presentStackTrace = new java.lang.StackTraceElement[0]; - logRecord.setLevel(java.util.logging.Level.FINEST); - logRecord.setMessage("Execution times:"); - } else if (printTrace) { - long lineCount = logRecord.getMessage().lines().count(); - throwableMessage = (lineCount > 1 ? logRecord.getMessage().lines().findFirst().map(s -> s + " + " + lineCount + " more lines...").orElse("") : logRecord.getMessage()).stripLeading(); - } else return; - java.lang.Throwable throwable = new java.lang.Throwable(throwableMessage); - throwable.setStackTrace(presentStackTrace); - logRecord.setThrown(throwable); - }); - java.util.logging.Logger.getLogger(HAL.class.getSimpleName()).log(logRecord); } /** diff --git a/src/main/java/frc4388/utility/AnsiLogging.java b/src/main/java/frc4388/utility/AnsiLogging.java index 2659a5e..19d74bd 100644 --- a/src/main/java/frc4388/utility/AnsiLogging.java +++ b/src/main/java/frc4388/utility/AnsiLogging.java @@ -11,6 +11,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Map; import java.util.Optional; +import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Level; @@ -28,10 +29,14 @@ import org.fusesource.jansi.AnsiConsole; import org.fusesource.jansi.AnsiPrintStream; public class AnsiLogging { - private static final AnsiPrintStream ANSI_CONSOLE_STREAM = AnsiConsole.out(); + public static final boolean ENABLED = true; + private static final AnsiPrintStream ANSI_CONSOLE_STREAM = AnsiConsole.err(); private static final Level LEVEL = Level.ALL; + public static Handler halLoggerHandler = new ConsoleHandler(); + public static void systemInstall() { + if (!ENABLED) return; try { // Configure java.util.logging.Logger to output additional colored information. LogManager.getLogManager().updateConfiguration(key -> (o, n) -> { @@ -52,6 +57,8 @@ public class AnsiLogging { System.setErr(printStreamLogger(Logger.getGlobal(), "err", Level.SEVERE)); // This is registering a plugin that will log Durian errors to the console using a logger. DurianPlugins.register(Errors.Plugins.Log.class, e -> Logger.getLogger(e.getStackTrace()[0].getClassName().substring(e.getStackTrace()[0].getClassName().lastIndexOf('.') + 1)).log(Level.SEVERE, e, e::getLocalizedMessage)); + // Store the handler for HAL to use when sending errors to DriverStation. + halLoggerHandler = new LoggingAnsiConsoleHandler(); } catch (IOException exception) { exception.printStackTrace(AnsiConsole.sysErr()); }