package org.slf4j.impl import scala.collection.immutable.ArraySeq import scala.concurrent.ExecutionContext import scala.concurrent.duration._ import _root_.monix.execution.Scheduler import _root_.monix.execution.Scheduler.Implicits.global import cats.arrow.FunctionK import cats.effect.Clock import cats.effect.ContextShift import cats.effect.Effect import cats.effect.IO import cats.effect.Timer import cats.implicits._ import io.odin._ import io.odin.json.Formatter import io.odin.slf4j.OdinLoggerBinder import io.odin.syntax._ //effect type should be specified inbefore //log line will be recorded right after the call with no suspension class StaticLoggerBinder extends OdinLoggerBinder[IO] { val ec: ExecutionContext = Scheduler.global implicit val timer: Timer[IO] = IO.timer(ec) implicit val clock: Clock[IO] = timer.clock implicit val cs: ContextShift[IO] = IO.contextShift(ec) implicit val F: Effect[IO] = IO.ioEffect val monixToCats = new FunctionK[_root_.monix.bio.Task, IO] { def apply[A](fa: _root_.monix.bio.Task[A]): IO[A] = fa.to[IO] } val (defaultConsoleLogger, release1) = consoleLogger[IO](minLevel = Level.Debug) .withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000)) .allocated .unsafeRunSync() val (mainFileLogger, release2) = fileLogger[IO]( "application-log-2.log", Formatter.json, minLevel = Level.Debug ).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000)) .allocated .unsafeRunSync() val mainFileLogger2 = mainFileLogger.contramap(lm => lm.copy(message = lm.message.map(s => fansi.Str(s).plainText)) ) val (eventBusFileLogger, release3) = fileLogger[IO]( "eventbus.log", Formatter.json, minLevel = Level.Debug ).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000)) .allocated .unsafeRunSync() { ArraySeq(release1, release2, release3).foreach(r => sys.addShutdownHook(r.unsafeRunSync()) ) } val loggers: PartialFunction[String, Logger[IO]] = { case "some.external.package.SpecificClass" => //disable noisy external logs defaultConsoleLogger.withMinimalLevel(Level.Warn) case asyncHttpClient if asyncHttpClient.startsWith("org.asynchttpclient.netty") => defaultConsoleLogger.withMinimalLevel(Level.Warn) case s if s.startsWith("com.jayfella.jme.jfx.util.JfxPlatform") => defaultConsoleLogger.withMinimalLevel(Level.Info) case s if s.startsWith( "wow.doge.mygame.subsystems.movement.PlayerMovementEventHandler" ) => defaultConsoleLogger.withMinimalLevel(Level.Info) case s if s.startsWith( "wow.doge.mygame.game.entities.NpcMovementActor" ) => defaultConsoleLogger.withMinimalLevel(Level.Trace) |+| mainFileLogger2 .withMinimalLevel(Level.Trace) // defaultConsoleLogger.withMinimalLevel( Level.Trace) //selectively turn on trace logging for specific classes case s if s.startsWith("wow.doge.mygame.subsystems.events.EventBus") => defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| eventBusFileLogger case s if s.startsWith("akka.actor") || s.startsWith("wow.doge.mygame") => defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| mainFileLogger2 case _ => //if wildcard case isn't provided, default logger is no-op defaultConsoleLogger.withMinimalLevel(Level.Debug) } } object StaticLoggerBinder extends StaticLoggerBinder { var REQUESTED_API_VERSION: String = "1.7" def getSingleton: StaticLoggerBinder = this }