2

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

dks551
  • 1,113
  • 1
  • 15
  • 39

1 Answers1

3

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!

fcat
  • 1,251
  • 8
  • 18
  • With the above sbt change it's failing while building the jar file. [error] (*:assembly) deduplicate: different file contents found in the following: [error] /Users/deepak/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic1.1.7.jar:org/slf4j/impl/StaticLoggerBinder.class [error] /Users/deepak/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.6.1.jar:org/slf4j/impl/StaticLoggerBinder.class [error] deduplicate: different file contents found in the following: – dks551 Sep 21 '17 at 16:04
  • I didn't get such an exception. If you have additional libraries which has their own `logback.xml` files in your `build.sbt`, they may cause such a conflict. In that case, you should define a `merge strategy`. Take a look at this [case](https://stackoverflow.com/questions/30446984/spark-sbt-assembly-deduplicate-different-file-contents-found-in-the-followi) But I would strongly recommend using [sbt-native-packager](https://github.com/sbt/sbt-native-packager) for building. You don't face this kind of problems with it. – fcat Sep 22 '17 at 07:39
  • @user3156383 that error suggests you have 2 slf4j backends in your dependency tree: logback and slf4j-log4j12. You can have only one. Assuming you want logback, you could use https://github.com/jrudolph/sbt-dependency-graph to find out where the dependency on slf4-log4j12 comes from. – Arnout Engelen Sep 22 '17 at 13:22