All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.model3.logging.logback.LogbackLoggerFactory.scala Maven / Gradle / Ivy

The newest version!
package net.model3.logging.logback

import a8.common.logging.{Level, Logger, LoggerFactory, LoggingBootstrapConfig}
import ch.qos.logback.classic.LoggerContext
import org.slf4j.MDC
import ch.qos.logback.classic.Level as LogbackLevel
import ch.qos.logback.core.status.{Status, StatusListener}
import org.slf4j.event.EventConstants

import scala.collection.concurrent.TrieMap
import scala.concurrent.Promise

object LogbackLoggerFactory extends LoggerFactory {

  type LogbackLevel = ch.qos.logback.classic.Level

  val nestedContextThreadLocal = new ThreadLocal[Vector[String]]

  val loggerContext: LoggerContext = org.slf4j.LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]

  private[logback] lazy val loggingConfiguredPromise = Promise[Unit]()

  lazy val loggingConfiguredFuture = loggingConfiguredPromise.future

  private final lazy val m3ToLogbackLevelMap: Map[Level, LogbackLevel] =
    Map(
      Level.All -> LogbackLevel.ALL,
      Level.Debug -> LogbackLevel.DEBUG,
      Level.Error -> LogbackLevel.ERROR,
      Level.Fatal -> LogbackLevel.ERROR,
      Level.Info -> LogbackLevel.INFO,
      Level.Off -> LogbackLevel.OFF,
      Level.Trace -> LogbackLevel.TRACE,
      Level.Warn -> LogbackLevel.WARN
    )

  final lazy val m3ToLogbackLevelIntMap: Map[Level, Int] =
    Map(
      Level.Debug -> EventConstants.DEBUG_INT,
      Level.Error -> EventConstants.ERROR_INT,
      Level.Fatal -> EventConstants.ERROR_INT,
      Level.Info -> EventConstants.INFO_INT,
      Level.Trace -> EventConstants.TRACE_INT,
      Level.Warn -> EventConstants.WARN_INT,
    )

  private final lazy val logbackToM3LevelMap =
    m3ToLogbackLevelMap.map(t => t._2 -> t._1)

  final val loggerMap = TrieMap.empty[String,Logger]

  override def logger(category: String): Logger = {
    loggerMap.getOrElseUpdate(category, createLoggerImpl(category))
  }

  protected def createLoggerImpl(category: String): Logger = {
    val delegate = loggerContext.getLogger(category)
    LogbackLogger(this, delegate)
  }

  def model3Level(level: LogbackLevel): Level =
    logbackToM3LevelMap(level)

  def logbackLevel(level: Level): LogbackLevel =
    m3ToLogbackLevelMap(level)

  /**
   * simulating NDC behaviour in logback
   *
   * @param ndcValue
   * @param fn
   * @tparam A
   * @return
   */
  override def withContext[A](ndcValue: String)(fn: => A): A = {

    val mdcKey = "ndc"

    val savedMdc = Option(MDC.get(mdcKey))

    val newNdc =
      savedMdc match {
        case None =>
          ndcValue
        case Some(s) =>
          s + " " + ndcValue
      }

    try {
      MDC.put(mdcKey, newNdc)
      fn
    } finally {
      savedMdc match {
        case None =>
          MDC.remove(mdcKey)
        case Some(v) =>
          MDC.put(mdcKey, v)
      }
    }
  }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy