#Configure Logging in Spring
In the logging world, there are some options.
- JDK logging which is provided in the JDK distribution.
- Apache Commons logging
- Apache Log4j
- Logback
When you are using some third party dependencies in your project, and you maybe want to see some logging info of those, but unfortunately, if they used different logging system, it will confuse you.
SLF4J is a simple abstraction which provides advanced APIs for those logging system. Logback itself provides an implementation of slf4j API, and slf4j project provides some bridges for others which make you free from the logging specified APIs and use the general APIs provided in slf4j, and keep your logging configuration. Thus when you switch from one to another logging system, what you need to do is only the convert your configuration file and no need to change the codes.
And more magically, when you are using slf4j in your project, you can mix different logging systems and use your preferred logging for all. For example, for some historic reason, Spring core used Commons logging, but obviously log4j is more popular in these days. Through the bridge library provided by slf4j, you can configure your project logging in log4j, and also configure the Spring core Commons logging level in the same log4j configuration.
Log4j
Add the log4j and slf4j related dependencies in your POM file.
<pre> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </pre>
slf4j-log4j12
provides an implementation of slf4j-api
, and jcl-over-slf4j
provides an bridge from commons logging to slf4j APIs which hand over the logging process. You can exclude the commons logging dependency from spring-core
artifact in the project.
<pre> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> </pre>
If you are using the latest Spring IO Platform BOM, it have excluded the commons logging.
The log4j configuration example.
<pre> og4j.rootLogger=INFO, R, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Print the date in ISO 8601 format log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=application.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n log4j.logger.com.hantsylabs=debug </pre>
Log4j also provides configuration in XML form, please go to the official website for more details.
##Logback
Alternatively, you can use logback instead of log4j.
Replace the lo4j dependency with logback.
<pre> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> </pre>
logback Configuration file.
<pre> <?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>application.log</file> <encoder> <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n </pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%date %level [%thread] %class:%line %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> <logger name="com.hantsylabs.example.spring"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </logger> </configuration> </pre>
##MongoLog4jAppender
Spring Data Mongo provides a MongoLog4jAppender
which allows you store your logging info in the MongoDB, and you could do some analysis on it in future.
Add an additional dependency to the log4j solution.
<pre> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb-log4j</artifactId> </dependency> </pre>
And configure the MongoLog4jAppender
in the log4j configuration.
<pre> log4j.rootLogger=warn, M, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Print the date in ISO 8601 format log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n log4j.appender.M=org.springframework.data.mongodb.log4j.MongoLog4jAppender log4j.appender.M.layout=org.apache.log4j.PatternLayout log4j.appender.M.layout.ConversionPattern=%d %p [%c] - <%m>%n log4j.appender.M.host = localhost log4j.appender.M.port = 27017 log4j.appender.M.database = logs log4j.appender.M.collectionPattern = %c log4j.appender.M.applicationId = conference-db log4j.appender.M.warnOrHigherWriteConcern = FSYNC_SAFE log4j.logger.com.hantsylabs=debug </pre>
If the MongoDB is runging, after run the test codes, the logging info will be stored in the MongoDB.
Open Mongo shell.
<pre> mongo </pre>
After you enter the mongo shell interface, try to switch the database which is use for persisting the logging.
<pre> >use logs; </pre>
Show all collections.
<pre> >show collections </pre>
Query the collection which name is same as the logging host class name.
<pre> > db.getCollection("com.hantsylabs.example.spring4.logging.LoggingTest").find(). pretty() </pre>
You will see some info like the following.
<pre> { "_id" : ObjectId("53ca5ea8ecd6fa21712f9027"), "applicationId" : "conference-db", "name" : "com.hantsylabs.example.spring4.logging.LoggingTest", "level" : "DEBUG", "timestamp" : ISODate("2014-07-19T12:03:51.549Z"), "properties" : { "applicationId" : "conference-db" }, "message" : "==================before class=========================" } { "_id" : ObjectId("53ca5eaaecd6fa21712f9028"), "applicationId" : "conference-db", //more are omitted </pre>
##Example codes
The codes is hosted on my github.com account, check out and play it yourself.
<pre> git clone https://github.com/hantsy/spring4-sandbox </pre>
And it includes 3 Maven profiles, which are for log4j
, logback
and MongoLog4jAppender
respectively.