title: Using SLF4J in Akka
body: <p>I followed <a href="https://doc.akka.io/docs/akka/2.5/logging.html" rel="nofollow noreferrer">Logging Doc</a> for using <code>SLF4J</code> with <code>logback</code> in my Akka application. But i have problem in logging in non-actor classes: I can not log MDCs (e.g. <code>sourceActorSystem</code>) in my non-actor classes by a SLF4J logger. Here is my simple application:</p>
  
  <p>1- <code>pom.xml</code>:</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;com.typesafe.akka&lt;/groupId&gt;
      &lt;artifactId&gt;akka-slf4j_2.12&lt;/artifactId&gt;
      &lt;version&gt;2.5.18&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;ch.qos.logback&lt;/groupId&gt;
      &lt;artifactId&gt;logback-classic&lt;/artifactId&gt;
      &lt;version&gt;1.2.3&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>2- <code>application.conf</code>:</p>
  
  <pre><code>akka {
    loggers = ["akka.event.slf4j.Slf4jLogger"]
    loglevel = "DEBUG"
    logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
  }
  </code></pre>
  
  <p>3- <code>logback.xml</code> which uses <code>sourceThread</code>, <code>akkaSource</code>, and <code>sourceActorSystem</code> MDCs:</p>
  
  <pre><code>&lt;configuration scan="true" scanPeriod="30 seconds" &gt; 
      &lt;contextName&gt;akka-sample&lt;/contextName&gt;
      &lt;jmxConfigurator /&gt;
      &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;
          &lt;encoder&gt;
              &lt;pattern&gt;%d{HH:mm:ss} %-5level [%contextName] [%X{sourceThread}] [%X{sourceActorSystem}] [%X{akkaSource}] %logger{40} -| %msg %rEx%n&lt;/pattern&gt;
          &lt;/encoder&gt;
      &lt;/appender&gt;
      &lt;root level="info"&gt;
          &lt;appender-ref ref="STDOUT" /&gt;
      &lt;/root&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>4- <code>UserActor</code>: An actor class which logs by <code>DiagnosticLoggingAdapter</code>:</p>
  
  <pre><code>public class UserActor extends AbstractActor {
      DiagnosticLoggingAdapter logger = Logging.getLogger(this);
      Handler handler = new Handler(); // non-actor class
  
      public static Props props() {
          return Props.create(UserActor.class, UserActor::new);
      }
  
      @Override
      public Receive createReceive() {
          return receiveBuilder()
              .match(UserMessages.Register.class, register -&gt; {
                  logger.info("{} received", register);
                  // Delegate message-handling to a non-actor class
                  handler.onRegister(register, getSelf(), getSender());
              })
              .build();
      }
  }
  </code></pre>
  
  <p>5- <code>Handler</code>: A non-actor class which logs by <code>SLF4J</code> logger. Each <code>UserActor</code> instance has a <code>Handler</code> field for delegating message-handling to it:</p>
  
  <pre><code>public class Handler {
      org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());
  
      public void onRegister(UserMessages.Register register, ActorRef self, ActorRef sender) {
          logger.info("Handling {}", register);
          sender.tell(new UserMessages.Registered(), self);
      }
  }
  </code></pre>
  
  <p>6- Simple application:</p>
  
  <pre><code>public class Application {
      public static void main(String [] args) throws InterruptedException {
          ActorSystem system = null;
          try {
              system = ActorSystem.create("akka-system");
              ActorRef user1 = system.actorOf(UserActor.props(), "user-1");
              ActorRef user2 = system.actorOf(UserActor.props(), "user-2");
              user2.tell(UserMessages.Register.builder().userId("1").build(), user1);
              Thread.sleep(2000);
          } finally {
              system.terminate();
          }
      }
  }
  </code></pre>
  
  <p>Log Output:</p>
  
  <pre><code>18:07:30 INFO  [akka-sample] [] [] [] akka.event.slf4j.Slf4jLogger -| Slf4jLogger started 
  18:07:30 INFO  [akka-sample] [akka-system-akka.actor.default-dispatcher-4] [akka-system] [akka://akka-system/user/user-2] x.y.akka.UserActor -| UserMessages.Register(userId=1) received 
  18:07:30 INFO  [akka-sample] [] [] [] x.y.akka.Handler -| Handling UserMessages.Register(userId=1) 
  </code></pre>
  
  <p>As you can see, only log in <code>UserActor</code> (actor class) has <code>sourceThread</code>, <code>akkaSource</code>, and <code>sourceActorSystem</code> MDCs; But in <code>Handler</code> (non-actor) they are empty. Also if i change <code>akka.event.DiagnosticLoggingAdapter</code> in <code>UserActor</code> to <code>org.slf4j.Logger</code>, these MDCs become empty.</p>