diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala
index d6e71aa586..0425b4c661 100644
--- a/akka-actor/src/main/scala/akka/event/Logging.scala
+++ b/akka-actor/src/main/scala/akka/event/Logging.scala
@@ -281,19 +281,34 @@ object Logging {
val debugFormat = "[DEBUG] [%s] [%s] [%s] %s".intern
/**
- * Obtain LoggingAdapter for the given application and source object. The
- * source is used to identify the source of this logging channel and must have
+ * Obtain LoggingAdapter for the given event stream (system) and source object.
+ * Note that there is an implicit conversion from [[akka.actor.ActorSystem]]
+ * to [[akka.event.LoggingBus]].
+ *
+ * The source is used to identify the source of this logging channel and must have
* a corresponding LogSource[T] instance in scope; by default these are
- * provided for Class[_], Actor, ActorRef and String types.
+ * provided for Class[_], Actor, ActorRef and String types. The source
+ * object is translated to a String according to the following rules:
+ *
+ * if it is an Actor or ActorRef, its path is used
+ * in case of a String it is used as is
+ * in case of a class an approximation of its simpleName
+ * and in all other cases the simpleName of its class
+ *
*/
def apply[T: LogSource](eventStream: LoggingBus, logSource: T): LoggingAdapter =
new BusLogging(eventStream, implicitly[LogSource[T]].genString(logSource))
/**
- * Java API: Obtain LoggingAdapter for the given application and source object. The
- * source object is used to identify the source of this logging channel; if it is
- * an Actor or ActorRef, its address is used, in case of a class an approximation of
- * its simpleName and in all other cases the simpleName of its class.
+ * Java API: Obtain LoggingAdapter for the given system and source object. The
+ * source object is used to identify the source of this logging channel. The source
+ * object is translated to a String according to the following rules:
+ *
+ * if it is an Actor or ActorRef, its path is used
+ * in case of a String it is used as is
+ * in case of a class an approximation of its simpleName
+ * and in all other cases the simpleName of its class
+ *
*/
def getLogger(system: ActorSystem, logSource: AnyRef): LoggingAdapter = apply(system.eventStream, LogSource.fromAnyRef(logSource))
@@ -354,6 +369,11 @@ object Logging {
*/
case object LoggerInitialized
+ /**
+ * Java API to create a LoggerInitialized message.
+ */
+ def loggerInitialized() = LoggerInitialized
+
class LoggerInitializationException(msg: String) extends AkkaException(msg)
trait StdOutLogger {
diff --git a/akka-docs/general/code/ConfigDocSpec.scala b/akka-docs/general/code/akka/docs/config/ConfigDocSpec.scala
similarity index 100%
rename from akka-docs/general/code/ConfigDocSpec.scala
rename to akka-docs/general/code/akka/docs/config/ConfigDocSpec.scala
diff --git a/akka-docs/general/code/akka/docs/event/LoggingDocSpec.scala b/akka-docs/general/code/akka/docs/event/LoggingDocSpec.scala
new file mode 100644
index 0000000000..3d355bccb2
--- /dev/null
+++ b/akka-docs/general/code/akka/docs/event/LoggingDocSpec.scala
@@ -0,0 +1,59 @@
+package akka.docs.event
+
+import akka.actor.ActorSystem
+import akka.testkit.AkkaSpec
+import akka.actor.Actor
+import akka.actor.Props
+
+object LoggingDocSpec {
+
+ //#my-actor
+ import akka.event.Logging
+
+ class MyActor extends Actor {
+ val log = Logging(context.system, this)
+ override def preStart() = {
+ log.debug("Starting")
+ }
+ override def preRestart(reason: Throwable, message: Option[Any]) {
+ log.error(reason, "Restarting due to [{}] when processing [{}]",
+ reason.getMessage, message.getOrElse(""))
+ }
+ def receive = {
+ case "test" ⇒ log.info("Received test")
+ case x ⇒ log.warning("Received unknown message: {}", x)
+ }
+ }
+ //#my-actor
+
+ //#my-event-listener
+ import akka.event.Logging.InitializeLogger
+ import akka.event.Logging.LoggerInitialized
+ import akka.event.Logging.Error
+ import akka.event.Logging.Warning
+ import akka.event.Logging.Info
+ import akka.event.Logging.Debug
+
+ class MyEventListener extends Actor {
+ def receive = {
+ case InitializeLogger(_) ⇒ sender ! LoggerInitialized
+ case Error(cause, logSource, message) ⇒ // ...
+ case Warning(logSource, message) ⇒ // ...
+ case Info(logSource, message) ⇒ // ...
+ case Debug(logSource, message) ⇒ // ...
+ }
+ }
+ //#my-event-listener
+
+}
+
+class LoggingDocSpec extends AkkaSpec {
+
+ import LoggingDocSpec.MyActor
+
+ "use a logging actor" in {
+ val myActor = system.actorOf(Props(new MyActor))
+ myActor ! "test"
+ }
+
+}
diff --git a/akka-docs/general/code/akka/docs/event/LoggingDocTest.scala b/akka-docs/general/code/akka/docs/event/LoggingDocTest.scala
new file mode 100644
index 0000000000..2a55bdb81a
--- /dev/null
+++ b/akka-docs/general/code/akka/docs/event/LoggingDocTest.scala
@@ -0,0 +1,5 @@
+package akka.docs.event
+
+import org.scalatest.junit.JUnitSuite
+
+class LoggingDocTest extends LoggingDocTestBase with JUnitSuite
diff --git a/akka-docs/general/code/akka/docs/event/LoggingDocTestBase.java b/akka-docs/general/code/akka/docs/event/LoggingDocTestBase.java
new file mode 100644
index 0000000000..669caa14b1
--- /dev/null
+++ b/akka-docs/general/code/akka/docs/event/LoggingDocTestBase.java
@@ -0,0 +1,86 @@
+package akka.docs.event;
+
+//#imports
+import akka.event.Logging;
+import akka.event.LoggingAdapter;
+
+//#imports
+
+//#imports-listener
+import akka.event.Logging.InitializeLogger;
+import akka.event.Logging.Error;
+import akka.event.Logging.Warning;
+import akka.event.Logging.Info;
+import akka.event.Logging.Debug;
+
+//#imports-listener
+
+import org.junit.Test;
+
+import scala.Option;
+import static org.junit.Assert.*;
+
+import akka.actor.ActorSystem;
+import akka.actor.ActorRef;
+import akka.actor.UntypedActor;
+import akka.actor.UntypedActorFactory;
+
+public class LoggingDocTestBase {
+
+ @Test
+ public void useLoggingActor() {
+ ActorSystem system = ActorSystem.create("MySystem");
+ ActorRef myActor = system.actorOf(new UntypedActorFactory() {
+ public UntypedActor create() {
+ return new MyActor();
+ }
+ });
+ myActor.tell("test");
+ system.stop();
+ }
+
+ //#my-actor
+ class MyActor extends UntypedActor {
+ LoggingAdapter log = Logging.getLogger(getContext().system(), this);
+
+ @Override
+ public void preStart() {
+ log.debug("Starting");
+ }
+
+ @Override
+ public void preRestart(Throwable reason, Option message) {
+ log.error(reason, "Restarting due to [{}] when processing [{}]", reason.getMessage(),
+ message.isDefined() ? message.get() : "");
+ }
+
+ public void onReceive(Object message) {
+ if (message.equals("test")) {
+ log.info("Received test");
+ } else {
+ log.warning("Received unknown message: {}", message);
+ }
+ }
+ }
+
+ //#my-actor
+
+ //#my-event-listener
+ class MyEventListener extends UntypedActor {
+ public void onReceive(Object message) {
+ if (message instanceof InitializeLogger) {
+ getSender().tell(Logging.loggerInitialized());
+ } else if (message instanceof Error) {
+ // ...
+ } else if (message instanceof Warning) {
+ // ...
+ } else if (message instanceof Info) {
+ // ...
+ } else if (message instanceof Debug) {
+ // ...
+ }
+ }
+ }
+ //#my-event-listener
+
+}
diff --git a/akka-docs/general/configuration.rst b/akka-docs/general/configuration.rst
index 9328e19561..96467312bd 100644
--- a/akka-docs/general/configuration.rst
+++ b/akka-docs/general/configuration.rst
@@ -47,7 +47,7 @@ with ``/``. ``-Dconfig.resource=/dev.conf`` will load the ``dev.conf`` from the
You may also specify and parse the configuration programmatically in other ways when instantiating
the ``ActorSystem``.
-.. includecode:: code/ConfigDocSpec.scala
+.. includecode:: code/akka/docs/config/ConfigDocSpec.scala
:include: imports,custom-config
The ``ConfigFactory`` provides several methods to parse the configuration from various sources.
diff --git a/akka-docs/general/index.rst b/akka-docs/general/index.rst
index f3cc0d2a7d..4853061fbc 100644
--- a/akka-docs/general/index.rst
+++ b/akka-docs/general/index.rst
@@ -7,7 +7,6 @@ General
jmm
message-send-semantics
configuration
- event-handler
- slf4j
+ logging
addressing
supervision
diff --git a/akka-docs/general/logging.rst b/akka-docs/general/logging.rst
new file mode 100644
index 0000000000..bdcf54c1cf
--- /dev/null
+++ b/akka-docs/general/logging.rst
@@ -0,0 +1,103 @@
+.. _logging:
+
+#########
+ Logging
+#########
+
+.. sidebar:: Contents
+
+ .. contents:: :local:
+
+How to Log
+==========
+
+Create a ``LoggingAdapter`` and use the ``error``, ``warning``, ``info``, or ``debug`` methods,
+as illustrated in this example in Scala:
+
+.. includecode:: code/akka/docs/event/LoggingDocSpec.scala
+ :include: my-actor
+
+Corresponding example in Java:
+
+.. includecode:: code/akka/docs/event/LoggingDocTestBase.java
+ :include: imports,my-actor
+
+The second parameter to the ``Logging`` or ``Logging.getLogger`` is the source of this logging channel.
+The source object is translated to a String according to the following rules:
+
+ * if it is an Actor or ActorRef, its path is used
+ * in case of a String it is used as is
+ * in case of a class an approximation of its simpleName
+ * and in all other cases the simpleName of its class
+
+The log message may contain argument placeholders ``{}``, which will be substituted if the log level
+is enabled.
+
+Event Handler
+=============
+
+Logging is performed asynchronously through an event bus. You can configure which event handlers that should
+subscribe to the logging events. That is done using the 'event-handlers' element in the :ref:`configuration`.
+Here you can also define the log level.
+
+.. code-block:: ruby
+
+ akka {
+ # Event handlers to register at boot time (Logging$DefaultLogger logs to STDOUT)
+ event-handlers = ["akka.event.Logging$DefaultLogger"]
+ loglevel = "DEBUG" # Options: ERROR, WARNING, INFO, DEBUG
+ }
+
+The default one logs to STDOUT and is registered by default. It is not intended to be used for production. There is also an :ref:`slf4j`
+event handler available in the 'akka-slf4j' module.
+
+Example of creating a listener in Scala:
+
+.. includecode:: code/akka/docs/event/LoggingDocSpec.scala
+ :include: my-event-listener
+
+Corresponding example in Java:
+
+.. includecode:: code/akka/docs/event/LoggingDocTestBase.java
+ :include: imports,imports-listener,my-event-listener
+
+
+.. _slf4j:
+
+SLF4J
+=====
+
+Akka provides an event handler for `SL4FJ `_. This module is available in the 'akka-slf4j.jar'.
+It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4J backend, we recommend `Logback `_:
+
+ .. code-block:: scala
+
+ lazy val logback = "ch.qos.logback" % "logback-classic" % "1.0.0" % "runtime"
+
+
+You need to enable the Slf4jEventHandler in the 'event-handlers' element in
+the :ref:`configuration`. Here you can also define the log level of the event bus.
+More fine grained log levels can be defined in the configuration of the SLF4J backend
+(e.g. logback.xml). The String representation of the source object that is used when
+creating the ``LoggingAdapter`` correspond to the name of the SL4FJ logger.
+
+.. code-block:: ruby
+
+ akka {
+ event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
+ loglevel = "DEBUG"
+ }
+
+Logging thread in MDC
+---------------------
+
+Since the logging is done asynchronously the thread in which the logging was performed is captured in
+Mapped Diagnostic Context (MDC) with attribute name ``sourceThread``.
+With Logback the thread name is available with ``%X{sourceThread}`` specifier within the pattern layout configuration::
+
+
+
+ %date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n
+
+
+
diff --git a/akka-docs/general/slf4j.rst b/akka-docs/general/slf4j.rst
deleted file mode 100644
index 296cbb7b48..0000000000
--- a/akka-docs/general/slf4j.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-.. _slf4j:
-
-SLF4J
-=====
-
-This module is available in the 'akka-slf4j.jar'. It has one single dependency; the slf4j-api jar. In runtime you
-also need a SLF4J backend, we recommend `Logback `_:
-
- .. code-block:: scala
-
- lazy val logback = "ch.qos.logback" % "logback-classic" % "1.0.0" % "runtime"
-
-
-Event Handler
--------------
-
-This module includes a SLF4J Event Handler that works with Akka's standard Event Handler. You enabled it in the 'event-handlers' element in
-the :ref:`configuration`. Here you can also define the log level.
-
-.. code-block:: ruby
-
- akka {
- event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
- loglevel = "DEBUG"
- }
-
-Read more about how to use the :ref:`event-handler`.
-
-Logging thread in MDC
----------------------
-
-Since the logging is done asynchronously the thread in which the logging was performed is captured in
-Mapped Diagnostic Context (MDC) with attribute name ``sourceThread``.
-With Logback the thread name is available with ``%X{sourceThread}`` specifier within the pattern layout configuration::
-
-
-
- %date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n
-
-
-
-
\ No newline at end of file