JhonArias
JhonArias

Reputation: 127

How save error levels in diferents files in log4j?

I'm using log4j for javaweb app, I'll like to save each level in diferents files.

I have this log4j.properties

# Root logger option
log4j.rootLogger=INFO, file, errorfile,fatalfile

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender

#Redirect to Tomcat logs folder
#log4j.appender.file.File=${catalina.home}/logs/logging.log

log4j.appender.file.File=C:\\log\\logging.log
log4j.appender.file.encoding=UTF-8
log4j.appender.file.Threshold=INFO
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}.%M:%L - %m%n

log4j.appender.errorfile=org.apache.log4j.RollingFileAppender
log4j.appender.errorfile.encoding=UTF-8
log4j.appender.errorfile.Threshold=ERROR
log4j.appender.errorfile.File=C:\\log\\errorlogging.log
log4j.appender.errorfile.MaxFileSize=10MB
log4j.appender.errorfile.MaxBackupIndex=10
log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}.%M:%L - %m%n

log4j.appender.fatalfile=org.apache.log4j.RollingFileAppender
log4j.appender.fatalfile.encoding=UTF-8
log4j.appender.fatalfile.Threshold=FATAL
log4j.appender.fatalfile.File=C:\\log\\fatallogging.log
log4j.appender.fatalfile.MaxFileSize=10MB
log4j.appender.fatalfile.MaxBackupIndex=10
log4j.appender.fatalfile.layout=org.apache.log4j.PatternLayout
log4j.appender.fatalfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}.%M:%L - %m%n

Then, I wan to save the errors only in the file named errorlogging, the fatal in the file fatallogging but info in the file logging, but when I send an error or fatal they're saved in errorlogging, fatallogging and logging too, but I want it in diferrents files.

The way I save the log is:

private static final Logger logger = Logger.getLogger(UserRepository.class);


logger.info("Begin "+userName);
logger.fatal("An error has occurred getting the user");
logger.fatal(e.getMessage(),e);

How can I do that?, thanks for your support.

Upvotes: 0

Views: 251

Answers (1)

Ramu
Ramu

Reputation: 681

The problem with your current logging configuration is you are using only one logger which is rootLogger and routing all your log messages through rootLogger to your File, ErrorFile and FatalFile appenders with the INFO log level.

Here is what happens when an INFO level message is logged in your application.

  1. First, the root logger checks if the message can be logged or not. Since the rootLogger configured to log INFO messages, the message will be routed to all configured appenders.
  2. Message comes to File appender. Since File appender itself has a Threshold defined (which is INFO), the appender checks for the level. Since Level check condition is satisfied, the message will be logged.
  3. Now the message comes to ErrorFile appender. Same thing here as well, except the Threshold is Error. Since the Log message is at INFO level the message will not be logged in ErrorFile.
  4. Now the message comes to FatalFile appender. Here the appender threshold is Fatal. Message will not be logged in FatalFile.

Here is what happens when an ERROR level message is logged in your application.

  1. First, the root logger checks if the message can be logged or not. Since the rootLogger configured to log INFO messages and the message level is Error, the message will be routed to all configured appenders.
  2. File appender -> Level check passes for this one (as explained in the previous section), message will be logged in File appender.
  3. ErrorFile appender -> Level check passes and the message will be logged in ErrorFile.
  4. FatalFile appender -> Level check fails for this one and message will not be logged in FatalFile.

Here is what happens when an FATAL level message is logged in your application.

  1. First, the root logger checks if the message can be logged or not. Since the rootLogger configured to log INFO messages and the message level is FATAL, the message will be routed to all configured appenders.
  2. File appender -> Level check passes for this one and message will be logged in File appender.
  3. ErrorFile appender -> Level check passes and the message will be logged in ErrorFile.
  4. FatalFile appender -> Level check fails for this one and message will not be logged in FatalFile.

What you are asking, can only be done using Log4j Filters. See the below URL for a nice example on how to use the filters.

https://riptutorial.com/java/example/19786/filter-logoutput-by-level--log4j-1-x-

This example uses an XML configuration and I am not sure if the same thing can be acheived using properties configuration.

The simplest solution (or hack) is, if you have at least 2 packages and all your logging is done from 2nd level package, then you can use this instead of filters.

#FatalFile logger (Define this before the Error Logger)
log4j.logger.firstpackage.secondpackage=Fatal, FatalFile
log4j.additivity.firstpackage.secondpackage=false

#ErroFile logger
log4j.logger.firstpackage=Error, ErrorFile
log4j.additivity.firstpackage=false

Upvotes: 1

Related Questions