ch.qos.logback.classic.spi.ILoggingEvent Scala Examples

The following examples show how to use ch.qos.logback.classic.spi.ILoggingEvent. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: ManualChangesSummarySubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report.impl

import java.io.OutputStream
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._


class ManualChangesSummarySubscriber extends IReportEventSubscriber[(String, Int)] {

  private[this] var manualChanges = Map.empty[String, Int]

  override def filter(event: scala.Any): Optional[(String, Int)] = {
    val Regex = """Rule (.*) requires (\d+) manual changes""".r
    val info = event match {
      case event1: ILoggingEvent =>
        event1.getFormattedMessage match {
          case Regex(rule, num) => Some((rule, num.toInt))
          case _ => None
        }
      case _ => None
    }

    info.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (manualChanges.nonEmpty) {
    val outputTemplate = "\r## Manual Changes Required\n\n| Rule | Details |\n| ---- | ----------- |\n"
    val content = manualChanges.foldLeft(outputTemplate) {(c, summary) =>
      c + s"|[${summary._1}](#${summary._1.split("\\.").lastOption getOrElse ""}) | ${summary._2} manual changes required |\n"
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: (String, Int)): Unit = manualChanges get event._1 match {
    case Some(num) => manualChanges += event._1 -> (event._2 + num)
    case None => manualChanges += event._1 -> event._2
  }

  override val sequence = 4
} 
Example 2
Source File: Logger.scala    From shapenet-viewer   with MIT License 5 votes vote down vote up
package edu.stanford.graphics.shapenet.util

import org.slf4j.LoggerFactory
import java.io.File

import org.slf4j.bridge.SLF4JBridgeHandler
import uk.org.lidalia.sysoutslf4j.context.SysOutOverSLF4J


                   additive: Boolean = false) = {
    import ch.qos.logback.classic.spi.ILoggingEvent
    import ch.qos.logback.classic.Level
    import ch.qos.logback.classic.LoggerContext
    import ch.qos.logback.classic.encoder.PatternLayoutEncoder
    import ch.qos.logback.core.FileAppender

    // Make sure log directory is created
    val file: File = new File(filename)
    val parent: File = file.getParentFile
    if (parent != null) parent.mkdirs

    val loggerContext = LoggerFactory.getILoggerFactory().asInstanceOf[LoggerContext]
    val logger = loggerContext.getLogger(loggerName)

    // Setup pattern
    val patternLayoutEncoder = new PatternLayoutEncoder()
    patternLayoutEncoder.setPattern(pattern)
    patternLayoutEncoder.setContext(loggerContext)
    patternLayoutEncoder.start()

    // Setup appender
    val fileAppender = new FileAppender[ILoggingEvent]()
    fileAppender.setFile(filename)
    fileAppender.setEncoder(patternLayoutEncoder)
    fileAppender.setContext(loggerContext)
    fileAppender.start()

    // Attach appender to logger
    logger.addAppender(fileAppender)
    //logger.setLevel(Level.DEBUG)
    logger.setAdditive(additive)

    fileAppender.getName
  }

  def detachAppender(appenderName: String, loggerName: String = org.slf4j.Logger.ROOT_LOGGER_NAME): Unit = {
    import ch.qos.logback.classic.LoggerContext

    val loggerContext = LoggerFactory.getILoggerFactory().asInstanceOf[LoggerContext]
    val logger = loggerContext.getLogger(loggerName)
    logger.detachAppender(appenderName)
  }

  def getLogger(clazz: Class[_]): org.slf4j.Logger = {
    LoggerFactory.getLogger(clazz)
  }

  def getLogger(name: String): org.slf4j.Logger = {
    LoggerFactory.getLogger(name)
  }
}

trait Loggable {
  lazy val logger = Logger.getLogger(this.getClass)

  def startTrack(name: String): Unit = {
    logger.debug("Starting " + name)
  }

  def endTrack(name: String): Unit = {
    logger.debug("Finished " + name)
  }
} 
Example 3
Source File: LogPublisherHub.scala    From vamp   with Apache License 2.0 5 votes vote down vote up
package io.vamp.common.akka

import akka.actor.{ ActorRef, ActorSystem }
import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.classic.{ Level, LoggerContext, Logger ⇒ LogbackLogger }
import ch.qos.logback.core.AppenderBase
import io.vamp.common.Namespace
import org.slf4j.{ Logger, LoggerFactory }

import scala.collection.mutable

object LogPublisherHub {

  private val logger = LoggerFactory.getLogger(LogPublisherHub.getClass)

  private val context = LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
  private val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME)

  private val sessions: mutable.Map[String, LogPublisher] = new mutable.HashMap()

  def subscribe(to: ActorRef, level: String, loggerName: Option[String], encoder: (ILoggingEvent) ⇒ AnyRef)(implicit actorSystem: ActorSystem, namespace: Namespace): Unit = {
    val appenderLevel = Level.toLevel(level, Level.INFO)
    val appenderLogger = loggerName.map(context.getLogger).getOrElse(rootLogger)

    val exists = sessions.get(to.toString).exists { publisher ⇒
      publisher.level == appenderLevel && publisher.logger.getName == appenderLogger.getName
    }

    if (!exists) {
      unsubscribe(to)
      if (appenderLevel != Level.OFF) {
        logger.info(s"Starting log publisher [${appenderLevel.levelStr}] '${appenderLogger.getName}': $to")
        val publisher = LogPublisher(to, appenderLogger, appenderLevel, encoder)
        publisher.start()
        sessions.put(to.toString, publisher)
      }
    }
  }

  def unsubscribe(to: ActorRef): Unit = {
    sessions.remove(to.toString).foreach { publisher ⇒
      logger.info(s"Stopping log publisher: $to")
      publisher.stop()
    }
  }
}

private case class LogPublisher(to: ActorRef, logger: LogbackLogger, level: Level, encoder: (ILoggingEvent) ⇒ AnyRef)(implicit actorSystem: ActorSystem, namespace: Namespace) {

  private val filter = new ThresholdFilter()
  filter.setLevel(level.levelStr)

  private val appender = new AppenderBase[ILoggingEvent] {
    override def append(loggingEvent: ILoggingEvent) = to ! encoder(loggingEvent)
  }

  appender.addFilter(filter)
  appender.setName(to.toString)

  def start() = {
    val context = logger.getLoggerContext
    filter.setContext(context)
    appender.setContext(context)
    filter.start()
    appender.start()
    logger.addAppender(appender)
  }

  def stop() = {
    appender.stop()
    filter.stop()
    logger.detachAppender(appender)
  }
} 
Example 4
Source File: LogApiController.scala    From vamp   with Apache License 2.0 5 votes vote down vote up
package io.vamp.operation.controller

import java.time.{ OffsetDateTime, ZoneId }
import java.util.Date

import akka.actor.{ ActorRef, Props }
import akka.stream.actor.ActorPublisher
import akka.stream.actor.ActorPublisherMessage.{ Cancel, Request }
import akka.stream.scaladsl.Source
import ch.qos.logback.classic.spi.ILoggingEvent
import akka.http.scaladsl.model.sse.ServerSentEvent
import io.vamp.common.Namespace
import io.vamp.common.akka._
import io.vamp.common.json.{ OffsetDateTimeSerializer, SerializationFormat }
import org.json4s.native.Serialization._

import scala.concurrent.duration.FiniteDuration

case class LogEvent(logger: String, level: String, message: String, timestamp: OffsetDateTime)

trait LogApiController extends AbstractController {

  private val eventType = "log"

  def sourceLog(level: String, logger: Option[String], keepAlivePeriod: FiniteDuration)(implicit namespace: Namespace): Source[ServerSentEvent, ActorRef] = {
    Source.actorPublisher[ServerSentEvent](Props(new ActorPublisher[ServerSentEvent] {
      def receive: Receive = {
        case Request(_) ⇒ openLogStream(self, level, logger, { event ⇒
          ServerSentEvent(write(encode(event))(SerializationFormat(OffsetDateTimeSerializer)), eventType)
        })
        case Cancel                                  ⇒ closeLogStream(self)
        case sse: ServerSentEvent if totalDemand > 0 ⇒ onNext(sse)
        case _                                       ⇒
      }

    })).keepAlive(keepAlivePeriod, () ⇒ ServerSentEvent.heartbeat)
  }

  def openLogStream(to: ActorRef, level: String, logger: Option[String], encoder: (ILoggingEvent) ⇒ AnyRef)(implicit namespace: Namespace): Unit = {
    LogPublisherHub.subscribe(to, level, logger, encoder)
  }

  def closeLogStream(to: ActorRef): Unit = LogPublisherHub.unsubscribe(to)

  def encode(loggingEvent: ILoggingEvent) = LogEvent(
    loggingEvent.getLoggerName,
    loggingEvent.getLevel.toString,
    loggingEvent.getFormattedMessage,
    OffsetDateTime.ofInstant(new Date(loggingEvent.getTimeStamp).toInstant, ZoneId.of("UTC"))
  )
} 
Example 5
Source File: LogbackAppender.scala    From rollbar-scala   with MIT License 5 votes vote down vote up
package com.storecove.rollbar.appenders

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.{ILoggingEvent, ThrowableProxy}
import ch.qos.logback.core.UnsynchronizedAppenderBase
import org.apache.log4j.helpers.LogLog


class LogbackAppender extends UnsynchronizedAppenderBase[ILoggingEvent] with AbstractAppender {

    override def append(event: ILoggingEvent): Unit = {
        if (enabled) {
            try {
                if (event.getLevel.isGreaterOrEqual(notifyLevel)) {
                    val hasThrowable = event.getThrowableProxy != null
                    if (!onlyThrowable || hasThrowable) {
                        rollbarNotifier.notify(event.getLevel.toString, event.getMessage, getThrowable(event), getMDCContext)
                    }
                }
            } catch {
                case e: Exception => LogLog.error("Error sending error notification! error=" + e.getClass.getName + " with message=" + e.getMessage)
            }
        }
    }

    override def start(): Unit = {
        if (this.apiKey == null || this.apiKey.isEmpty) {
            this.addError("No apiKey set for the appender named [" + getName + "].")
        } else if (this.environment == null || this.environment.isEmpty) {
            this.addError("No environment set for the appender named [" + getName + "].")
        } else {
            super.start()
        }
    }

    protected def getThrowable(event: ILoggingEvent): Option[Throwable] = {
        event.getThrowableProxy match {
            case throwableProxy: ThrowableProxy => Some(throwableProxy.getThrowable)
            case _ => None
        }
    }

    override def notifyLevel: Level = Level.toLevel(notifyLevelString)

    def setNotifyLevel(notifyLevel: String): Unit = notifyLevelString = notifyLevel

} 
Example 6
Source File: ZLogsSuite.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu.logging.zlogs

import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.read.ListAppender
import derevo.derive
import io.circe.JsonObject
import io.circe.syntax._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.slf4j.LoggerFactory
import tofu.logging.LogTree
import tofu.logging.derivation.loggable
import tofu.logging.impl.ContextMarker
import tofu.syntax.logging._
import zio.blocking.Blocking
import zio.clock.Clock
import zio.console.Console
import zio.{Has, Runtime, URIO, URLayer, ZLayer}

import scala.jdk.CollectionConverters._

class ZLogsSuite extends AnyFlatSpec with Matchers {
  import ZLogsSuite.MyLogging

  val expr = debug"hello" *> info"world"

  "ZLogs" should "log the context" in {
    val appender = ZLogsSuite.attachList()
    Runtime.default.unsafeRun(expr.provideLayer(ZLogsSuite.fullLayer))
    val items    = appender.list.asScala

    val expected = JsonObject("foo" -> "kojima".asJson, "bar" -> 2.asJson).asJson

    items.map(_.getMarker).collect {
      case ContextMarker(ctx, _) => LogTree(ctx)
    } should ===(List.fill(2)(expected))
  }
}

object ZLogsSuite {
  val Name = "zio logs suite"

  @derive(loggable)
  case class FooService(foo: String)

  val fooLayer = ZLayer.succeed(FooService("kojima"))

  @derive(loggable)
  case class BarService(bar: Int)

  val barLayer = ZLayer.succeed(BarService(2))

  type Foo = Has[FooService]
  type Bar = Has[BarService]

  type LogEnv    = Foo with Bar
  type SystemEnv = Blocking with Clock with Console
  type MyEnv     = SystemEnv with LogEnv with ZLog[LogEnv]
  type TIO[+A]   = URIO[MyEnv, A]

  val logs: ZLogs[Foo with Bar] = ZLogs.build.of[Foo].of[Bar].make

  implicit val MyLogging: ZLogging[MyEnv] = ZLogs.access[MyEnv, LogEnv]

  implicitly[ZioHasBuilder.UnHas[Foo]](ZioHasBuilder.UnHas.unHas[FooService])
  val fullLayer: URLayer[Blocking with Console with Clock, MyEnv] =
    ZLayer.identity[SystemEnv] ++ fooLayer ++ barLayer ++ ZLogs.named(logs, Name)

  def attachList() = {
    val logger   = LoggerFactory.getLogger(Name).asInstanceOf[Logger]
    val appender = new ListAppender[ILoggingEvent]
    appender.start()
    logger.addAppender(appender)
    appender
  }
} 
Example 7
Source File: ELKLayout.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu
package logging

import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.CoreConstants.{LINE_SEPARATOR => EOL}
import ch.qos.logback.core.LayoutBase
import tofu.logging.ELKLayout.Arguments
import tofu.logging.logback.EventLoggable


class ELKLayout extends LayoutBase[ILoggingEvent] {
  private var arguments: Arguments = Arguments.Merge

  private[this] implicit var eventLoggable: Loggable[ILoggingEvent] = EventLoggable.merge

  def setArgumentsField(name: String): Unit = {
    arguments = Arguments.Collect(name)
    updateEventLoggable()
  }
  def setArguments(value: String): Unit = {
    arguments = Arguments.parse(value)
    updateEventLoggable()
  }

  private def updateEventLoggable(): Unit =
    eventLoggable = arguments match {
      case Arguments.Merge         => EventLoggable.merge
      case Arguments.Group         => EventLoggable.group
      case Arguments.Collect(name) => EventLoggable.collect(name)
    }

  override def doLayout(event: ILoggingEvent): String =
    ELKLayout.builder(event)
}

object ELKLayout {

  val MarkersField    = "markers"
  val TimeStampField  = "@timestamp"
  val LoggerNameField = "loggerName"
  val ThreadNameField = "threadName"
  val LevelField      = "level"
  val HostNameField   = "hostName"
  val MessageField    = "message"
  val MessageIdField  = "messageId"
  val ExceptionField  = "exception"
  val StackTraceField = "stackTrace"

  val builder: TethysBuilder = TethysBuilder(postfix = EOL)

  sealed trait Arguments

  object Arguments {
    case object Merge                 extends Arguments
    case object Group                 extends Arguments
    case class Collect(field: String) extends Arguments

    def parse(name: String): Arguments = name match {
      case "merge" => Merge
      case "group" => Group
    }
  }

  case class ArgumentParsingException(value: String) extends RuntimeException(s"could not parse $value")
} 
Example 8
Source File: LogColors.scala    From graphql-gateway   with Apache License 2.0 5 votes vote down vote up
package sangria.gateway.util

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.pattern.color.ForegroundCompositeConverterBase
import ch.qos.logback.core.pattern.color.ANSIConstants._

class LogColors extends ForegroundCompositeConverterBase[ILoggingEvent] {
  override def getForegroundColorCode(event: ILoggingEvent): String =
    event.getLevel.toInt match {
      case Level.ERROR_INT ⇒
        BOLD + RED_FG
      case Level.WARN_INT ⇒
        YELLOW_FG
      case Level.INFO_INT ⇒
        GREEN_FG
      case Level.DEBUG_INT ⇒
        CYAN_FG
      case _ ⇒
        DEFAULT_FG
    }
} 
Example 9
Source File: JsonEncoderSpec.scala    From logback-json-logger   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.play.logging
import java.io.{PrintWriter, StringWriter}
import java.net.InetAddress

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.{ILoggingEvent, ThrowableProxy}
import ch.qos.logback.core.ContextBase
import org.apache.commons.lang3.time.FastDateFormat
import org.mockito.Mockito.when
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatestplus.mockito.MockitoSugar
import play.api.libs.json.{JsLookupResult, Json}

import scala.collection.JavaConverters._

class JsonEncoderSpec extends AnyWordSpec with Matchers with MockitoSugar {

  "Json-encoded message" should {
    "contain all required fields" in {

      val jsonEncoder = new JsonEncoder()
      val event       = mock[ILoggingEvent]

      when(event.getTimeStamp).thenReturn(1)
      when(event.getLevel).thenReturn(Level.INFO)
      when(event.getThreadName).thenReturn("my-thread")
      when(event.getFormattedMessage).thenReturn("my-message")
      when(event.getLoggerName).thenReturn("logger-name")
      when(event.getMDCPropertyMap).thenReturn(Map("myMdcProperty" -> "myMdcValue").asJava)

      val testException = new Exception("test-exception")
      val stringWriter  = new StringWriter()
      testException.printStackTrace(new PrintWriter(stringWriter))
      when(event.getThrowableProxy).thenReturn(new ThrowableProxy(testException))

      jsonEncoder.setContext {
        val ctx = new ContextBase()
        ctx.putProperty("myKey", "myValue")
        ctx
      }

      val result       = new String(jsonEncoder.encode(event), "UTF-8")
      val resultAsJson = Json.parse(result)

      (resultAsJson \ "app").asString           shouldBe "my-app-name"
      (resultAsJson \ "hostname").asString      shouldBe InetAddress.getLocalHost.getHostName
      (resultAsJson \ "timestamp").asString     shouldBe FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSSZZ").format(1)
      (resultAsJson \ "message").asString       shouldBe "my-message"
      (resultAsJson \ "exception").asString     should include("test-exception")
      (resultAsJson \ "exception").asString     should include("java.lang.Exception")
      (resultAsJson \ "exception").asString     should include(stringWriter.toString)
      (resultAsJson \ "logger").asString        shouldBe "logger-name"
      (resultAsJson \ "thread").asString        shouldBe "my-thread"
      (resultAsJson \ "level").asString         shouldBe "INFO"
      (resultAsJson \ "mykey").asString         shouldBe "myValue"
      (resultAsJson \ "mymdcproperty").asString shouldBe "myMdcValue"

    }
  }

  implicit class JsLookupResultOps(jsLookupResult: JsLookupResult) {
    def asString: String = jsLookupResult.get.as[String]
  }

} 
Example 10
Source File: ReportEventPublisher.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report

import java.io.OutputStream

import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.AppenderBase
import com.ebay.rtran.report.api.IReportEventSubscriber


class ReportEventPublisher extends AppenderBase[ILoggingEvent] {

  private[this] var _subscribers = List.empty[IReportEventSubscriber[_]]

  setName("ReportEventPublisher")

  override def append(eventObject: ILoggingEvent): Unit = {
    _subscribers foreach {_.accept(eventObject)}
  }

  def startWithSubscribers(subscribers: List[IReportEventSubscriber[_]]): Unit = {
    _subscribers = subscribers
    super.start()
  }

  def stopAndSave(outputStream: OutputStream): Unit = {
    _subscribers foreach (_ dumpTo outputStream)
    outputStream.flush()
    outputStream.close()
    super.stop()
  }
} 
Example 11
Source File: ReportAndLogSupport.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report

import java.io.{File, FileOutputStream}

import ch.qos.logback.classic
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.FileAppender
import org.reflections.Reflections
import com.ebay.rtran.report.api.IReportEventSubscriber
import org.slf4j.{Logger, LoggerFactory}

import scala.collection.JavaConversions._
import scala.language.postfixOps
import scala.util.{Success, Try}


trait ReportAndLogSupport {

  val reportFilePrefix: String
  val warnLogPrefix: String
  val debugLogPrefix: String

  def createReportAndLogs[T](projectRoot: File,
                             taskId: Option[String], packages: String*)(fn: => T): T = {
    val appenders = prepareAppenders(projectRoot, taskId)
    val rootLogger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME).asInstanceOf[classic.Logger]
    appenders foreach rootLogger.addAppender
    appenders foreach (_.start)
    val reportFile = new File(projectRoot, s"$reportFilePrefix${taskId.map("-" + _) getOrElse ""}.md")
    val result = Report.createReport(
      new FileOutputStream(reportFile),
      subscribers = allSubscribers(projectRoot, packages: _*)
    )(fn)
    appenders foreach (_.stop)
    appenders foreach rootLogger.detachAppender
    result
  }

  def allSubscribers(projectRoot: File, packages: String*) = {
    val subscribers = packages flatMap {prefix =>
      new Reflections(prefix).getSubTypesOf(classOf[IReportEventSubscriber[_]])
    } map {clazz =>
      Try(clazz.getDeclaredConstructor(classOf[File]).newInstance(projectRoot)) orElse Try(clazz.newInstance)
    } collect {
      case Success(subscriber) => subscriber
    } toList

    subscribers.sortBy(_.sequence)
  }

  private def prepareAppenders(projectRoot: File, taskId: Option[String]) = {
    val lc = LoggerFactory.getILoggerFactory.asInstanceOf[classic.LoggerContext]
    val encoders = Array(new PatternLayoutEncoder, new PatternLayoutEncoder)
    encoders foreach (_ setContext lc)
    encoders foreach (_ setPattern "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}.%M:%L - %m%n")
    encoders foreach (_.start)

    val warnFileAppender = new FileAppender[ILoggingEvent]
    warnFileAppender.setName("warnFileAppender")
    warnFileAppender.setFile(s"${projectRoot.getAbsolutePath}/$warnLogPrefix${taskId.map("-" + _) getOrElse ""}.log")
    warnFileAppender.addFilter(new SameThreadFilter)
    val warnFilter = new ThresholdFilter
    warnFilter.setLevel("WARN")
    warnFilter.start()
    warnFileAppender.addFilter(warnFilter)

    val debugFileAppender = new FileAppender[ILoggingEvent]
    debugFileAppender.setName("debugFileAppender")
    debugFileAppender.setFile(s"${projectRoot.getAbsolutePath}/$debugLogPrefix${taskId.map("-" + _) getOrElse ""}.log")
    debugFileAppender.addFilter(new SameThreadFilter)
    val debugFilter = new ThresholdFilter
    debugFilter.setLevel("DEBUG")
    debugFilter.start()
    debugFileAppender.addFilter(debugFilter)

    val result = List(warnFileAppender, debugFileAppender)
    result.foreach(_ setContext lc)
    result zip encoders foreach (entry => entry._1 setEncoder entry._2)
    result
  }
} 
Example 12
Source File: UpgradeSummarySubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report.impl

import java.io.OutputStream
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._


class UpgradeSummarySubscriber extends IReportEventSubscriber[(String, Int)] {

  private[this] var ruleSummary = Map.empty[String, Int]

  override def filter(event: scala.Any): Optional[(String, Int)] = {
    val Regex = """Rule (.+) was applied to (\d+).*""".r
    val info = event match {
      case event1: ILoggingEvent =>
        event1.getFormattedMessage match {
          case Regex(rule, num) => Some((rule, num.toInt))
          case _ => None
        }

      case _ => None
    }

    info.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (ruleSummary.nonEmpty) {
    val outputTemplate = "\r## Summary\n\n| Operation | Details |\n| ---- | ----------- |\n"
    val content = ruleSummary.foldLeft(outputTemplate) {(c, summary) =>
      c + s"|[${summary._1}](#${summary._1.split("\\.").lastOption getOrElse ""}) | impacted ${summary._2} file(s) |\n"
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: (String, Int)): Unit = ruleSummary get event._1 match {
    case Some(num) => ruleSummary += event._1 -> (event._2 + num)
    case None => ruleSummary += event._1 -> event._2
  }

  override val sequence = 3
} 
Example 13
Source File: LogCollector.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.platform.testing

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.AppenderBase

import scala.beans.BeanProperty
import scala.collection.concurrent.TrieMap
import scala.collection.mutable
import scala.reflect.ClassTag

object LogCollector {

  private val log =
    TrieMap
      .empty[String, TrieMap[String, mutable.Builder[(Level, String), Vector[(Level, String)]]]]

  def read[Test, Logger](
      implicit test: ClassTag[Test],
      logger: ClassTag[Logger]): IndexedSeq[(Level, String)] =
    log
      .get(test.runtimeClass.getName)
      .flatMap(_.get(logger.runtimeClass.getName))
      .fold(IndexedSeq.empty[(Level, String)])(_.result())

  def clear[Test](implicit test: ClassTag[Test]): Unit = {
    log.remove(test.runtimeClass.getName)
    ()
  }

}

final class LogCollector extends AppenderBase[ILoggingEvent] {

  @BeanProperty
  var test: String = _

  override def append(e: ILoggingEvent): Unit = {
    if (test == null) {
      addError("Test identifier undefined, skipping logging")
    } else {
      val log = LogCollector.log
        .getOrElseUpdate(test, TrieMap.empty)
        .getOrElseUpdate(e.getLoggerName, Vector.newBuilder)
      val _ = log.synchronized { log += e.getLevel -> e.getMessage }
    }
  }
} 
Example 14
Source File: ProjectDetailsSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report.impl;

import java.io.OutputStream
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._



class ProjectDetailsSubscriber extends IReportEventSubscriber[ProjectDetails]{

  private[this] var projectDetails: Option[ProjectDetails] = None

  override def filter(event: scala.Any): Optional[ProjectDetails] = {
    val details = event match {
      case event1: ILoggingEvent =>
        // Starting upgrade {} project to {}, pom {}
        val NoTaskId = """Starting upgrade (.*) project to (.*), pom (.*) with taskId None""".r
        val HasTaskId = """Starting upgrade (.*) project to (.*), pom (.*) with taskId Some\((.*)\)""".r

        event1.getFormattedMessage match {
          case HasTaskId(stack, targetVersion, pomPath, id) => Some(ProjectDetails(pomPath, stack, targetVersion, Some(id)))
          case NoTaskId(stack, targetVersion, pomPath) => Some(ProjectDetails(pomPath, stack, targetVersion, None))
          case _ => None
        }
      case _ => None
    }
    details.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = projectDetails match {
    case Some(ProjectDetails(pathToPom, stack, targetVersion, taskId)) =>
      outputStream.write(outputTemplate(pathToPom, stack, targetVersion, taskId).getBytes("utf8"))
    case None =>
  }

  private def outputTemplate(pathToPom: String,stack: String, targetVersion: String,  taskId: Option[String]) = {
    s"""
       |# $stack project upgrade report
       |## Project details
       |Name | Description
       |---- | -----------
       |Path to project POM |	$pathToPom
       |Target Version |	$targetVersion
       |Upgrade job ID | $taskId
       |Full upgrade log | [link](raptor-upgrade-debug${taskId.map("-" + _) getOrElse ""}.log)
       |Upgrade warnings only log | [link](raptor-upgrade-warn${taskId.map("-" + _) getOrElse ""}.log)
       |
     """.stripMargin
  }

  override def doAccept(event: ProjectDetails): Unit = projectDetails = Some(event)

  override val sequence = 0
}

case class ProjectDetails(pathToPom: String, stack: String, targetVersion: String, taskId: Option[String]) 
Example 15
Source File: SameThreadFilter.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.report

import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.filter.Filter
import ch.qos.logback.core.spi.FilterReply


class SameThreadFilter extends Filter[ILoggingEvent] {

  val currentThreadName = Thread.currentThread.getName

  override def decide(event: ILoggingEvent): FilterReply = {
    if (event.getThreadName == currentThreadName) {
      FilterReply.NEUTRAL
    } else {
      FilterReply.DENY
    }
  }
}

class LoggerNameFilter(loggerNames: Set[String]) extends Filter[ILoggingEvent] {
  override def decide(event: ILoggingEvent): FilterReply = {
    if (loggerNames.isEmpty) {
      FilterReply.NEUTRAL
    } else {
      if (loggerNames contains event.getLoggerName) FilterReply.NEUTRAL else FilterReply.DENY
    }
  }
} 
Example 16
Source File: MavenAddManagedDependenciesSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class MavenAddManagedDependenciesSubscriber(projectRoot: File)
  extends IReportEventSubscriber[AddManagedDependencyEvent] {

  private[this] var details = Map.empty[URI, List[String]]

  override def filter(event: scala.Any): Optional[AddManagedDependencyEvent] = {
    val artifact = event match {
      case e: ILoggingEvent =>
        if (e.getLoggerName.endsWith("MavenAddManagedDependenciesRule")
          && e.getMessage == "{} added managed dependency {} to {}") {
          val args = e.getArgumentArray
          Try(AddManagedDependencyEvent(args(1).toString, args(2).asInstanceOf[File])).toOption
        } else None
      case _ => None
    }

    artifact.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (details.nonEmpty) {
    val outputTemplate =
      """
        |### MavenAddManagedDependenciesRule
        |The following artifacts were added to dependencyManagement of the POM:
      """.stripMargin
    val content = details.foldLeft(outputTemplate) {(c, detail) =>
     val header = s"\n#### File [${detail._1}](${detail._1})\n|Artifacts|\n|---------|\n"
     c + detail._2.foldLeft(header) {(result, artifact) =>
       result + s"|$artifact|\n"
     }
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: AddManagedDependencyEvent): Unit = {
    val relativePomPath = projectRoot.toURI relativize event.pomFile.toURI
    details get relativePomPath match {
      case Some(list) => details += relativePomPath -> (event.dependency :: list)
      case None => details += relativePomPath -> List(event.dependency)
    }
  }
}

case class AddManagedDependencyEvent(dependency: String, pomFile: File) 
Example 17
Source File: MavenAddDependenciesSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class MavenAddDependenciesSubscriber(projectRoot: File) extends IReportEventSubscriber[AddDependencyEvent] {

  private[this] var details = Map.empty[URI, List[String]]

  override def filter(event: scala.Any): Optional[AddDependencyEvent] = {
    val artifact = event match {
      case e: ILoggingEvent =>
        if (e.getLoggerName.endsWith("MavenAddDependenciesRule") && e.getMessage == "{} added dependency {} to {}") {
          val args = e.getArgumentArray
          Try(AddDependencyEvent(args(1).toString, args(2).asInstanceOf[File])).toOption
        } else None
      case _ => None
    }

    artifact.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (details.nonEmpty) {
    val outputTemplate =
      """
        |### MavenAddDependenciesRule
        |The following artifacts were added to the POM:
      """.stripMargin
    val content = details.foldLeft(outputTemplate) {(c, detail) =>
     val header = s"\n#### File [${detail._1}](${detail._1})\n|Artifacts|\n|---------|\n"
     c + detail._2.foldLeft(header) {(result, artifact) =>
       result + s"|$artifact|\n"
     }
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: AddDependencyEvent): Unit = {
    val relativePomPath = projectRoot.toURI relativize event.pomFile.toURI
    details get relativePomPath match {
      case Some(list) => details += relativePomPath -> (event.dependency :: list)
      case None => details += relativePomPath -> List(event.dependency)
    }
  }
}

case class AddDependencyEvent(dependency: String, pomFile: File) 
Example 18
Source File: MavenExcludeDependenciesSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class MavenExcludeDependenciesSubscriber(projectRoot: File) extends IReportEventSubscriber[ExcludeDependencyEvent] {

  private[this] var events = Map.empty[URI, Set[ExcludeDependencyEvent]]

  override def filter(event: scala.Any): Optional[ExcludeDependencyEvent] = {
    val excludeEvent = event match {
      case e: ILoggingEvent =>
        if (e.getLoggerName.endsWith("MavenExcludeDependenciesRule") && e.getMessage == "{} excluded {} from {} in {}") {
          val args = e.getArgumentArray
          Try(ExcludeDependencyEvent(
            args(1).asInstanceOf[Set[_]].map(_.toString),
            args(2).toString,
            args(3).asInstanceOf[File]
          )).toOption
        } else None
      case _ => None
    }

    excludeEvent.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (events.nonEmpty) {
    val outputTemplate =
      """
        |### MavenExcludeDependenciesRule
        |The following artifacts were excluded:
      """.stripMargin
    val content = events.foldLeft(outputTemplate) {(c, event) =>
      val header = s"\n#### File [${event._1}](${event._1})\n|Artifact|Exclusions|\n|-------|------|\n"
      c + header + event._2.map(e => e.dep -> e.exclusions).toMap.foldLeft("") {(result, entry) =>
        result + s"|${entry._1}|" + entry._2.foldLeft("<ul>")(_ + "<li>" + _ + "</li>") + "</ul>|\n"
      }
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: ExcludeDependencyEvent): Unit = {
    val relativePomPath = projectRoot.toURI relativize event.pomFile.toURI
    events get relativePomPath match {
      case Some(set) => events += relativePomPath -> (set + event)
      case None => events += relativePomPath -> Set(event)
    }
  }
}

case class ExcludeDependencyEvent(exclusions: Set[String], dep: String, pomFile: File) 
Example 19
Source File: MavenRemoveDependenciesSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class MavenRemoveDependenciesSubscriber(projectRoot: File) extends IReportEventSubscriber[RemoveDependencyEvent] {

  private[this] var details = Map.empty[URI, List[String]]

  override def filter(event: scala.Any): Optional[RemoveDependencyEvent] = {
    val removeEvent = event match {
      case e: ILoggingEvent =>
        if (e.getLoggerName.endsWith("MavenRemoveDependenciesRule") && e.getMessage == "{} removed dependency {} from {}") {
          val args = e.getArgumentArray
          Try(RemoveDependencyEvent(args(1).toString, args(2).asInstanceOf[File])).toOption
        } else None
      case _ => None
    }

    removeEvent.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (details.nonEmpty) {
    val outputTemplate =
      """
        |### MavenRemoveDependenciesRule
        |The following artifacts were removed from the POM:
      """.stripMargin
    val content = details.foldLeft(outputTemplate) {(c, detail) =>
      val header = s"\n#### File [${detail._1}](${detail._1})\n|Artifacts|\n|---------|\n"
      c + detail._2.foldLeft(header) {(result, artifact) =>
        result + s"|$artifact|\n"
      }
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: RemoveDependencyEvent): Unit = {
    val relativePomPath = projectRoot.toURI relativize event.pomFile.toURI
    details get relativePomPath match {
      case Some(list) => details += relativePomPath -> (event.dependency :: list)
      case None => details += relativePomPath -> List(event.dependency)
    }
  }
}

case class RemoveDependencyEvent(dependency: String, pomFile: File) 
Example 20
Source File: MavenDependenciesMappingSubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class MavenDependenciesMappingSubscriber(projectRoot: File) extends IReportEventSubscriber[DependencyMappingEvent] {

  private[this] var details = Map.empty[URI, List[DependencyMappingEvent]]

  override def filter(event: scala.Any): Optional[DependencyMappingEvent] = {
    val artifact = event match {
      case e: ILoggingEvent =>
        if (e.getLoggerName.endsWith("MavenDependenciesMappingRule") && e.getMessage == "{} mapped {} to {} in {}") {
          val args = e.getArgumentArray
          Try(DependencyMappingEvent(
            args(1).asInstanceOf[Set[_]].map(_.toString),
            args(2).asInstanceOf[Set[_]].map(_.toString),
            args(3).asInstanceOf[File]
          )).toOption
        } else None
      case _ => None
    }

    artifact.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (details.nonEmpty) {
    val outputTemplate =
      """
        |### MavenDependenciesMappingRule
        |The following groups of artifacts were mapped to new ones.
      """.stripMargin
    val content = details.foldLeft(outputTemplate) {(c, detail) =>
      val header = s"\n#### File [${detail._1}](${detail._1})\n|from|to|\n|----|---|\n"
      val body = detail._2.foldLeft(header) {(b, event) =>
        val from = event.from.foldLeft("<ul>") {(f, x) =>
          f + s"<li>$x</li>"
        } + "</ul>"
        val to = event.to.foldLeft("<ul>") {(f, x) =>
          f + s"<li>$x</li>"
        } + "</ul>"
        b + s"| $from | $to |\n"
      }
      c + body
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: DependencyMappingEvent): Unit = {
    val relativePomPath = projectRoot.toURI relativize event.pomFile.toURI
    details get relativePomPath match {
      case Some(list) => details += relativePomPath -> (event :: list)
      case None => details += relativePomPath -> List(event)
    }
  }
}

case class DependencyMappingEvent(from: Set[String], to: Set[String], pomFile: File) 
Example 21
Source File: ArtifactsSummarySubscriber.scala    From RTran   with Apache License 2.0 5 votes vote down vote up
package com.ebay.rtran.maven.report

import java.io.{File, OutputStream}
import java.net.URI
import java.util.Optional

import ch.qos.logback.classic.spi.ILoggingEvent
import com.ebay.rtran.report.api.IReportEventSubscriber

import scala.compat.java8.OptionConverters._
import scala.util.Try


class ArtifactsSummarySubscriber(projectRoot: File) extends IReportEventSubscriber[(URI, String)] {

  private[this] var artifacts = Set.empty[(URI, String)]

  override def filter(event: scala.Any): Optional[(URI, String)] = {
    val artifact = event match {
      case e: ILoggingEvent =>
        e.getMessage match {
          case "Found maven pom {} for artifact {}" =>
            val args = e.getArgumentArray
            Try((projectRoot.toURI.relativize(args(0).asInstanceOf[File].toURI), args(1).toString)).toOption
          case _ => None
        }
      case _ => None
    }

    artifact.asJava
  }

  override def dumpTo(outputStream: OutputStream): Unit = if (artifacts.nonEmpty) {
    val outputTemplate = s"\r### Artifacts\n" +
      s"This upgrade request processed only the ${artifacts.size} Maven project artifacts\n" +
      s"that were referenced directly or indirectly by the project's parent POM:\n\n" +
      s"| No. | POM file | Artifact ID |\n" +
      s"| --- | -------- | ----------- |\n"
    var pomCount = 0
    val content = artifacts.foldLeft(outputTemplate) {(c, artifact) =>
      pomCount += 1
      c + s"| $pomCount | [${artifact._1}](${artifact._1}) | ${artifact._2} |\n"
    }
    outputStream.write(content.getBytes("utf8"))
  }

  override def doAccept(event: (URI, String)): Unit = if (event._1.toString != "pom.xml") artifacts += event

  override val sequence = 1
} 
Example 22
Source File: MemoryAppender.scala    From ncdbg   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.programmaticallyspeaking.ncd.testing

import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.UnsynchronizedAppenderBase
import ch.qos.logback.core.encoder.Encoder
import ch.qos.logback.core.status.ErrorStatus
import java.io.{ByteArrayOutputStream, IOException, OutputStream}
import java.nio.charset.StandardCharsets

import com.programmaticallyspeaking.ncd.messaging.{Observable, SerializedSubject}

object MemoryAppender {
  private[MemoryAppender] val logEventSubject = new SerializedSubject[String]

  def logEvents: Observable[String] = logEventSubject
}

class MemoryAppender extends UnsynchronizedAppenderBase[ILoggingEvent] {
  import MemoryAppender._
  private var encoder: Encoder[ILoggingEvent] = _
  private var outputStream = new OutputStream {
    override def write(b: Int): Unit = ???

    override def write(b: Array[Byte]): Unit = {
      val str = new String(b, StandardCharsets.UTF_8)
      logEventSubject.onNext(str)
    }
  }

  override def start(): Unit = {
    try {
      Option(encoder).foreach(_.init(outputStream))
      super.start()
    } catch {
      case e: IOException =>
        started = false
        addStatus(new ErrorStatus("Failed to initialize encoder for appender named [" + name + "].", this, e))
    }
  }

  override protected def append(event: ILoggingEvent): Unit = {
    if (!isStarted) return
    try {
      event.prepareForDeferredProcessing()
      Option(encoder).foreach(_.doEncode(event))
    } catch {
      case ioe: IOException =>
        started = false
        addStatus(new ErrorStatus("IO failure in appender", this, ioe))
    }
  }

  def setEncoder(e: Encoder[ILoggingEvent]): Unit = {
    encoder = e
  }
} 
Example 23
Source File: LogbackConfigurator.scala    From apalache   with Apache License 2.0 5 votes vote down vote up
package at.forsyte.apalache.infra.log

import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.classic.spi.{Configurator, ILoggingEvent}
import ch.qos.logback.classic.{Level, LoggerContext, PatternLayout}
import ch.qos.logback.core.encoder.LayoutWrappingEncoder
import ch.qos.logback.core.spi.ContextAwareBase
import ch.qos.logback.core.{ConsoleAppender, FileAppender}
import org.slf4j.LoggerFactory


class LogbackConfigurator extends ContextAwareBase with Configurator {
  def configureDefaultContext(): Unit = {
    val loggerContext = LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
    setContext(loggerContext)
    configure(loggerContext)
  }

  override def configure(loggerContext: LoggerContext): Unit = {
    addInfo("Setting up a logback configuration")
    loggerContext.reset() // forget everything that was configured automagically
    val rootLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME)
    val consoleAppender = mkConsoleAppender(loggerContext)
    // only warnings at the root level
    rootLogger.setLevel(Level.WARN)
    rootLogger.addAppender(mkFileAppender(loggerContext))
    rootLogger.addAppender(consoleAppender)
    // debug messages at the apalache level
    val apalacheLogger = loggerContext.getLogger("at.forsyte.apalache")
    apalacheLogger.setLevel(Level.DEBUG)
  }

  private def mkConsoleAppender(loggerContext: LoggerContext): ConsoleAppender[ILoggingEvent] = {
    // set up ConsoleAppender
    val app = new ConsoleAppender[ILoggingEvent]()
    app.setContext(loggerContext)
    app.setName("console")
    val filter = new ThresholdFilter()
    filter.setContext(loggerContext)
    filter.setLevel(Level.INFO.levelStr)
    filter.start()
    app.addFilter(filter)
    val layout = new PatternLayout()
    layout.setPattern("%-65msg %.-1level@%d{HH:mm:ss.SSS}%n")
    layout.setContext(loggerContext)
    layout.start()
    val encoder = new LayoutWrappingEncoder[ILoggingEvent]()
    encoder.setContext(loggerContext)
    encoder.setLayout(layout)
    app.setEncoder(encoder)
    app.start()
    app
  }

  private def mkFileAppender(loggerContext: LoggerContext): FileAppender[ILoggingEvent] = {
    // set up FileAppender
    val app = new FileAppender[ILoggingEvent]()
    app.setContext(loggerContext)
    app.setName("file")
    app.setFile("detailed.log")
    val encoder = new LayoutWrappingEncoder[ILoggingEvent]()
    encoder.setContext(loggerContext)
    val layout = new PatternLayout()
    layout.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{12} - %msg%n")
    layout.setContext(loggerContext)
    layout.start()
    encoder.setLayout(layout)
    app.setEncoder(encoder)
    val filter = new ThresholdFilter()
    filter.setLevel(Level.DEBUG.levelStr)
    filter.setContext(loggerContext)
    filter.start()
    app.addFilter(filter)
    app.start()
    app
  }
} 
Example 24
Source File: TraceTokenMDCLoggingTest.scala    From akka-http-extensions   with Apache License 2.0 5 votes vote down vote up
package com.lonelyplanet.akka.http.extensions.logging

import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.classic.{Level, Logger, LoggerContext}
import ch.qos.logback.core.AppenderBase
import com.lonelyplanet.akka.http.extensions.tracing.{MaybeTraceTokenHolder, TraceToken}
import org.scalatest.{FlatSpec, Matchers}
import org.slf4j.LoggerFactory

import scala.util.Random

class TraceTokenMDCLoggingSpec extends FlatSpec with Matchers {
  it should "log trace token if one is present" in {
    withInMemoryAppender { appender =>
      val traceToken = TraceToken.random
      val loggingTester = new LoggingTester(Some(traceToken))
      val message = randomMessage

      loggingTester.doLog(message)

      appender.output should not be empty
      appender.output.lines.foreach({ line =>
        line.contains(message) shouldBe true
        line.contains(traceToken.toString) shouldBe true
      })
    }
  }

  private def withInMemoryAppender(f: (InMemoryLoggingAppender) => Unit) = {
    val loggerContext = LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
    val appender = new InMemoryLoggingAppender
    appender.setContext(loggerContext)

    val logger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).asInstanceOf[Logger]
    logger.setLevel(Level.ALL)
    logger.detachAndStopAllAppenders()

    logger.addAppender(appender)
    appender.start()
    f(appender)
    logger.detachAppender(appender)
    appender.stop()
  }

  private def randomMessage = Random.alphanumeric.take(20).mkString("")
}

private class InMemoryLoggingAppender extends AppenderBase[ILoggingEvent] {
  private val builder = new StringBuilder

  override def append(event: ILoggingEvent): Unit = {
    builder.append(event.getMessage)
    builder.append(" ")
    if (event.getMDCPropertyMap.containsKey(TraceToken.MDCKey)) {
      builder.append(event.getMDCPropertyMap.get(TraceToken.MDCKey))
    }
    builder.append("\n")
  }

  def output: String = builder.toString()
  def clear(): Unit = builder.clear()
}

private class LoggingTester(maybeTraceTokenFunc: => Option[TraceToken]) extends TraceTokenMDCLogging with MaybeTraceTokenHolder {
  override def maybeTraceToken: Option[TraceToken] = maybeTraceTokenFunc
  def doLog(message: String): Unit = {
    logger.trace(message)
    logger.debug(message)
    logger.info(message)
    logger.warn(message)
    logger.error(message)
  }
} 
Example 25
Source File: LogbackThresholdFilterWithExclusion.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.client.binding.log

import ch.qos.logback.classic.filter.ThresholdFilter
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.spi.FilterReply


class LogbackThresholdFilterWithExclusion extends ThresholdFilter {
  @volatile private var excludeLogger: String = _

  def setExcludeLogger(a: String): Unit = this.excludeLogger = a

  def getExcludeLogger: String = this.excludeLogger

  override def decide(event: ILoggingEvent): FilterReply = {
    if (!this.isStarted) FilterReply.NEUTRAL
    else if (event.getLoggerName.startsWith(excludeLogger)) FilterReply.NEUTRAL
    else super.decide(event)
  }

  override def start(): Unit = {
    if (this.excludeLogger != null) {
      super.start()
    }
  }
} 
Example 26
Source File: JsonEncoder.scala    From logback-json-logger   with Apache License 2.0 4 votes vote down vote up
package uk.gov.hmrc.play.logging

import java.net.InetAddress
import java.nio.charset.StandardCharsets

import ch.qos.logback.classic.spi.{ILoggingEvent, ThrowableProxyUtil}
import ch.qos.logback.core.encoder.EncoderBase
import com.fasterxml.jackson.core.JsonGenerator.Feature
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.commons.io.IOUtils._
import org.apache.commons.lang3.time.FastDateFormat
import com.typesafe.config.ConfigFactory

import scala.util.{Success, Try}
import scala.collection.JavaConverters._

class JsonEncoder extends EncoderBase[ILoggingEvent] {

  private val mapper = new ObjectMapper().configure(Feature.ESCAPE_NON_ASCII, true)

  lazy val appName: String = Try { ConfigFactory.load().getString("appName") } match {
    case Success(name) => name.toString
    case _             => "APP NAME NOT SET"
  }

  private val DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSZZ"

  private lazy val dateFormat = {
    val dformat = Try { ConfigFactory.load().getString("logger.json.dateformat") } match {
      case Success(date) => date.toString
      case _             => DATE_FORMAT
    }
    FastDateFormat.getInstance(dformat)
  }

  override def encode(event: ILoggingEvent): Array[Byte] = {
    val eventNode = mapper.createObjectNode

    eventNode.put("app", appName)
    eventNode.put("hostname", InetAddress.getLocalHost.getHostName)
    eventNode.put("timestamp", dateFormat.format(event.getTimeStamp))
    eventNode.put("message", event.getFormattedMessage)

    Option(event.getThrowableProxy).map(p => eventNode.put("exception", ThrowableProxyUtil.asString(p)))

    eventNode.put("logger", event.getLoggerName)
    eventNode.put("thread", event.getThreadName)
    eventNode.put("level", event.getLevel.toString)

    Option(getContext).foreach(c =>
      c.getCopyOfPropertyMap.asScala foreach { case (k, v) => eventNode.put(k.toLowerCase, v) })
    event.getMDCPropertyMap.asScala foreach { case (k, v) => eventNode.put(k.toLowerCase, v) }

    s"${mapper.writeValueAsString(eventNode)}$LINE_SEPARATOR".getBytes(StandardCharsets.UTF_8)
  }

  override def footerBytes(): Array[Byte] =
    LINE_SEPARATOR.getBytes(StandardCharsets.UTF_8)

  override def headerBytes(): Array[Byte] =
    LINE_SEPARATOR.getBytes(StandardCharsets.UTF_8)

}