I am attempting to use LoggingConfigurator
to configure a ConsoleAppender
with a JsonEncoder
to print JSON logs. However, the program prints plain text logs instead.
$ scala-cli .
16:57:51.531 [io-compute-5] DEBUG myapp.App -- Hello, world!
I expected the output to be in JSON format:
$ scala-cli .
{"timestamp": "2023-06-24T16:57:51.531+0500", "level": "DEBUG", "name": "myapp.App", "msg": "Hello, world!"}
What am I doing wrong?
app.scala
//> using scala 3
//> using resourceDir ./resources
//> using dep org.typelevel::log4cats-slf4j:2.6.0
//> using dep ch.qos.logback:logback-classic:1.4.8
//> using dep org.typelevel::cats-core:2.9.0
//> using dep org.typelevel::cats-effect:3.5.1
//> using dep com.monovore::decline:2.4.1
//> using dep com.monovore::decline-effect:2.4.1
package myapp
import cats.effect.{ExitCode, IO, Sync}
import cats.implicits._
import org.typelevel.log4cats.slf4j.Slf4jFactory
import org.typelevel.log4cats.{LoggerFactory, SelfAwareStructuredLogger}
import com.monovore.decline.effect.CommandIOApp
import com.monovore.decline.Opts
import org.typelevel.log4cats.syntax._
class LoggingConfigurator
extends ch.qos.logback.core.spi.ContextAwareBase
with ch.qos.logback.classic.spi.Configurator {
override final def configure(
loggerContext: ch.qos.logback.classic.LoggerContext,
): ch.qos.logback.classic.spi.Configurator.ExecutionStatus = {
val encoder = new ch.qos.logback.classic.encoder.JsonEncoder
encoder.setContext(loggerContext)
encoder.start()
val appender = new ch.qos.logback.core.ConsoleAppender[ch.qos.logback.classic.spi.ILoggingEvent]
appender.setContext(loggerContext)
appender.setTarget("System.err")
appender.setEncoder(encoder)
appender.start()
val logger = loggerContext.getLogger("ROOT")
logger.addAppender(appender)
logger.setLevel(ch.qos.logback.classic.Level.DEBUG)
logger.setAdditive(false)
ch.qos.logback.classic.spi.Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY
}
}
trait Logging[F[_]: Sync] {
private given LoggerFactory[F] = Slf4jFactory.create[F]
inline protected given SelfAwareStructuredLogger[F] = LoggerFactory[F].getLogger
}
object App extends CommandIOApp("myapp", "an app", true, "0.0.1") with Logging[IO] {
override final def main: Opts[IO[ExitCode]] =
Opts.unit map { _ =>
for {
_ <- debug"Hello, world!"
} yield ExitCode.Success
}
}
resources/META-INF/services/ch.qos.logback.classic.spi.Configurator
myapp.LoggingConfigurator
I am attempting to configure a ConsoleAppender
with a JsonEncoder
to print JSON logs. However, the program prints plain text logs instead:
$ scala-cli .
16:57:51.531 [io-compute-5] DEBUG myapp.App -- Hello, world!
I expected the output to be in JSON format:
$ scala-cli .
{"timestamp": "2023-06-24T16:57:51.531+0500", "level": "DEBUG", "name": "myapp.App", "msg": "Hello, world!"}
What am I doing wrong?