Search code examples
scalaloggingakkalogback

Configuring logback to write to different logs files


I've an actor system with multiple actors. Actors are grouped by a fixed set of domains. Currently I'm logging to just one big log file which interleaves the logs from different actors belonging to different domains.

How can I configure logback so that each actor writes to its own .log file. Also, does writing to different log files compared to writing to a single one have a performance impact ?


Solution

  • What you require here is a SiftingAppender with a Actor/Actor system based discriminator.
    Give the following configuration in your logback.xml

    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator class="com.abc.ActorDomainBasedDiscriminator"/>
    <sift>
        <appender name="FILE-${actorDomain}" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <file>app-${actorDomain}.log</file>
    ...
    

    This configuration will result in log files being created like 'app-Domain1.log', 'app-Domain2.log' etc...

    Define a class ActorDomainBasedDiscriminator

    import ch.qos.logback.classic.spi.LoggingEvent
    import ch.qos.logback.core.sift.Discriminator
    import ch.qos.logback.core.spi.ContextAwareBase
    
    class ActorDomainBasedDiscriminator extends ContextAwareBase with Discriminator[LoggingEvent] {
      private val Key = "actorDomain";
    
      @volatile
      private var started = false;
    
      def getDiscriminatingValue(event: LoggingEvent) = {
        val loggerName = event.getLoggerName
        if(loggerName.startsWith("Domain"))
          loggerName
        else event.getLevel.toString
      }
    
     def getKey: String = Key
    
     …
    
     } 
    

    Now create the loggers in the Actor classes like this...

       class Actor1 extends Actor {
    
          val logger = LoggerFactory.getLogger("Domain1")
          ....
    
    
        class Actor2 extends Actor {
    
          val logger = LoggerFactory.getLogger("Domain2")
          ....
    
      class Actor3 extends Actor {
          val logger = LoggerFactory.getLogger("Domain1")
          ...
    

    You may refer to this link to for discriminator example

    http://www.nurkiewicz.com/2013/04/siftingappender-logging-different.html