or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-com-typesafe-akka--akka-slf4j_2-12

SLF4J logging integration for Akka providing logger implementation and utilities for integrating Akka's logging system with SLF4J-based logging frameworks

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/com.typesafe.akka/akka-slf4j_2.12@2.8.x

To install, run

npx @tessl/cli install tessl/maven-com-typesafe-akka--akka-slf4j_2-12@2.8.0

index.mddocs/

Akka SLF4J

Akka SLF4J provides seamless integration between Akka's actor-based logging system and the SLF4J logging facade. It enables developers to leverage existing SLF4J-compatible logging frameworks (like Logback, Log4J) within Akka applications while maintaining compatibility with Akka's event bus and logging levels.

The library includes the Slf4jLogger actor for processing Akka log events, the SLF4JLogging trait for easy logging access, utilities for configuring MDC (Mapped Diagnostic Context) support for structured logging, and filtering capabilities that respect SLF4J backend configuration.

Package Information

  • Package Name: akka-slf4j_2.12
  • Package Type: maven
  • Language: Scala
  • Installation: Add to build.sbt: "com.typesafe.akka" %% "akka-slf4j" % "2.8.8"
  • Module: akka.event.slf4j

Core Imports

import akka.event.slf4j._

For specific components:

import akka.event.slf4j.{SLF4JLogging, Logger, Slf4jLogger, Slf4jLogMarker, Slf4jLoggingFilter}

Basic Usage

Configure Akka to use SLF4J Logger

// application.conf
akka {
  loggers = ["akka.event.slf4j.Slf4jLogger"]  
  loglevel = "INFO"
  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
}

Using SLF4JLogging trait in actors

import akka.actor.{Actor, ActorLogging}
import akka.event.slf4j.SLF4JLogging

class MyActor extends Actor with SLF4JLogging {
  def receive = {
    case message =>
      log.info("Received message: {}", message)
      log.debug("Processing in actor: {}", self.path)
  }
}

Manual logger creation

import akka.event.slf4j.Logger

class MyService {
  private val log = Logger("com.example.MyService")
  
  def processData(data: String): Unit = {
    log.info("Processing data of length: {}", data.length)
    if (data.isEmpty) {
      log.warn("Empty data received")
    }
  }
}

Architecture

Akka SLF4J is built around several key components:

  • SLF4JLogging trait: Provides convenient log field initialization for classes
  • Logger object: Factory for creating SLF4J logger instances with Akka-aware handling
  • Slf4jLogger actor: Core actor that receives Akka log events and forwards them to SLF4J
  • Slf4jLoggingFilter: Filter that respects SLF4J backend configuration for log level filtering
  • Slf4jLogMarker: Wrapper for SLF4J markers to enable marker-based logging with Akka
  • MDC Support: Automatic population of Mapped Diagnostic Context with Akka-specific information

Capabilities

SLF4J Logging Trait

Base trait that provides easy access to SLF4J logging infrastructure with lazy logger initialization.

trait SLF4JLogging {
  @transient lazy val log: org.slf4j.Logger = Logger(this.getClass.getName)
}

Mix this trait into any class to get access to a logger instance named after the class.

Logger Factory

Factory object for creating SLF4J logger instances with various initialization options.

object Logger {
  def apply(logger: String): org.slf4j.Logger
  def apply(logClass: Class[_], logSource: String): org.slf4j.Logger  
  def root: org.slf4j.Logger
}
  • apply(logger: String): Creates logger for the given logger name
  • apply(logClass: Class[_], logSource: String): Creates logger for specified class and source. Uses pattern matching to handle DummyClassForStringSources specially, falling back to logSource parameter for logger name
  • root: Returns the SLF4J root logger

SLF4J Logger Actor

Core actor that processes Akka logging events and forwards them to SLF4J with proper context and formatting.

class Slf4jLogger extends Actor with SLF4JLogging with RequiresMessageQueue[LoggerMessageQueueSemantics] {
  def receive: Receive
  protected def formatTimestamp(timestamp: Long): String
  
  // MDC attribute name constants
  val mdcThreadAttributeName: String = "sourceThread"
  val mdcActorSystemAttributeName: String = "sourceActorSystem"  
  val mdcAkkaSourceAttributeName: String = "akkaSource"
  val mdcAkkaTimestamp: String = "akkaTimestamp"
  val mdcAkkaAddressAttributeName: String = "akkaAddress"
  val mdcAkkaUidAttributeName: String = "akkaUid"
}

The actor handles these Akka log events:

  • Error - Maps to SLF4J error level with exception handling
  • Warning - Maps to SLF4J warn level
  • Info - Maps to SLF4J info level
  • Debug - Maps to SLF4J debug level
  • InitializeLogger - Logger initialization message

SLF4J Logging Filter

Logging filter that uses the SLF4J backend configuration to determine if log events should be published to the event stream.

class Slf4jLoggingFilter(@unused settings: ActorSystem.Settings, eventStream: EventStream) 
    extends LoggingFilterWithMarker {
  
  def isErrorEnabled(logClass: Class[_], logSource: String): Boolean
  def isWarningEnabled(logClass: Class[_], logSource: String): Boolean  
  def isInfoEnabled(logClass: Class[_], logSource: String): Boolean
  def isDebugEnabled(logClass: Class[_], logSource: String): Boolean
  
  // Marker-aware versions
  def isErrorEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
  def isWarningEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
  def isInfoEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
  def isDebugEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
}

This filter checks both Akka's event stream log level and the SLF4J backend configuration to determine if logging should occur.

SLF4J Log Marker Support

Wrapper class and factory for integrating SLF4J markers with Akka's logging system.

final class Slf4jLogMarker(val marker: org.slf4j.Marker) extends LogMarker(name = marker.getName, properties = Map.empty)

object Slf4jLogMarker {
  def apply(marker: org.slf4j.Marker): Slf4jLogMarker
  def create(marker: org.slf4j.Marker): Slf4jLogMarker  // Java API
}

Use with Akka's marker-based logging:

import akka.event.Logging
import org.slf4j.MarkerFactory

val marker = MarkerFactory.getMarker("BUSINESS_EVENT")
val markLog = Logging.withMarker(context.system, this)
markLog.info(Slf4jLogMarker(marker), "Business event occurred")

Types

Core Types

// From SLF4J API (external dependency)
trait org.slf4j.Logger {
  def info(msg: String): Unit
  def info(format: String, arg: Any): Unit
  def warn(msg: String): Unit
  def error(msg: String, t: Throwable): Unit
  def debug(msg: String): Unit
  def isInfoEnabled(): Boolean
  def isDebugEnabled(): Boolean
  // ... other standard SLF4J methods
}

trait org.slf4j.Marker {
  def getName(): String
  // ... other marker methods
}

Akka Integration Types

// From akka-actor (dependency)
trait Actor {
  def receive: Receive
  def context: ActorContext
}

trait LoggingFilterWithMarker {
  def isErrorEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
  def isWarningEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
  def isInfoEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean  
  def isDebugEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
}

abstract class LogMarker(val name: String, val properties: Map[String, Any])

trait RequiresMessageQueue[T <: MessageQueue]
trait LoggerMessageQueueSemantics extends MessageQueue

// From akka-event
trait EventStream {
  def logLevel: Int
}

class ActorSystem {
  type Settings
}

// Additional types referenced in the API
trait LogEvent {
  def timestamp: Long
  def thread: Thread
  def mdc: Map[String, Any]
}

trait LogEventWithMarker extends LogEvent {
  def marker: LogMarker
}

trait LogEventWithCause extends LogEvent {
  def cause: Throwable
}

case class Error(cause: Throwable, logSource: String, logClass: Class[_], message: Any) extends LogEvent with LogEventWithCause
case class Warning(logSource: String, logClass: Class[_], message: Any) extends LogEvent
case class Info(logSource: String, logClass: Class[_], message: Any) extends LogEvent  
case class Debug(logSource: String, logClass: Class[_], message: Any) extends LogEvent
case class InitializeLogger(bus: EventStream) extends LogEvent
case object LoggerInitialized

trait DiagnosticActorLogging {
  def log: DiagnosticLoggingAdapter
}

trait DiagnosticLoggingAdapter {
  def mdc(mdc: Map[String, Any]): Unit
  def clearMDC(): Unit
}

class DummyClassForStringSources

// From akka-actor types
trait ActorContext {
  def system: ActorSystem
}

type Receive = PartialFunction[Any, Unit]

trait MessageQueue

// Log level constants 
val ErrorLevel: Int
val WarningLevel: Int  
val InfoLevel: Int
val DebugLevel: Int

Configuration Examples

Basic SLF4J Integration

akka {
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  loglevel = "DEBUG"
  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
  logger-startup-timeout = 30s
}

With Logback Backend

Create logback.xml:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%X{akkaSource}] %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  
  <logger name="akka" level="INFO" />
  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

Advanced MDC Usage

The logger automatically populates MDC with Akka-specific context:

// These MDC keys are automatically available in your logging pattern:
// sourceThread - Thread where logging occurred  
// sourceActorSystem - Name of the actor system
// akkaSource - Akka logging source
// akkaTimestamp - Formatted timestamp  
// akkaAddress - Actor system address
// akkaUid - Actor system unique identifier

Access in logback pattern:

<pattern>%d [%X{sourceThread}] [%X{akkaSource}] %-5level %logger - %msg%n</pattern>

Error Handling

The SLF4J integration handles various error scenarios:

  • Null messages: Handled gracefully without throwing exceptions
  • Missing SLF4J backend: Falls back to no-op logging behavior
  • Actor system shutdown: Proper cleanup of MDC context
  • Thread context: MDC is properly cleared after each log statement to prevent context leakage

Dependencies

This module requires:

  • akka-actor - Core Akka actor system
  • slf4j-api (version 1.7.36) - SLF4J logging facade
  • SLF4J implementation (like Logback, Log4J2) - Choose based on your needs

Add to your build.sbt:

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-slf4j" % "2.8.8",
  "ch.qos.logback" % "logback-classic" % "1.2.12" // or your preferred SLF4J implementation  
)