From 99329805ad7ee44399b11a2e0615ad3243c527e5 Mon Sep 17 00:00:00 2001 From: eikek Date: Sun, 20 Feb 2022 00:14:17 +0100 Subject: [PATCH] Always log to stdout --- .../logging/impl/ScribeConfigure.scala | 9 ++- .../docspell/logging/impl/StdoutWriter.scala | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 modules/logging/scribe/src/main/scala/docspell/logging/impl/StdoutWriter.scala diff --git a/modules/logging/scribe/src/main/scala/docspell/logging/impl/ScribeConfigure.scala b/modules/logging/scribe/src/main/scala/docspell/logging/impl/ScribeConfigure.scala index bcaaa4de..1b8b6c79 100644 --- a/modules/logging/scribe/src/main/scala/docspell/logging/impl/ScribeConfigure.scala +++ b/modules/logging/scribe/src/main/scala/docspell/logging/impl/ScribeConfigure.scala @@ -13,7 +13,6 @@ import docspell.logging.{Level, LogConfig} import scribe.format.Formatter import scribe.jul.JULHandler -import scribe.writer.ConsoleWriter object ScribeConfigure { private[this] val docspellRootVerbose = "DOCSPELL_ROOT_LOGGER_LEVEL" @@ -46,13 +45,13 @@ object ScribeConfigure { l => cfg.format match { case Format.Fancy => - l.withHandler(formatter = Formatter.enhanced) + l.withHandler(formatter = Formatter.enhanced, writer = StdoutWriter) case Format.Plain => - l.withHandler(formatter = Formatter.classic) + l.withHandler(formatter = Formatter.classic, writer = StdoutWriter) case Format.Json => - l.withHandler(writer = JsonWriter(ConsoleWriter)) + l.withHandler(writer = JsonWriter(StdoutWriter)) case Format.Logfmt => - l.withHandler(writer = LogfmtWriter(ConsoleWriter)) + l.withHandler(writer = LogfmtWriter(StdoutWriter)) }, _.replace() ) diff --git a/modules/logging/scribe/src/main/scala/docspell/logging/impl/StdoutWriter.scala b/modules/logging/scribe/src/main/scala/docspell/logging/impl/StdoutWriter.scala new file mode 100644 index 00000000..ba79d892 --- /dev/null +++ b/modules/logging/scribe/src/main/scala/docspell/logging/impl/StdoutWriter.scala @@ -0,0 +1,56 @@ +/* + * Copyright 2020 Eike K. & Contributors + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package docspell.logging.impl + +import scribe._ +import scribe.output.LogOutput +import scribe.output.format.OutputFormat +import scribe.writer.Writer + +// From: https://github.com/outr/scribe/blob/8e99521e1ee1f0c421629764dd96e4eb193d84bd/core/shared/src/main/scala/scribe/writer/SystemOutputWriter.scala +// Modified to always log to stdout. The original code was logging to stdout and stderr +// depending on the log level. +// Original code licensed under MIT + +private[impl] object StdoutWriter extends Writer { + + /** If true, will always synchronize writing to the console to avoid interleaved text. + * Most native consoles will handle this automatically, but IntelliJ and Eclipse are + * notorious about not properly handling this. Defaults to true. + */ + val synchronizeWriting: Boolean = true + + /** Workaround for some consoles that don't play nicely with asynchronous calls */ + val alwaysFlush: Boolean = false + + private val stringBuilders = new ThreadLocal[StringBuilder] { + override def initialValue(): StringBuilder = new StringBuilder(512) + } + + @annotation.nowarn + override def write[M]( + record: LogRecord[M], + output: LogOutput, + outputFormat: OutputFormat + ): Unit = { + val stream = Logger.system.out + val sb = stringBuilders.get() + outputFormat.begin(sb.append(_)) + outputFormat(output, s => sb.append(s)) + outputFormat.end(sb.append(_)) + if (synchronizeWriting) { + synchronized { + stream.println(sb.toString()) + if (alwaysFlush) stream.flush() + } + } else { + stream.println(sb.toString()) + if (alwaysFlush) stream.flush() + } + sb.clear() + } +}