Adopt to new loggin api

This commit is contained in:
eikek
2022-02-19 14:00:47 +01:00
parent 6442771270
commit e483a97de7
130 changed files with 634 additions and 662 deletions

View File

@ -0,0 +1,39 @@
/*
* Copyright 2020 Eike K. & Contributors
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package docspell.logging
import cats.data.NonEmptyList
import cats.syntax.all._
import cats.{Applicative, Id}
final private[logging] class AndThenLogger[F[_]: Applicative](
val loggers: NonEmptyList[Logger[F]]
) extends Logger[F] {
def log(ev: LogEvent): F[Unit] =
loggers.traverse(_.log(ev)).as(())
def asUnsafe: Logger[Id] =
new Logger[Id] { self =>
def log(ev: LogEvent): Unit =
loggers.toList.foreach(_.asUnsafe.log(ev))
def asUnsafe = self
}
}
private[logging] object AndThenLogger {
def combine[F[_]: Applicative](a: Logger[F], b: Logger[F]): Logger[F] =
(a, b) match {
case (aa: AndThenLogger[F], bb: AndThenLogger[F]) =>
new AndThenLogger[F](aa.loggers ++ bb.loggers.toList)
case (aa: AndThenLogger[F], _) =>
new AndThenLogger[F](aa.loggers.prepend(b))
case (_, bb: AndThenLogger[F]) =>
new AndThenLogger[F](bb.loggers.prepend(a))
case _ =>
new AndThenLogger[F](NonEmptyList.of(a, b))
}
}

View File

@ -20,6 +20,9 @@ final case class LogEvent(
line: Line
) {
def asString =
s"${level.name} ${name.value}/${fileName}:${line.value} - ${msg()}"
def data[A: Encoder](key: String, value: => A): LogEvent =
copy(data = data.updated(key, () => Encoder[A].apply(value)))
@ -28,6 +31,11 @@ final case class LogEvent(
def addError(ex: Throwable): LogEvent =
copy(additional = (() => Right(ex)) :: additional)
def findErrors: List[Throwable] =
additional.map(a => a()).collect { case Right(ex) =>
ex
}
}
object LogEvent {

View File

@ -6,14 +6,18 @@
package docspell.logging
import cats.Id
import cats.effect.Sync
import java.io.PrintStream
import java.time.Instant
import docspell.logging.impl.LoggerWrapper
import cats.effect.{Ref, Sync}
import cats.syntax.applicative._
import cats.syntax.functor._
import cats.syntax.order._
import cats.{Applicative, Id}
import sourcecode._
trait Logger[F[_]] {
trait Logger[F[_]] extends LoggerExtension[F] {
def log(ev: LogEvent): F[Unit]
@ -117,12 +121,46 @@ trait Logger[F[_]] {
}
object Logger {
def unsafe(name: String): Logger[Id] =
new LoggerWrapper.ImplUnsafe(scribe.Logger(name))
def off: Logger[Id] =
new Logger[Id] {
def log(ev: LogEvent): Unit = ()
def asUnsafe = this
}
def apply[F[_]: Sync](name: String): Logger[F] =
new LoggerWrapper.Impl[F](scribe.Logger(name))
def offF[F[_]: Applicative]: Logger[F] =
new Logger[F] {
def log(ev: LogEvent) = ().pure[F]
def asUnsafe = off
}
def apply[F[_]: Sync](clazz: Class[_]): Logger[F] =
new LoggerWrapper.Impl[F](scribe.Logger(clazz.getName))
def buffer[F[_]: Sync](): F[(Ref[F, Vector[LogEvent]], Logger[F])] =
for {
buffer <- Ref.of[F, Vector[LogEvent]](Vector.empty[LogEvent])
logger =
new Logger[F] {
def log(ev: LogEvent) =
buffer.update(_.appended(ev))
def asUnsafe = off
}
} yield (buffer, logger)
/** Just prints to the given print stream. Useful for testing. */
def simple(ps: PrintStream, minimumLevel: Level): Logger[Id] =
new Logger[Id] {
def log(ev: LogEvent): Unit =
if (ev.level >= minimumLevel)
ps.println(s"${Instant.now()} [${Thread.currentThread()}] ${ev.asString}")
else
()
def asUnsafe = this
}
def simpleF[F[_]: Sync](ps: PrintStream, minimumLevel: Level): Logger[F] =
new Logger[F] {
def log(ev: LogEvent) =
Sync[F].delay(asUnsafe.log(ev))
val asUnsafe = simple(ps, minimumLevel)
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2020 Eike K. & Contributors
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package docspell.logging
import cats.Applicative
import fs2.Stream
trait LoggerExtension[F[_]] { self: Logger[F] =>
def stream: Logger[Stream[F, *]] =
new Logger[Stream[F, *]] {
def log(ev: LogEvent) =
Stream.eval(self.log(ev))
def asUnsafe = self.asUnsafe
}
def andThen(other: Logger[F])(implicit F: Applicative[F]): Logger[F] =
AndThenLogger.combine(self, other)
def >>(other: Logger[F])(implicit F: Applicative[F]): Logger[F] =
AndThenLogger.combine(self, other)
}

View File

@ -7,10 +7,10 @@
package docspell.logging.impl
import io.circe.syntax._
import scribe.LogRecord
import scribe._
import scribe.output._
import scribe.output.format.OutputFormat
import scribe.output.{LogOutput, TextOutput}
import scribe.writer.Writer
import scribe.writer._
final case class JsonWriter(writer: Writer, compact: Boolean = true) extends Writer {
override def write[M](

View File

@ -7,10 +7,10 @@
package docspell.logging.impl
import io.circe.syntax._
import scribe.LogRecord
import scribe._
import scribe.output._
import scribe.output.format.OutputFormat
import scribe.output.{LogOutput, TextOutput}
import scribe.writer.Writer
import scribe.writer._
// https://brandur.org/logfmt
final case class LogfmtWriter(writer: Writer) extends Writer {

View File

@ -6,7 +6,7 @@
package docspell.logging.impl
import cats.effect._
import cats.effect.Sync
import docspell.logging.LogConfig
import docspell.logging.LogConfig.Format
@ -26,7 +26,7 @@ object ScribeConfigure {
def unsafeConfigure(logger: scribe.Logger, cfg: LogConfig): Unit = {
val mods = List[scribe.Logger => scribe.Logger](
_.clearHandlers(),
_.withMinimumLevel(LoggerWrapper.convertLevel(cfg.minimumLevel)),
_.withMinimumLevel(ScribeWrapper.convertLevel(cfg.minimumLevel)),
l =>
cfg.format match {
case Format.Fancy =>

View File

@ -7,14 +7,14 @@
package docspell.logging.impl
import cats.Id
import cats.effect._
import cats.effect.Sync
import docspell.logging._
import docspell.logging.{Level, LogEvent, Logger}
import scribe.LoggerSupport
import scribe.message.{LoggableMessage, Message}
private[logging] object LoggerWrapper {
private[logging] object ScribeWrapper {
final class ImplUnsafe(log: scribe.Logger) extends Logger[Id] {
override def asUnsafe = this

View File

@ -0,0 +1,33 @@
/*
* Copyright 2020 Eike K. & Contributors
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package docspell
import cats.Id
import cats.effect._
import docspell.logging.impl.ScribeWrapper
import sourcecode.Enclosing
package object logging {
def unsafeLogger(name: String): Logger[Id] =
new ScribeWrapper.ImplUnsafe(scribe.Logger(name))
def unsafeLogger(implicit e: Enclosing): Logger[Id] =
unsafeLogger(e.value)
def getLogger[F[_]: Sync](implicit e: Enclosing): Logger[F] =
getLogger(e.value)
def getLogger[F[_]: Sync](name: String): Logger[F] =
new ScribeWrapper.Impl[F](scribe.Logger(name))
def getLogger[F[_]: Sync](clazz: Class[_]): Logger[F] =
new ScribeWrapper.Impl[F](scribe.Logger(clazz.getName))
}