From 2ab5409eec4e514f3c00a927bd56f6241a54da0f Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 5 Nov 2024 19:16:54 -0800 Subject: [PATCH] Refactor into own class --- .../common/logging/KernelLogLogger.java | 73 +++++++++++++++++++ .../photonvision/common/logging/Logger.java | 43 +---------- .../src/main/java/org/photonvision/Main.java | 5 +- 3 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 photon-core/src/main/java/org/photonvision/common/logging/KernelLogLogger.java diff --git a/photon-core/src/main/java/org/photonvision/common/logging/KernelLogLogger.java b/photon-core/src/main/java/org/photonvision/common/logging/KernelLogLogger.java new file mode 100644 index 0000000000..2335e5a24f --- /dev/null +++ b/photon-core/src/main/java/org/photonvision/common/logging/KernelLogLogger.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) Photon Vision. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.photonvision.common.logging; + +import edu.wpi.first.util.RuntimeDetector; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.photonvision.common.util.TimedTaskManager; +import org.photonvision.jni.QueuedFileLogger; + +/** + * Listens for and reproduces Linux kernel logs, from /var/log/kern.log, into the Photon logger + * ecosystem + */ +public class KernelLogLogger { + private static KernelLogLogger INSTANCE; + + public static KernelLogLogger getInstance() { + if (INSTANCE == null) { + INSTANCE = new KernelLogLogger(); + } + return INSTANCE; + } + + QueuedFileLogger listener = null; + Logger logger = new Logger(KernelLogLogger.class, LogGroup.General); + + public KernelLogLogger() { + if (RuntimeDetector.isLinux()) { + logger.info("Listening for klogs on /var/log/dmesg ! Boot logs:"); + + try { + var bootlog = Files.readAllLines(Path.of("/var/log/dmesg")); + for (var line : bootlog) { + logger.log(line, LogLevel.DEBUG); + } + } catch (IOException e) { + logger.error("Couldn't read /var/log/dmesg - not printing boot logs"); + } + + listener = new QueuedFileLogger("/var/log/kern.log"); + } else { + System.out.println("NOT for klogs"); + } + + // arbitrary frequency to grab logs. The underlying native buffer will grow unbounded without + // this, lol + TimedTaskManager.getInstance().addTask("outputPrintk", this::outputNewPrintks, 1000); + } + + public void outputNewPrintks() { + for (var msg : listener.getNewlines()) { + // We currently set all logs to debug regardless of their actual level + logger.log(msg, LogLevel.DEBUG); + } + } +} diff --git a/photon-core/src/main/java/org/photonvision/common/logging/Logger.java b/photon-core/src/main/java/org/photonvision/common/logging/Logger.java index 9df99f8671..7bba651b53 100644 --- a/photon-core/src/main/java/org/photonvision/common/logging/Logger.java +++ b/photon-core/src/main/java/org/photonvision/common/logging/Logger.java @@ -17,9 +17,7 @@ package org.photonvision.common.logging; -import edu.wpi.first.util.RuntimeDetector; import java.io.*; -import java.nio.file.Files; import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -31,7 +29,6 @@ import org.photonvision.common.dataflow.DataChangeService; import org.photonvision.common.dataflow.events.OutgoingUIEvent; import org.photonvision.common.util.TimedTaskManager; -import org.photonvision.jni.QueuedFileLogger; /** TODO: get rid of static {} blocks and refactor to singleton pattern */ public class Logger { @@ -40,8 +37,8 @@ public class Logger { private static final UILogAppender uiLogAppender = new UILogAppender(); - // TODO why's the logger care about this? split it out - private static KernelLogListener klogListener = null; + // // TODO why's the logger care about this? split it out + // private static KernelLogLogger klogListener = null; static { levelMap.put(LogGroup.Camera, LogLevel.INFO); @@ -61,10 +58,6 @@ public class Logger { cleanLogs(PathManager.getInstance().getLogsDir()); } - public static void addKlongListener() { - klogListener = new KernelLogListener(); - } - public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLACK = "\u001B[30m"; public static final String ANSI_RED = "\u001B[31m"; @@ -298,38 +291,6 @@ private static String convertStackTraceToString(Throwable throwable) { } } - private static class KernelLogListener { - QueuedFileLogger listener = null; - Logger logger = new Logger(KernelLogListener.class, LogGroup.General); - - public KernelLogListener() { - if (RuntimeDetector.isLinux()) { - logger.info("Listening for klogs on /var/log/dmesg ! Boot logs:"); - - try { - var bootlog = Files.readAllLines(Path.of("/var/log/dmesg")); - for (var line : bootlog) { - logger.log(line, LogLevel.DEBUG); - } - } catch (IOException e) { - logger.error("Couldn't read /var/log/dmesg - not printing boot logs"); - } - - listener = new QueuedFileLogger("/var/log/kern.log"); - } else { - System.out.println("NOT for klogs"); - } - - TimedTaskManager.getInstance().addTask("outputPrintk", this::outputNewPrintks, 1000); - } - - public void outputNewPrintks() { - for (var msg : listener.getNewlines()) { - logger.log(msg, LogLevel.DEBUG); - } - } - } - private interface LogAppender { void log(String message, LogLevel level); diff --git a/photon-server/src/main/java/org/photonvision/Main.java b/photon-server/src/main/java/org/photonvision/Main.java index b6948e2209..a3834abe5e 100644 --- a/photon-server/src/main/java/org/photonvision/Main.java +++ b/photon-server/src/main/java/org/photonvision/Main.java @@ -33,6 +33,7 @@ import org.photonvision.common.hardware.HardwareManager; import org.photonvision.common.hardware.PiVersion; import org.photonvision.common.hardware.Platform; +import org.photonvision.common.logging.KernelLogLogger; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.LogLevel; import org.photonvision.common.logging.Logger; @@ -437,8 +438,8 @@ public static void main(String[] args) { Logger.setLevel(LogGroup.General, logLevel); logger.info("Logging initialized in debug mode."); - // after native libraries are loaded :( - Logger.addKlongListener(); + // Add Linux kernel log->Photon logger + KernelLogLogger.getInstance(); // Add CSCore->Photon logger PvCSCoreLogger.getInstance();