0
# Akka SLF4J
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: akka-slf4j
7
- **Package Type**: maven
8
- **Language**: Scala
9
- **Installation**: `"com.typesafe.akka" %% "akka-slf4j" % "2.5.23"`
10
11
## Core Imports
12
13
```scala
14
import akka.event.slf4j.{SLF4JLogging, Logger, Slf4jLogger, Slf4jLoggingFilter, Slf4jLogMarker}
15
```
16
17
## Basic Usage
18
19
### Configure Akka to use SLF4J
20
21
```scala
22
akka {
23
loggers = ["akka.event.slf4j.Slf4jLogger"]
24
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
25
loglevel = "INFO"
26
}
27
```
28
29
### Using SLF4JLogging trait in actors
30
31
```scala
32
import akka.actor.Actor
33
import akka.event.slf4j.SLF4JLogging
34
35
class MyActor extends Actor with SLF4JLogging {
36
def receive = {
37
case message =>
38
log.info("Received message: {}", message)
39
log.debug("Processing message...")
40
}
41
}
42
```
43
44
### Using Logger factory
45
46
```scala
47
import akka.event.slf4j.Logger
48
49
class MyService {
50
private val log = Logger(this.getClass.getName)
51
52
def doSomething(): Unit = {
53
log.info("Service operation started")
54
// ... do work ...
55
log.info("Service operation completed")
56
}
57
}
58
```
59
60
## Capabilities
61
62
### SLF4J Integration Trait
63
64
Base trait that provides SLF4J logging capability to any class.
65
66
```scala { .api }
67
trait SLF4JLogging {
68
@transient
69
lazy val log: org.slf4j.Logger
70
}
71
```
72
73
Mix this trait into your classes to get access to a lazy-initialized SLF4J logger.
74
75
### Logger Factory
76
77
Factory object for obtaining SLF4J logger instances.
78
79
```scala { .api }
80
object Logger {
81
def apply(logger: String): org.slf4j.Logger
82
def apply(logClass: Class[_], logSource: String): org.slf4j.Logger
83
def root: org.slf4j.Logger
84
}
85
```
86
87
- `apply(logger: String)` - Returns a logger for the specified logger name
88
- `apply(logClass: Class[_], logSource: String)` - Returns a logger for the specified class and source
89
- `root` - Returns the SLF4J root logger
90
91
### Akka Logger Actor
92
93
Actor that handles Akka logging events and forwards them to SLF4J backends.
94
95
```scala { .api }
96
class Slf4jLogger extends Actor with SLF4JLogging
97
with RequiresMessageQueue[LoggerMessageQueueSemantics] {
98
99
val mdcThreadAttributeName: String
100
val mdcActorSystemAttributeName: String
101
val mdcAkkaSourceAttributeName: String
102
val mdcAkkaTimestamp: String
103
104
def receive: Receive
105
final def withMdc(logSource: String, logEvent: LogEvent)(logStatement: => Unit): Unit
106
protected def formatTimestamp(timestamp: Long): String
107
}
108
```
109
110
The logger actor:
111
- Handles Akka logging events (Error, Warning, Info, Debug, InitializeLogger)
112
- Sets up MDC (Mapped Diagnostic Context) with thread, actor system, and source information
113
- Formats and forwards log events to the configured SLF4J backend
114
- Supports log markers for structured logging
115
116
MDC attribute names:
117
- `mdcThreadAttributeName` - "sourceThread"
118
- `mdcActorSystemAttributeName` - "sourceActorSystem"
119
- `mdcAkkaSourceAttributeName` - "akkaSource"
120
- `mdcAkkaTimestamp` - "akkaTimestamp"
121
122
### Logging Filter
123
124
LoggingFilter that uses SLF4J backend configuration to filter log events before publishing to the event stream.
125
126
```scala { .api }
127
class Slf4jLoggingFilter(settings: ActorSystem.Settings, eventStream: EventStream)
128
extends LoggingFilterWithMarker {
129
130
def isErrorEnabled(logClass: Class[_], logSource: String): Boolean
131
def isWarningEnabled(logClass: Class[_], logSource: String): Boolean
132
def isInfoEnabled(logClass: Class[_], logSource: String): Boolean
133
def isDebugEnabled(logClass: Class[_], logSource: String): Boolean
134
135
def isErrorEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
136
def isWarningEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
137
def isInfoEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
138
def isDebugEnabled(logClass: Class[_], logSource: String, marker: LogMarker): Boolean
139
}
140
```
141
142
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.
143
144
### Log Markers
145
146
Support for SLF4J markers in Akka logging.
147
148
```scala { .api }
149
final class Slf4jLogMarker(val marker: org.slf4j.Marker) extends LogMarker
150
151
object Slf4jLogMarker {
152
def apply(marker: org.slf4j.Marker): Slf4jLogMarker
153
def create(marker: org.slf4j.Marker): Slf4jLogMarker
154
}
155
```
156
157
Slf4jLogMarker wraps SLF4J markers for use with Akka's marker-based logging. The `create` method provides Java API compatibility.
158
159
### Usage with Markers
160
161
```scala
162
import akka.event.Logging
163
import akka.event.slf4j.Slf4jLogMarker
164
import org.slf4j.MarkerFactory
165
166
class MarkedLoggingActor extends Actor with DiagnosticActorLogging {
167
val markLog = Logging.withMarker(this)
168
val securityMarker = MarkerFactory.getMarker("SECURITY")
169
170
def receive = {
171
case sensitiveData =>
172
markLog.info(Slf4jLogMarker(securityMarker), "Processing sensitive data")
173
}
174
}
175
```
176
177
## Types
178
179
### Required Akka Types
180
181
```scala { .api }
182
// From akka.event
183
sealed trait LogEvent {
184
def logSource: String
185
def logClass: Class[_]
186
def message: Any
187
def timestamp: Long
188
def thread: Thread
189
def mdc: Map[String, Any]
190
}
191
192
case class Error(cause: Throwable, logSource: String, logClass: Class[_], message: Any = Error.NoCause) extends LogEvent
193
case class Warning(logSource: String, logClass: Class[_], message: Any) extends LogEvent
194
case class Info(logSource: String, logClass: Class[_], message: Any) extends LogEvent
195
case class Debug(logSource: String, logClass: Class[_], message: Any) extends LogEvent
196
case class InitializeLogger(bus: EventStream) extends LogEvent
197
198
trait LogEventWithCause extends LogEvent {
199
def cause: Throwable
200
}
201
202
trait LogEventWithMarker extends LogEvent {
203
def marker: LogMarker
204
}
205
206
abstract class LogMarker(val name: String)
207
208
// Message queue semantics
209
trait LoggerMessageQueueSemantics
210
```
211
212
### SLF4J Types
213
214
```scala { .api }
215
// From org.slf4j
216
trait Logger {
217
def error(msg: String): Unit
218
def error(marker: Marker, msg: String): Unit
219
def error(msg: String, t: Throwable): Unit
220
def error(marker: Marker, msg: String, t: Throwable): Unit
221
222
def warn(msg: String): Unit
223
def warn(marker: Marker, msg: String): Unit
224
def warn(msg: String, t: Throwable): Unit
225
def warn(marker: Marker, msg: String, t: Throwable): Unit
226
227
def info(msg: String): Unit
228
def info(marker: Marker, msg: String): Unit
229
def info(format: String, arg: Object): Unit
230
def info(marker: Marker, format: String, arg: Object): Unit
231
232
def debug(msg: String): Unit
233
def debug(marker: Marker, msg: String): Unit
234
def debug(format: String, arg: Object): Unit
235
def debug(marker: Marker, format: String, arg: Object): Unit
236
237
def isErrorEnabled(): Boolean
238
def isErrorEnabled(marker: Marker): Boolean
239
def isWarnEnabled(): Boolean
240
def isWarnEnabled(marker: Marker): Boolean
241
def isInfoEnabled(): Boolean
242
def isInfoEnabled(marker: Marker): Boolean
243
def isDebugEnabled(): Boolean
244
def isDebugEnabled(marker: Marker): Boolean
245
}
246
247
trait Marker {
248
def getName(): String
249
}
250
251
object MDC {
252
def put(key: String, value: String): Unit
253
def remove(key: String): Unit
254
}
255
```
256
257
## Configuration
258
259
### Application Configuration
260
261
Configure Akka to use SLF4J logger and filter:
262
263
```hocon
264
akka {
265
# Use SLF4J logger
266
loggers = ["akka.event.slf4j.Slf4jLogger"]
267
268
# Use SLF4J-based filtering
269
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
270
271
# Set Akka log level
272
loglevel = "INFO"
273
274
# Log config on startup
275
log-config-on-start = on
276
277
# Logger startup timeout
278
logger-startup-timeout = 30s
279
}
280
```
281
282
### SLF4J Backend Configuration
283
284
Configure your SLF4J backend (e.g., Logback) to handle Akka's MDC attributes:
285
286
```xml
287
<!-- logback.xml -->
288
<configuration>
289
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
290
<encoder>
291
<pattern>%d{HH:mm:ss.SSS} %-5level [%X{akkaSource}] [%X{sourceThread}] %logger{36} - %msg%n</pattern>
292
</encoder>
293
</appender>
294
295
<root level="INFO">
296
<appender-ref ref="STDOUT" />
297
</root>
298
</configuration>
299
```
300
301
### SBT Dependency
302
303
Add to your `build.sbt`:
304
305
```scala
306
libraryDependencies += "com.typesafe.akka" %% "akka-slf4j" % "2.5.23"
307
```
308
309
You'll also need an SLF4J implementation like Logback:
310
311
```scala
312
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"
313
```