From f5e729d61e5cc195eaf2179b187d5b16367408cc Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 24 Sep 2024 17:35:04 -0400 Subject: [PATCH] use custom log formatter for journald logging --- .../attestation/server/AttestationServer.java | 7 ++ .../attestation/server/JournaldFormatter.java | 83 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/main/java/app/attestation/server/JournaldFormatter.java diff --git a/src/main/java/app/attestation/server/AttestationServer.java b/src/main/java/app/attestation/server/AttestationServer.java index d549b67d..ab53b3c7 100644 --- a/src/main/java/app/attestation/server/AttestationServer.java +++ b/src/main/java/app/attestation/server/AttestationServer.java @@ -55,6 +55,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.logging.ConsoleHandler; +import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.DataFormatException; @@ -267,6 +269,11 @@ private static int getUserVersion(final SQLiteConnection conn) throws SQLiteExce public static void main(final String[] args) throws Exception { Logger.getLogger("com.almworks.sqlite4java").setLevel(Level.OFF); + Logger.getLogger("app.attestation").setUseParentHandlers(false); + final ConsoleHandler handler = new ConsoleHandler(); + handler.setFormatter(new JournaldFormatter()); + Logger.getLogger("app.attestation").addHandler(handler); + final SQLiteConnection samplesConn = open(SAMPLES_DATABASE); try { final SQLiteStatement selectCreated = samplesConn.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='Samples'"); diff --git a/src/main/java/app/attestation/server/JournaldFormatter.java b/src/main/java/app/attestation/server/JournaldFormatter.java new file mode 100644 index 00000000..ac68fee4 --- /dev/null +++ b/src/main/java/app/attestation/server/JournaldFormatter.java @@ -0,0 +1,83 @@ +package app.attestation.server; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Date; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; + +class JournaldFormatter extends Formatter { + private static final int LEVEL_EMERG = 0; + private static final int LEVEL_ALERT = 1; + private static final int LEVEL_CRIT = 2; + private static final int LEVEL_ERR = 3; + private static final int LEVEL_WARNING = 4; + private static final int LEVEL_NOTICE = 5; + private static final int LEVEL_INFO = 6; + private static final int LEVEL_DEBUG = 7; + + private static int toSyslogLevel(final Level level) { + final int value = level.intValue(); + if (value >= 1300) { + return LEVEL_EMERG; + } + if (value >= 1200) { + return LEVEL_ALERT; + } + if (value >= 1100) { + return LEVEL_CRIT; + } + // Level.SEVERE 1000 + if (value >= 1000) { + return LEVEL_ERR; + } + // Level.WARNING 900 + if (value >= 900) { + return LEVEL_WARNING; + } + if (value >= 850) { + return LEVEL_NOTICE; + } + // Level.INFO 800 + if (value >= 800) { + return LEVEL_INFO; + } + // Level.CONFIG 700 + // Level.FINE 500 + // Level.FINER 400 + // Level.FINEST 300 + return LEVEL_DEBUG; + } + + public synchronized String format(LogRecord record) { + String source; + if (record.getSourceClassName() != null) { + source = record.getSourceClassName(); + if (record.getSourceMethodName() != null) { + source += " " + record.getSourceMethodName(); + } + } else { + source = record.getLoggerName(); + } + final int level = toSyslogLevel(record.getLevel()); + final String message = formatMessage(record); + String throwable = ""; + if (record.getThrown() != null) { + final String newline = "\n<" + toSyslogLevel(record.getLevel()) + ">"; + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw) { + @Override + public void println() { + write(newline); + } + }; + pw.println(); + record.getThrown().printStackTrace(pw); + pw.close(); + throwable = sw.toString(); + } + return String.format("<%s>%s: %s%s\n", level, source, message, throwable); + } +}