2
votes

I have tried the below steps to configure logging for my akka system:

1.Created both application.conf and logback.xml file and put them in the src/main/resources directory.
2.application.conf file looks like:-

    akka {  
     loggers = ["akka.event.slf4j.Slf4jLogger"]  
     logging-filter="akka.event.slf4j.Slf4jLoggingFilter"  
     log-config-on-start = on  
     loglevel = "DEBUG"  
    }  

3.logback.xml file looks like:-

    <?xml version="1.0" encoding="UTF-8"?>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <target>System.out</target>
    <encoder>
        <pattern>%X{akkaTimestamp} %-5level[%thread] %logger{0} - %msg%n</pattern>
    </encoder>
</appender>

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/Users/deepak/work/logs/akka.log</file>
    <append>true</append>
    <encoder>
        <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
    </encoder>
</appender>

<logger name="akka" level="DEBUG" />

<root level="DEBUG">
    <appender-ref ref="CONSOLE"/>
    <appender-ref ref="FILE"/>
</root>


4.sbt build dependencies:-

    libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.11" % "2.4.14"  
    libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.1.3" % Test  

5.Akka Version="2.4.14"
6.After building the jar file, i checked the application.conf and logback.xml files are present inside it. So, i don't think it is any classpath issue.
7.My actor mixes with the ActorLogging trait. But when i run the jar file i am not able to see the logs

    import akka.actor.{Actor, ActorLogging}  
    class Reader extends Actor with ActorLogging{  
     override def receive = {  
      case _ =>log.info("Reader")  
     }  
    }  

Please, help here. I am not able figure out the issue

1

1 Answers

3
votes

After a quick look, I have seen 2 main problems in your project:

  1. Your logback.xml is wrong formatted. It should start with <configuration> and end with </configuration>

  2. Your build.sbt has a problem. While importing logback-classic you should remove the Test flag from that line. Otherwise, you could only use that library in test classes.

  3. Additionally, I recommend you to use the latest versions of akka-slf4j_2.11 and logback-classic. In this case, this does not make any harm but stick with the best practices, use the most recent versions.

Here are the corrected version of your project:

build.sbt

scalaVersion := "2.11.8"

libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.11" % "2.5.4"

//Removed the Test flag
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.1.7"

logback.xml

 <configuration>
     <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
         <target>System.out</target>
         <encoder>
             <pattern>%X{akkaTimestamp} %-5level[%thread] %logger{0} - %msg%n</pattern>
         </encoder>
     </appender>

     <appender name="FILE" class="ch.qos.logback.core.FileAppender">
         <file>akka.log</file>
         <append>true</append>
         <encoder>
             <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
         </encoder>
     </appender>

     <logger name="akka" level="DEBUG"/>

     <root level="DEBUG">
         <appender-ref ref="CONSOLE"/>
         <appender-ref ref="FILE"/>
     </root>
 </configuration>

application.conf

 akka {
   loggers = ["akka.event.slf4j.Slf4jLogger"]
   logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
   log-config-on-start = on
   loglevel = "DEBUG"
 }

Reader.scala

 import akka.actor.{Actor, ActorLogging}

 class Reader extends Actor with ActorLogging {

   override def receive = {
     case _ => log.info("Message received")
   }
 }

Main.scala

 import akka.actor.{ActorRef, ActorSystem, Props}

 object Main {
   def main(args: Array[String]): Unit = {
     implicit val system: ActorSystem = ActorSystem("reader-system")

     val ref: ActorRef = system.actorOf(Props(new Reader))

     //send message to actor
     ref ! "message"

   }

 }

With this configurations, you should be able to run Main.scala and see the Message received log in both std out and Log file.

Hope this helps!