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

SLF4J logging backend for Akka actor system

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

To install, run

npx @tessl/cli install tessl/maven-com-typesafe-akka--akka-slf4j@2.5.0

index.mddocs/

Akka SLF4J

Akka SLF4J provides SLF4J (Simple Logging Facade for Java) integration for the Akka actor system, enabling developers to use SLF4J logging infrastructure within Akka applications. It includes a logger actor that implements Akka's logging interface and provides seamless integration between Akka's internal logging system and SLF4J, allowing use of popular logging frameworks like Logback or Log4j through SLF4J's facade.

Package Information

  • Package Name: akka-slf4j
  • Package Type: maven
  • Language: Scala
  • Installation: "com.typesafe.akka" %% "akka-slf4j" % "2.5.23"

Core Imports

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

Basic Usage

Configure Akka to use SLF4J

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

Using SLF4JLogging trait in actors

import akka.actor.Actor
import akka.event.slf4j.SLF4JLogging

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

Using Logger factory

import akka.event.slf4j.Logger

class MyService {
  private val log = Logger(this.getClass.getName)
  
  def doSomething(): Unit = {
    log.info("Service operation started")
    // ... do work ...
    log.info("Service operation completed")
  }
}

Capabilities

SLF4J Integration Trait

Base trait that provides SLF4J logging capability to any class.

trait SLF4JLogging {
  @transient
  lazy val log: org.slf4j.Logger
}

Mix this trait into your classes to get access to a lazy-initialized SLF4J logger.

Logger Factory

Factory object for obtaining SLF4J logger instances.

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) - Returns a logger for the specified logger name
  • apply(logClass: Class[_], logSource: String) - Returns a logger for the specified class and source
  • root - Returns the SLF4J root logger

Akka Logger Actor

Actor that handles Akka logging events and forwards them to SLF4J backends.

class Slf4jLogger extends Actor with SLF4JLogging 
  with RequiresMessageQueue[LoggerMessageQueueSemantics] {
  
  val mdcThreadAttributeName: String
  val mdcActorSystemAttributeName: String
  val mdcAkkaSourceAttributeName: String
  val mdcAkkaTimestamp: String
  
  def receive: Receive
  final def withMdc(logSource: String, logEvent: LogEvent)(logStatement: => Unit): Unit
  protected def formatTimestamp(timestamp: Long): String
}

The logger actor:

  • Handles Akka logging events (Error, Warning, Info, Debug, InitializeLogger)
  • Sets up MDC (Mapped Diagnostic Context) with thread, actor system, and source information
  • Formats and forwards log events to the configured SLF4J backend
  • Supports log markers for structured logging

MDC attribute names:

  • mdcThreadAttributeName - "sourceThread"
  • mdcActorSystemAttributeName - "sourceActorSystem"
  • mdcAkkaSourceAttributeName - "akkaSource"
  • mdcAkkaTimestamp - "akkaTimestamp"

Logging Filter

LoggingFilter that uses SLF4J backend configuration to filter log events before publishing to the event stream.

class Slf4jLoggingFilter(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
  
  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 respects both Akka's log level configuration and the SLF4J backend's log level configuration, only allowing events through that are enabled at both levels.

Log Markers

Support for SLF4J markers in Akka logging.

final class Slf4jLogMarker(val marker: org.slf4j.Marker) extends LogMarker

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

Slf4jLogMarker wraps SLF4J markers for use with Akka's marker-based logging. The create method provides Java API compatibility.

Usage with Markers

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

class MarkedLoggingActor extends Actor with DiagnosticActorLogging {
  val markLog = Logging.withMarker(this)
  val securityMarker = MarkerFactory.getMarker("SECURITY")
  
  def receive = {
    case sensitiveData =>
      markLog.info(Slf4jLogMarker(securityMarker), "Processing sensitive data")
  }
}

Types

Required Akka Types

// From akka.event
sealed trait LogEvent {
  def logSource: String
  def logClass: Class[_]
  def message: Any
  def timestamp: Long
  def thread: Thread
  def mdc: Map[String, Any]
}

case class Error(cause: Throwable, logSource: String, logClass: Class[_], message: Any = Error.NoCause) extends LogEvent
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

trait LogEventWithCause extends LogEvent {
  def cause: Throwable
}

trait LogEventWithMarker extends LogEvent {
  def marker: LogMarker
}

abstract class LogMarker(val name: String)

// Message queue semantics
trait LoggerMessageQueueSemantics

SLF4J Types

// From org.slf4j
trait Logger {
  def error(msg: String): Unit
  def error(marker: Marker, msg: String): Unit
  def error(msg: String, t: Throwable): Unit
  def error(marker: Marker, msg: String, t: Throwable): Unit
  
  def warn(msg: String): Unit
  def warn(marker: Marker, msg: String): Unit
  def warn(msg: String, t: Throwable): Unit
  def warn(marker: Marker, msg: String, t: Throwable): Unit
  
  def info(msg: String): Unit
  def info(marker: Marker, msg: String): Unit
  def info(format: String, arg: Object): Unit
  def info(marker: Marker, format: String, arg: Object): Unit
  
  def debug(msg: String): Unit
  def debug(marker: Marker, msg: String): Unit
  def debug(format: String, arg: Object): Unit
  def debug(marker: Marker, format: String, arg: Object): Unit
  
  def isErrorEnabled(): Boolean
  def isErrorEnabled(marker: Marker): Boolean
  def isWarnEnabled(): Boolean
  def isWarnEnabled(marker: Marker): Boolean
  def isInfoEnabled(): Boolean
  def isInfoEnabled(marker: Marker): Boolean
  def isDebugEnabled(): Boolean
  def isDebugEnabled(marker: Marker): Boolean
}

trait Marker {
  def getName(): String
}

object MDC {
  def put(key: String, value: String): Unit
  def remove(key: String): Unit
}

Configuration

Application Configuration

Configure Akka to use SLF4J logger and filter:

akka {
  # Use SLF4J logger
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  
  # Use SLF4J-based filtering 
  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
  
  # Set Akka log level
  loglevel = "INFO"
  
  # Log config on startup
  log-config-on-start = on
  
  # Logger startup timeout
  logger-startup-timeout = 30s
}

SLF4J Backend Configuration

Configure your SLF4J backend (e.g., Logback) to handle Akka's MDC attributes:

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

SBT Dependency

Add to your build.sbt:

libraryDependencies += "com.typesafe.akka" %% "akka-slf4j" % "2.5.23"

You'll also need an SLF4J implementation like Logback:

libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"