Use Log4j to output different Package logs to different files

  • 2020-05-27 05:30:51
  • OfStack


As the scale of the project grows larger and larger, new modules will be introduced constantly. Different modules will print their own logs, which eventually makes it impossible to view the logs. For example, in my own project, there are the following logs:

The log of receiving external messages and the log of sending messages; Processing log of background resident thread; Interface logs such as parameters accessed by the external interface and return results; Service access to the database generates SQL logs;

Among these, the amount of log data for message logging and background threads is very large, if all the logs are printed in one file, use tail -f log.log File, you will find the log in a fast scroll, can not view or even locate a specific SQL or Service access log.

The solution is that different logs can be classified output, so that the logs do not affect each other, especially the important interface access log, can be very convenient to locate and troubleshoot the problem.

Step 1: configure in

I'm going to post one of my own Configuration:

log4j.rootLogger=INFO, console, file
log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p crazyant-web %-17c{2} (%13F:%L) %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} - %m%n
log4j.appender.file.layout.ConversionPattern=[%-5p] crazyant-web %d{yyyy-MM-dd HH:mm:ss,SSS} %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} method:%l%n%m%n
log4j.appender.file.encoding=UTF-8, message
log4j.appender.message.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.message.encoding=UTF-8, async
log4j.appender.async.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.async.encoding=UTF-8, showsql, showsql
log4j.appender.showsql.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.showsql.encoding=UTF-8, service
log4j.appender.service.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n

At the bottom of the configuration file, you can easily see that I output message(messages), async(back-end threads), showsql(database logs), and service(interface calls) to different log files.

Some explanations:

log4j.rootLogger=INFO, console, file

log4j has the concept of 1 rootLogger and normal Logger. By default, we only need 1 rootLogger, which means that all the logs will only be output to this 1 log file.

Take a look at the configuration of normal Logger (for example, interface log service) :

1., service

In this sentence" net.czt.crazyant.service ", indicating the full path of package in effect for this normal logger log configuration

Where the color service represents the name of the common logger


One of the" net.czt.crazyant.service ", as above, represents the package for which this configuration item is targeted

Do not output the package log to the rootLogger log, but only to your own configured log.

3, log4j.appender.service=org.apache.log4j.RollingFileAppender , and the configuration items under the configuration section

The "service" string here, which is the same as the "service" of the first configuration item above, represents the configuration of the ordinary Logger;

The configuration items at the bottom are the same as rootLogger, representing daily output files, encoding UTF8, sharding rules, output patterns per line, and so on

My own problem is the one above After the configuration, I found that each log file was created, but there was no content in it. Why is this? Let's look at the second thing to notice;

Step 2. When logging is output, the specific Class corresponding to the logging object should be set

What does that mean? In the configuration item above, there is 1" net.czt.crazyant.service "package string, so we think 1, log4j is how to output logger logs in different package to different files, think 1, there are two ways:

1. Using intercepter or aop, log4j detects the log output by itself. If it detects the log generated by package, it will output it to the corresponding file;

2. The user transmits one Class parameter, and log4j gets the corresponding Package of Class, which shall prevail to locate different log files;

Looking at the code 1, it is obvious that log4j USES the latter one in a simple and direct way:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyClassImpl implements MyClass {
  * loger
 private static final Log logger = LogFactory.getLog(MyClassImpl.class);
  * my func
 public void myfunc() {"call method myfunc.");

in log4j.properties0 , the Class parameter using the logger is passed in, and the Class is reflected to the package address, which is the package address used by log4j to output the log.

It also has a strong place, convenient logical log category, such as a lot of code that does not belong to a package, but they are logically belongs to 1, for example, message processing, not just in the interface to invoke Service package may also send msg operation call, if you want to put msg package 1 some log output to Service also, so in this msg logger initialization, into a Serivice Class.

Or for all logs of a class 1, all of their logger objects come from a single encapsulated object instance that passes in only one parameter to identify the logical categorization.


in , which supports the output of package or class logs separately, but also requires the initialization of logger in the code to correspond to package in the log configuration.

Well, the above is the entire content of this article, I hope the content of this article to your study or work can bring 1 definite help, if you have questions you can leave a message to communicate.

Related articles: