Skip to content

Commit 5cd9b18

Browse files
authored
Merge pull request #1535 from eikek/logging-improvements
Improve logging configuration
2 parents c4c5985 + 5bdf728 commit 5cd9b18

File tree

12 files changed

+90
-50
lines changed

12 files changed

+90
-50
lines changed

modules/fts-psql/src/test/scala/docspell/ftspsql/MigrationTest.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ class MigrationTest
2727
PostgreSQLContainer.Def(DockerImageName.parse("postgres:14"))
2828

2929
override def docspellLogConfig: LogConfig =
30-
LogConfig(Level.Debug, LogConfig.Format.Fancy)
31-
32-
override def rootMinimumLevel = Level.Warn
30+
super.docspellLogConfig.docspellLevel(Level.Debug)
3331

3432
test("create schema") {
3533
withContainers { cnt =>

modules/fts-psql/src/test/scala/docspell/ftspsql/PsqlFtsClientTest.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ class PsqlFtsClientTest
3131
private val table = FtsRepository.table
3232

3333
override def docspellLogConfig: LogConfig =
34-
LogConfig(Level.Debug, LogConfig.Format.Fancy)
35-
36-
override def rootMinimumLevel = Level.Warn
34+
super.docspellLogConfig.docspellLevel(Level.Debug)
3735

3836
test("insert data into index") {
3937
withContainers { cnt =>

modules/joex/src/main/resources/reference.conf

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ docspell.joex {
2626

2727
# The minimum level to log. From lowest to highest:
2828
# Trace, Debug, Info, Warn, Error
29-
minimum-level = "Info"
29+
minimum-level = "Warn"
30+
31+
# Override the log level of specific loggers
32+
levels = {
33+
"docspell" = "Info"
34+
"org.flywaydb" = "Info"
35+
"binny" = "Info"
36+
"org.http4s" = "Info"
37+
}
3038
}
3139

3240
# The database connection.

modules/logging/api/src/main/scala/docspell/logging/LogConfig.scala

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,26 @@ import cats.data.NonEmptyList
1010

1111
import io.circe.{Decoder, Encoder}
1212

13-
final case class LogConfig(minimumLevel: Level, format: LogConfig.Format) {}
13+
final case class LogConfig(
14+
minimumLevel: Level,
15+
format: LogConfig.Format,
16+
levels: LogConfig.ExtraLevels
17+
) {
18+
19+
def clearLevels: LogConfig =
20+
copy(levels = Map.empty)
21+
22+
def withLevel(logger: String, level: Level): LogConfig =
23+
copy(levels = levels.updated(logger, level))
24+
25+
def docspellLevel(level: Level): LogConfig =
26+
withLevel("docspell", level)
27+
}
1428

1529
object LogConfig {
1630

31+
type ExtraLevels = Map[String, Level]
32+
1733
sealed trait Format { self: Product =>
1834
def name: String =
1935
productPrefix.toLowerCase
@@ -38,8 +54,10 @@ object LogConfig {
3854
}
3955

4056
implicit val jsonDecoder: Decoder[LogConfig] =
41-
Decoder.forProduct2("minimumLevel", "format")(LogConfig.apply)
57+
Decoder.forProduct3("minimumLevel", "format", "levels")(LogConfig.apply)
4258

4359
implicit val jsonEncoder: Encoder[LogConfig] =
44-
Encoder.forProduct2("minimumLevel", "format")(r => (r.minimumLevel, r.format))
60+
Encoder.forProduct3("minimumLevel", "format", "levels")(r =>
61+
(r.minimumLevel, r.format, r.levels)
62+
)
4563
}

modules/logging/api/src/main/scala/docspell/logging/LogEvent.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ final case class LogEvent(
2626
def data[A: Encoder](key: String, value: => A): LogEvent =
2727
copy(data = data.updated(key, () => Encoder[A].apply(value)))
2828

29+
def addData(m: Map[String, Json]): LogEvent =
30+
copy(data = data ++ m.view.mapValues(json => () => json).toMap)
31+
2932
def addMessage(msg: => String): LogEvent =
3033
copy(additional = (() => Left(msg)) :: additional)
3134

modules/logging/scribe/src/main/scala/docspell/logging/impl/ScribeConfigure.scala

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,36 @@ import scribe.jul.JULHandler
1616
import scribe.writer.SystemOutWriter
1717

1818
object ScribeConfigure {
19-
private[this] val docspellRootVerbose = "DOCSPELL_ROOT_LOGGER_LEVEL"
20-
2119
def configure[F[_]: Sync](cfg: LogConfig): F[Unit] =
2220
Sync[F].delay {
2321
replaceJUL()
24-
val docspellLogger = scribe.Logger("docspell")
22+
unsafeConfigure(cfg)
23+
}
2524

26-
unsafeConfigure(scribe.Logger.root, cfg.copy(minimumLevel = getRootMinimumLevel))
27-
unsafeConfigure(docspellLogger, cfg)
28-
unsafeConfigure(scribe.Logger("org.flywaydb"), cfg)
29-
unsafeConfigure(scribe.Logger("binny"), cfg)
30-
unsafeConfigure(scribe.Logger("org.http4s"), cfg)
25+
def unsafeConfigure(cfg: LogConfig): Unit = {
26+
unsafeConfigure(scribe.Logger.root, cfg.format, cfg.minimumLevel)
27+
cfg.levels.foreach { case (name, level) =>
28+
unsafeConfigure(scribe.Logger(name), cfg.format, level)
3129
}
30+
}
3231

33-
private[this] def getRootMinimumLevel: Level =
34-
Option(System.getenv(docspellRootVerbose))
35-
.map(Level.fromString)
36-
.flatMap {
37-
case Right(level) => Some(level)
38-
case Left(err) =>
39-
scribe.warn(
40-
s"Environment variable '$docspellRootVerbose' has invalid value: $err"
41-
)
42-
None
43-
}
44-
.getOrElse(Level.Error)
32+
def unsafeConfigure(logger: String, cfg: LogConfig): Unit = {
33+
val log = scribe.Logger(logger)
34+
val level = cfg.levels.getOrElse(logger, cfg.minimumLevel)
35+
unsafeConfigure(log, cfg.format, level)
36+
}
4537

46-
def unsafeConfigure(logger: scribe.Logger, cfg: LogConfig): Unit = {
38+
def unsafeConfigure(
39+
logger: scribe.Logger,
40+
format: LogConfig.Format,
41+
level: Level
42+
): Unit = {
4743
val mods = List[scribe.Logger => scribe.Logger](
4844
_.clearHandlers(),
49-
_.withMinimumLevel(ScribeWrapper.convertLevel(cfg.minimumLevel)),
45+
_.withMinimumLevel(ScribeWrapper.convertLevel(level)),
5046
l =>
5147
if (logger.id == scribe.Logger.RootId) {
52-
cfg.format match {
48+
format match {
5349
case Format.Fancy =>
5450
l.withHandler(formatter = Formatter.enhanced, writer = SystemOutWriter)
5551
case Format.Plain =>

modules/logging/scribe/src/test/scala/docspell/logging/TestLoggingConfig.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ import docspell.logging.impl.ScribeConfigure
1111
import munit.Suite
1212

1313
trait TestLoggingConfig extends Suite {
14-
def docspellLogConfig: LogConfig = LogConfig(Level.Warn, LogConfig.Format.Fancy)
14+
def docspellLogConfig: LogConfig =
15+
LogConfig(rootMinimumLevel, LogConfig.Format.Fancy, Map.empty)
16+
1517
def rootMinimumLevel: Level = Level.Error
1618

1719
override def beforeAll(): Unit = {
1820
super.beforeAll()
19-
val docspellLogger = scribe.Logger("docspell")
20-
ScribeConfigure.unsafeConfigure(docspellLogger, docspellLogConfig)
21-
val rootCfg = docspellLogConfig.copy(minimumLevel = rootMinimumLevel)
22-
ScribeConfigure.unsafeConfigure(scribe.Logger.root, rootCfg)
23-
()
21+
ScribeConfigure.unsafeConfigure(docspellLogConfig)
2422
}
25-
2623
}

modules/restserver/src/main/resources/reference.conf

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@ docspell.server {
2929

3030
# The minimum level to log. From lowest to highest:
3131
# Trace, Debug, Info, Warn, Error
32-
minimum-level = "Info"
32+
minimum-level = "Warn"
33+
34+
# Override the log level of specific loggers
35+
levels = {
36+
"docspell" = "Info"
37+
"org.flywaydb" = "Info"
38+
"binny" = "Info"
39+
"org.http4s" = "Info"
40+
}
3341
}
3442

3543
# Where the server binds to.

modules/scheduler/impl/src/main/scala/docspell/scheduler/impl/LogEvent.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import cats.implicits._
1111

1212
import docspell.common._
1313

14+
import io.circe.Json
15+
1416
case class LogEvent(
1517
jobId: Ident,
1618
taskName: Ident,
@@ -19,7 +21,8 @@ case class LogEvent(
1921
time: Timestamp,
2022
level: LogLevel,
2123
msg: String,
22-
ex: Option[Throwable] = None
24+
ex: Option[Throwable],
25+
data: Map[String, Json]
2326
) {
2427

2528
def logLine: String =
@@ -35,10 +38,11 @@ object LogEvent {
3538
group: Ident,
3639
jobInfo: String,
3740
level: LogLevel,
38-
msg: String
41+
msg: String,
42+
data: Map[String, Json]
3943
): F[LogEvent] =
4044
Timestamp
4145
.current[F]
42-
.map(now => LogEvent(jobId, taskName, group, jobInfo, now, level, msg))
46+
.map(now => LogEvent(jobId, taskName, group, jobInfo, now, level, msg, None, data))
4347

4448
}

modules/scheduler/impl/src/main/scala/docspell/scheduler/impl/LogSink.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ object LogSink {
2929
}
3030

3131
def logInternal[F[_]: Sync](e: LogEvent): F[Unit] = {
32-
val logger = docspell.logging.getLogger[F]
32+
val logger = docspell.logging.getLogger[F](e.taskName.id)
3333
val addData: logging.LogEvent => logging.LogEvent =
3434
_.data("jobId", e.jobId)
3535
.data("task", e.taskName)
3636
.data("group", e.group)
3737
.data("jobInfo", e.jobInfo)
38+
.addData(e.data)
3839

3940
e.level match {
4041
case LogLevel.Info =>

0 commit comments

Comments
 (0)