2011-12-13 14:46:15 +01:00
|
|
|
|
.. _logging-java:
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2011-12-13 14:46:15 +01:00
|
|
|
|
################
|
|
|
|
|
|
Logging (Java)
|
|
|
|
|
|
################
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
How to Log
|
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
|
|
Create a ``LoggingAdapter`` and use the ``error``, ``warning``, ``info``, or ``debug`` methods,
|
2011-12-13 14:46:15 +01:00
|
|
|
|
as illustrated in this example:
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
2012-09-26 10:56:25 +02:00
|
|
|
|
:include: imports
|
|
|
|
|
|
|
|
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
|
|
|
|
|
:include: my-actor
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-01-13 13:50:42 +01:00
|
|
|
|
The first parameter to ``Logging.getLogger`` could also be any
|
|
|
|
|
|
:class:`LoggingBus`, specifically ``system.eventStream()``; in the demonstrated
|
|
|
|
|
|
case, the actor system’s address is included in the ``akkaSource``
|
|
|
|
|
|
representation of the log source (see `Logging Thread and Akka Source in MDC`_)
|
|
|
|
|
|
while in the second case this is not automatically done. The second parameter
|
|
|
|
|
|
to ``Logging.getLogger`` is the source of this logging channel. The source
|
|
|
|
|
|
object is translated to a String according to the following rules:
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
|
|
|
|
|
* 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
|
|
|
|
|
|
|
2012-02-22 11:00:00 +01:00
|
|
|
|
The log message may contain argument placeholders ``{}``, which will be
|
|
|
|
|
|
substituted if the log level is enabled. Giving more arguments as there are
|
|
|
|
|
|
placeholders results in a warning being appended to the log statement (i.e. on
|
|
|
|
|
|
the same line with the same severity). You may pass a Java array as the only
|
|
|
|
|
|
substitution argument to have its elements be treated individually:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTestBase.java#array
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-01-13 13:50:42 +01:00
|
|
|
|
The Java :class:`Class` of the log source is also included in the generated
|
|
|
|
|
|
:class:`LogEvent`. In case of a simple string this is replaced with a “marker”
|
|
|
|
|
|
class :class:`akka.event.DummyClassForStringSources` in order to allow special
|
|
|
|
|
|
treatment of this case, e.g. in the SLF4J event listener which will then use
|
|
|
|
|
|
the string instead of the class’ name for looking up the logger instance to
|
|
|
|
|
|
use.
|
|
|
|
|
|
|
2012-01-23 13:54:11 +01:00
|
|
|
|
Auxiliary logging options
|
|
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
|
|
|
|
Akka has a couple of configuration options for very low level debugging, that makes most sense in
|
|
|
|
|
|
for developers and not for operations.
|
|
|
|
|
|
|
2012-01-23 14:35:01 +01:00
|
|
|
|
You almost definitely need to have logging set to DEBUG to use any of the options below:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
|
|
|
|
|
loglevel = DEBUG
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-23 13:54:11 +01:00
|
|
|
|
This config option is very good if you want to know what config settings are loaded by Akka:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
|
|
|
|
|
# Log the complete configuration at INFO level when the actor system is started.
|
|
|
|
|
|
# This is useful when you are uncertain of what configuration is used.
|
2012-02-09 20:40:09 +01:00
|
|
|
|
log-config-on-start = on
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
If you want very detailed logging of all automatically received messages that are processed
|
|
|
|
|
|
by Actors:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
2012-04-08 01:10:19 +02:00
|
|
|
|
actor {
|
|
|
|
|
|
debug {
|
2012-09-26 10:56:25 +02:00
|
|
|
|
# enable DEBUG logging of all AutoReceiveMessages (Kill, PoisonPill et.c.)
|
2012-04-08 01:10:19 +02:00
|
|
|
|
autoreceive = on
|
|
|
|
|
|
}
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
If you want very detailed logging of all lifecycle changes of Actors (restarts, deaths etc):
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
2012-04-08 01:10:19 +02:00
|
|
|
|
actor {
|
|
|
|
|
|
debug {
|
|
|
|
|
|
# enable DEBUG logging of actor lifecycle changes
|
|
|
|
|
|
lifecycle = on
|
|
|
|
|
|
}
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
If you want very detailed logging of all events, transitions and timers of FSM Actors that extend LoggingFSM:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
2012-04-08 01:10:19 +02:00
|
|
|
|
actor {
|
|
|
|
|
|
debug {
|
|
|
|
|
|
# enable DEBUG logging of all LoggingFSMs for events, transitions and timers
|
|
|
|
|
|
fsm = on
|
|
|
|
|
|
}
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
If you want to monitor subscriptions (subscribe/unsubscribe) on the ActorSystem.eventStream:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
2012-04-08 01:10:19 +02:00
|
|
|
|
actor {
|
|
|
|
|
|
debug {
|
|
|
|
|
|
# enable DEBUG logging of subscription changes on the eventStream
|
|
|
|
|
|
event-stream = on
|
|
|
|
|
|
}
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Auxiliary remote logging options
|
|
|
|
|
|
--------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
If you want to see all messages that are sent through remoting at DEBUG log level:
|
|
|
|
|
|
(This is logged as they are sent by the transport layer, not by the Actor)
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
|
|
|
|
|
remote {
|
2012-09-26 10:56:25 +02:00
|
|
|
|
# If this is "on", Akka will log all outbound messages at DEBUG level,
|
|
|
|
|
|
# if off then they are not logged
|
2012-01-23 14:14:39 +01:00
|
|
|
|
log-sent-messages = on
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
If you want to see all messages that are received through remoting at DEBUG log level:
|
|
|
|
|
|
(This is logged as they are received by the transport layer, not by any Actor)
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
|
|
|
|
|
remote {
|
2012-09-26 10:56:25 +02:00
|
|
|
|
# If this is "on", Akka will log all inbound messages at DEBUG level,
|
|
|
|
|
|
# if off then they are not logged
|
2012-01-23 14:14:39 +01:00
|
|
|
|
log-received-messages = on
|
2012-01-23 13:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-08-14 11:29:54 +02:00
|
|
|
|
Also see the logging options for TestKit: :ref:`actor.logging-java`.
|
2012-01-23 14:35:01 +01:00
|
|
|
|
|
2012-01-23 13:54:11 +01:00
|
|
|
|
|
2011-12-13 12:33:29 +01:00
|
|
|
|
Event Handler
|
|
|
|
|
|
=============
|
|
|
|
|
|
|
2011-12-14 15:12:40 +01:00
|
|
|
|
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`.
|
2011-12-13 12:33:29 +01:00
|
|
|
|
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"]
|
2011-12-14 15:12:40 +01:00
|
|
|
|
# Options: ERROR, WARNING, INFO, DEBUG
|
|
|
|
|
|
loglevel = "DEBUG"
|
2011-12-13 12:33:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-12-14 15:12:40 +01:00
|
|
|
|
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-java`
|
2011-12-13 12:33:29 +01:00
|
|
|
|
event handler available in the 'akka-slf4j' module.
|
|
|
|
|
|
|
2011-12-13 14:46:15 +01:00
|
|
|
|
Example of creating a listener:
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
2012-09-26 10:56:25 +02:00
|
|
|
|
:include: imports,imports-listener
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
|
.. includecode:: code/docs/event/LoggingDocTestBase.java
|
|
|
|
|
|
:include: my-event-listener
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2011-12-13 14:46:15 +01:00
|
|
|
|
.. _slf4j-java:
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
|
|
|
|
|
SLF4J
|
|
|
|
|
|
=====
|
|
|
|
|
|
|
2011-12-14 15:12:40 +01:00
|
|
|
|
Akka provides an event handler for `SL4FJ <http://www.slf4j.org/>`_. This module is available in the 'akka-slf4j.jar'.
|
2011-12-13 12:33:29 +01:00
|
|
|
|
It has one single dependency; the slf4j-api jar. In runtime you also need a SLF4J backend, we recommend `Logback <http://logback.qos.ch/>`_:
|
|
|
|
|
|
|
2011-12-13 14:46:15 +01:00
|
|
|
|
.. code-block:: xml
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2011-12-13 14:46:15 +01:00
|
|
|
|
<dependency>
|
|
|
|
|
|
<groupId>ch.qos.logback</groupId>
|
|
|
|
|
|
<artifactId>logback-classic</artifactId>
|
2012-06-07 20:40:14 +02:00
|
|
|
|
<version>1.0.4</version>
|
2011-12-13 14:46:15 +01:00
|
|
|
|
<scope>runtime</scope>
|
|
|
|
|
|
</dependency>
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2011-12-14 15:12:40 +01:00
|
|
|
|
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.
|
2011-12-13 12:33:29 +01:00
|
|
|
|
More fine grained log levels can be defined in the configuration of the SLF4J backend
|
2012-02-03 10:47:56 +01:00
|
|
|
|
(e.g. logback.xml).
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
|
|
|
|
|
.. code-block:: ruby
|
|
|
|
|
|
|
|
|
|
|
|
akka {
|
|
|
|
|
|
event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
|
|
|
|
|
|
loglevel = "DEBUG"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-02-03 10:47:56 +01:00
|
|
|
|
The SLF4J logger selected for each log event is chosen based on the
|
2012-02-03 11:42:59 +01:00
|
|
|
|
:class:`Class` of the log source specified when creating the
|
2012-02-03 10:47:56 +01:00
|
|
|
|
:class:`LoggingAdapter`, unless that was given directly as a string in which
|
|
|
|
|
|
case that string is used (i.e. ``LoggerFactory.getLogger(Class c)`` is used in
|
|
|
|
|
|
the first case and ``LoggerFactory.getLogger(String s)`` in the second).
|
|
|
|
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
2012-06-04 23:35:52 +02:00
|
|
|
|
Beware that the actor system’s name is appended to a :class:`String` log
|
2012-02-03 10:47:56 +01:00
|
|
|
|
source if the LoggingAdapter was created giving an :class:`ActorSystem` to
|
|
|
|
|
|
the factory. If this is not intended, give a :class:`LoggingBus` instead as
|
|
|
|
|
|
shown below:
|
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: scala
|
|
|
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
|
final LoggingAdapter log = Logging.getLogger(system.eventStream(), "my.string");
|
2012-02-03 10:47:56 +01:00
|
|
|
|
|
2012-01-11 14:14:08 +01:00
|
|
|
|
Logging Thread and Akka Source in MDC
|
|
|
|
|
|
-------------------------------------
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
|
|
|
|
|
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::
|
|
|
|
|
|
|
2011-12-14 15:12:40 +01:00
|
|
|
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
2012-02-07 11:21:49 +01:00
|
|
|
|
<encoder>
|
2011-12-14 15:12:40 +01:00
|
|
|
|
<pattern>%date{ISO8601} %-5level %logger{36} %X{sourceThread} - %msg%n</pattern>
|
2012-02-07 11:21:49 +01:00
|
|
|
|
</encoder>
|
2011-12-14 15:12:40 +01:00
|
|
|
|
</appender>
|
2011-12-13 12:33:29 +01:00
|
|
|
|
|
2012-01-13 13:50:42 +01:00
|
|
|
|
.. note::
|
2012-02-09 20:40:09 +01:00
|
|
|
|
|
2012-01-13 13:50:42 +01:00
|
|
|
|
It will probably be a good idea to use the ``sourceThread`` MDC value also in
|
|
|
|
|
|
non-Akka parts of the application in order to have this property consistently
|
|
|
|
|
|
available in the logs.
|
|
|
|
|
|
|
2012-01-11 14:14:08 +01:00
|
|
|
|
Another helpful facility is that Akka captures the actor’s address when
|
|
|
|
|
|
instantiating a logger within it, meaning that the full instance identification
|
|
|
|
|
|
is available for associating log messages e.g. with members of a router. This
|
|
|
|
|
|
information is available in the MDC with attribute name ``akkaSource``::
|
|
|
|
|
|
|
|
|
|
|
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
2012-02-07 11:21:49 +01:00
|
|
|
|
<encoder>
|
2012-01-11 14:14:08 +01:00
|
|
|
|
<pattern>%date{ISO8601} %-5level %logger{36} %X{akkaSource} - %msg%n</pattern>
|
2012-02-07 11:21:49 +01:00
|
|
|
|
</encoder>
|
2012-01-11 14:14:08 +01:00
|
|
|
|
</appender>
|
|
|
|
|
|
|
|
|
|
|
|
For more details on what this attribute contains—also for non-actors—please see
|
|
|
|
|
|
`How to Log`_.
|