# Beispiel für flexibles Logging mit slf4j und Logback



## Thomas Darimont (31. August 2010)

Hallo,

hier mal ein Beispiel für Logging durch SLF4J (http://www.slf4j.org/) 
und Logback (http://logback.qos.ch/). Für das Beispiel verwende ich Maven für den Build.

Pom.xml:

```
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>de.tutorials</groupId>
	<artifactId>java.logback.training</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.5.11</version>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>0.9.18</version>
			<scope>runtime</scope>
		</dependency>


		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
			<scope>testing</scope>
		</dependency>
	</dependencies>
</project>
```

Unser Logging Beispiel:

```
package de.tutorials.logging;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogBackExample {

	static Logger l = LoggerFactory.getLogger(LogBackExample.class);

	public static void main(String[] args) {

		for (int i = 0; i < 1000; i++) {
			l.debug("Hello {}", "Debug");
			l.info("Hello {}", "Info");
			l.warn("Hello {}", "Warn");
			l.trace("Hello {}", "Trace");
			l.error("Hello {}", "Error");
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
```

Unter src/main/resources legen wir nun eine logback.xml Datei an:

```
<configuration scan="true" scanPeriod="15 seconds">
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
     <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{36} - %msg%n</Pattern>
    </layout>
  </appender>

  <root level="INFO">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>
```

Mit dem Pattern-Element definieren wir die Ausgabemuster für die Log-Nachricht.
Weitere Informationen zu Möglichen Patterns findet man hier:
http://logback.qos.ch/manual/layouts.html#PatternLayout

Die Unterschiedlichen Loglevel (Info, Warning, Error, Debug, Trace) wird über das Pattern
%.-1level zu (I,W,E,D,T) reduziert (habe ich so beim Android Logging das erste mal gesehen).

Die Konfigurationsmöglichkeiten von LogBack sind um einiges Flexibler und Umfangreicher
als mit Log4J (Logback ist ja auch der Nachfolger von Log4j)

Ausgabe:

```
20:37:29.387 [main] I de.tutorials.logging.LogBackExample - Hello Info
20:37:29.391 [main] W de.tutorials.logging.LogBackExample - Hello Warn
20:37:29.391 [main] E de.tutorials.logging.LogBackExample - Hello Error
```

Will man für die Tests ein anderes (feineres) Logging haben so kann man dies mit Logback
bequem über eine weitere logging Konfigurationsdatei (logback-test.xml) die nur in Tests geladenen 
wird realisieren.

Unser Beispieltest:

```
package de.tutorials.logging;

import org.junit.Test;

public class LockBagExampleTest {
	@Test
	public void logging() {
		LogBackExample.main(null);
	}
}
```

logback-test.xml

```
<configuration scan="true" scanPeriod="15 seconds">
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
     <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{36} - %msg%n</Pattern>
    </layout>
  </appender>

  <root level="TRACE">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>
```

Diesmal habe ich das logger Level von INFO auf TRACE gesetzt.

Ausgabe:

```
20:30:10.703 [main] D de.tutorials.logging.LogBackExample - Hello Debug
20:30:10.707 [main] I de.tutorials.logging.LogBackExample - Hello Info
20:30:10.707 [main] W de.tutorials.logging.LogBackExample - Hello Warn
20:30:10.708 [main] T de.tutorials.logging.LogBackExample - Hello Trace
20:30:10.708 [main] E de.tutorials.logging.LogBackExample - Hello Error
```

Gruß Tom


----------



## Thomas Darimont (17. Januar 2011)

Hallo,

FYI:

Die "aktuellen" LogBack und SLF4J API Maven Dependencies:

```
<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
            <scope>runtime</scope>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>0.9.27</version>
            <scope>runtime</scope>
        </dependency>
```

Außerdem haben sich die Best Practices für die LogBack Konfiguration leicht geändert:
http://logback.qos.ch/codes.html#layoutInsteadOfEncoder

Beispiel:

```
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds">
	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="CONSOLE" />
	</root>
</configuration>
```

Gruß Tom


----------



## Anime-Otaku (18. Januar 2011)

Es sei noch dazu gesagt, dass man Logback sozusagen als inoffizieler Nachfolger von log4j nennen kann. Denn es wurde beides vom selben Entwickler gegründet (Ceki Gülcü).

Log4j zählt oftmals immer noch Standard-Tool zum loggen, obwohl es bereits seit Jahren nicht mehr weiter entwickelt wird. Ich bin auch erst durch Zufall auf logback gestoßen, als ich mich gefragt habe, ob log4j noch weiter entwickelt wird.


----------

