X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Finit%2Flogging%2FThinLogging.java;h=ff602ad51a7c06abe532fc5af3111f9c18870a93;hb=6c0d4c9eb9673fd893f8ef3e6d0ecb5f53a832c6;hp=44be1aa1b8d833d29b21b93f4e720bb15254e894;hpb=9fd6762a7ac6bb5102dcd2c5a3bc876aa5c942c4;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java b/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java index 44be1aa1b..ff602ad51 100644 --- a/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java +++ b/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java @@ -1,9 +1,14 @@ package org.argeo.init.logging; +import java.io.IOException; import java.io.PrintStream; import java.io.Serializable; import java.lang.System.Logger; import java.lang.System.Logger.Level; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.text.MessageFormat; import java.time.Instant; import java.util.Collections; @@ -43,10 +48,12 @@ class ThinLogging implements Consumer> { */ final static String PROP_ARGEO_LOGGING_SYNCHRONOUS = "argeo.logging.synchronous"; /** - * Whether to enable jounrald compatible output, either: auto (default), true, + * Whether to enable journald compatible output, either: auto (default), true, * or false. */ final static String PROP_ARGEO_LOGGING_JOURNALD = "argeo.logging.journald"; + /** A file to which additionally write log entries. */ + final static String PROP_ARGEO_LOGGING_FILE = "argeo.logging.file"; /** * The level from which call location (that is, line number in Java code) will * be searched (default is WARNING) @@ -67,6 +74,7 @@ class ThinLogging implements Consumer> { private final LogEntryPublisher publisher; private PrintStreamSubscriber synchronousSubscriber; + private PrintStream fileOut; private final boolean journald; private final Level callLocationLevel; @@ -82,6 +90,21 @@ class ThinLogging implements Consumer> { PrintStreamSubscriber subscriber = new PrintStreamSubscriber(); publisher = new LogEntryPublisher(); publisher.subscribe(subscriber); + String logFileStr = System.getProperty(PROP_ARGEO_LOGGING_FILE); + if (logFileStr != null) { + Path logFilePath = Paths.get(logFileStr); + if (!Files.exists(logFilePath.getParent())) { + System.err.println("Parent directory of " + logFilePath + " does not exist"); + } else { + try { + fileOut = new PrintStream(Files.newOutputStream(logFilePath), true, StandardCharsets.UTF_8); + publisher.subscribe(new PrintStreamSubscriber(fileOut, fileOut)); + } catch (IOException e) { + System.err.println("Cannot write log to " + logFilePath); + e.printStackTrace(); + } + } + } } Runtime.getRuntime().addShutdownHook(new Thread(() -> close(), "Log shutdown")); @@ -147,6 +170,14 @@ class ThinLogging implements Consumer> { // silent } } + + if (fileOut != null) { + try { + fileOut.close(); + } catch (Exception e) { + // silent + } + } } private Level computeApplicableLevel(String name) { @@ -225,10 +256,13 @@ class ThinLogging implements Consumer> { Thread thread, Throwable thrown, StackTraceElement callLocation) { assert level != null; assert logger != null; - assert msg != null; +// assert msg != null; assert instant != null; assert thread != null; + if (msg == null) + msg = "null"; + final long sequence = nextEntry.incrementAndGet(); Map logEntry = new LogEntryMap(sequence);