log4j - INFO to console and ERRORS to file - java

I want to redirect all messages with error level to file and messages with info level to console.
Here is my log4j.properties:
log4j.rootLogger=INFO, stdout
log4j.logger.java.lang.Exception=ALL, java.lang.Exception
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.java.lang.Exception=org.apache.log4j.RollingFileAppender
log4j.appender.java.lang.Exception.File=\\clientexceptionlog.txt
log4j.appender.java.lang.Exception.MaxFileSize=2048KB
log4j.appender.java.lang.Exception.layout=org.apache.log4j.PatternLayout
log4j.appender.java.lang.Exception.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
But seems like it doesn't work as I expect: clientexceptionlog.txt is always empty.
What I'm doing wrong? Thanks!

You may work with the Treshold option. Doing it that way, you can set the rootLogger to both, stdout and your file appender (I named it myAppender in the following code snippet):
log4j.rootLogger=INFO, stdout, myAppender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.myAppender=org.apache.log4j.RollingFileAppender
log4j.appender.myAppender.Threshold=WARN
log4j.appender.myAppender.File=\\clientexceptionlog.txt
log4j.appender.myAppender.MaxFileSize=2048KB
log4j.appender.myAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppender.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
What does it do? It sends everything with a loglevel INFO or higher to stdout and myAppender. While stdout will output all (including higher loglevels like WARN and ERROR) the myAppender will filter out everything that is lower than WARN (due to log4j.appender.myAppender.Threshold=WARN).
BTW: Don't use java.lang.Exception as name for the appender. That may confuse any one reading this configuration (including me!)

Related

Why do I get DEBUG level logging in console?

I have a log4j properties file defined like so:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.logger.com.github.user=DEBUG, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=target/cucumber-parser.log
log4j.appender.file.MaxFileSize=5MB
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}:%L - %m%n
Based on my understanding, INFO level logging should be routed to stdout (console) and DEBUG should be only written to file. However I get both, INFO and DEBUG level in console. What am I doing wrong?
I managed to solve my problem by applying the below line to log4j.appender.stdout:
log4j.appender.stdout.Threshold=INFO
With this line added to the original configuration that I posted in my original question, only the INFO level logs will be printed to the console and DEBUG will be rerouted to a file as desired.
Because INFO level covers DEBUG level. So that you see both.
See more Logging Levels
If you check log4j doc or this tutorial you can see more information about levels, but basically: ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF
So log shows the selected level and all the greaters.
add log4j.additivity.com.github.user=false.
As in your config, level of com.github.user is being set to debug. And besides "file", it will also be additive to root logger, so you can see debug log of com.github.user in the console.
In fact, if you write the config this way, splitting loggers and appenders, you can understand better.
log4j.rootLogger=INFO, stdout
log4j.logger.com.github.user=DEBUG, file
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=target/cucumber-parser.log
log4j.appender.file.MaxFileSize=5MB
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}:%L - %m%n
For loggers, you specified com.github.user to be debug, and all others info with rootlogger setting.
Then com.github.user will be printed to file, and all logs will be printed to console . And if you set the additivity, com.github.user will be removed from rootlogger, so there will only be other logs in console.

Custom layout for log4j

There is a way to print different layout for different log level? For example:
logger.warn("Message");
print something like this: 2016-06-20 13:34:41,245 INFO (main:) Message
and for logger.info("Message2");
print just: Message2
Is possible to do that? To define one layout to warn e other layout for info
log4j.properties
# Root logger option
log4j.rootLogger=INFO, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=log4j.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%m%n %d %-5p [%c] (%t:%x) %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] (%t:%x) %m%n
I haven't tested but it should work. If you define two appenders and you assign a pattern for each appenders. Then the keyword Threshold should filter the level
:
# Root logger option
log4j.rootLogger=INFO, fileWarning, fileInfo, stdout
log4j.appender.fileWarning=org.apache.log4j.RollingFileAppender
log4j.appender.fileWarning.File=log4j.log
log4j.appender.fileWarning.MaxFileSize=10MB
log4j.appender.fileWarning.MaxBackupIndex=10
log4j.appender.fileWarning.layout=org.apache.log4j.PatternLayout
log4j.appender.fileWarning.layout.ConversionPattern=%m%n %d %-5p [%c] (%t:%x) %m%n
log4j.appender.fileWarning.Threshold=WARNING
log4j.appender.fileInfo=org.apache.log4j.RollingFileAppender
log4j.appender.fileInfo.File=log4j.log
log4j.appender.fileInfo.MaxFileSize=10MB
log4j.appender.fileInfo.MaxBackupIndex=10
log4j.appender.fileInfo.layout=org.apache.log4j.PatternLayout
log4j.appender.fileInfo.layout.ConversionPattern=%m%n
log4j.appender.fileInfo.Threshold=INFO
Hope it's help.

Java Log4J Logger Messages

I am working on log4j with Java. I am redirecting all my applications logger messages to a specific folder inside my project like this:
logs/log4j-MyFirstClass.log
If I want to redirect specific file messages to specific log file, for ex: ABC.java logger messages to ABC.log file, then how should I change this log4J.properties file ? Please help. Here is my log4j.properties file:
# Root logger option
log4j.rootLogger=DEBUG, stdout, file
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Redirect log messages to a log file, support file rolling.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logs/log4j-MyFirstClass.log
log4j.appender.file.MaxFileSize=5MB
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}:%L - %m%n
You need to define an appender for each file, then specify which packages use which appender.
# Root logger option; everything logs to console at debug
log4j.rootLogger=INFO, stdout
# Classes in package com.foo.bar will use the file1 appender
log4j.logger.com.foo.bar=file1
# Classes in package com.whizz.bang will use the file2 appender, note we also overrode the default log level
log4j.logger.com.whizz.bang=DEBUG, file2
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Appender for file 1
log4j.appender.file1=org.apache.log4j.RollingFileAppender
log4j.appender.file1.File=logs/log4j-first.log
log4j.appender.file1.MaxFileSize=5MB
log4j.appender.file1.MaxBackupIndex=10
log4j.appender.file1.layout=org.apache.log4j.PatternLayout
log4j.appender.file1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Appender for file 2
log4j.appender.file2=org.apache.log4j.RollingFileAppender
log4j.appender.file2.File=logs/log4j-second.log
log4j.appender.file2.MaxFileSize=5MB
log4j.appender.file2.MaxBackupIndex=10
log4j.appender.file2.layout=org.apache.log4j.PatternLayout
log4j.appender.file2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

Duplicate exception and warning in separate file with log4j

log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=sip.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=%d %p %t %c - %m%n
Above is my log4j configuration. How to duplicate all exceptions and warning in separate log file? I would like to avoid code mofidications
Just add another logger like "R2".
log4j.rootLogger=debug, stdout, R, R2
...
log4j.appender.R2=org.apache.log4j.RollingFileAppender
log4j.appender.R2.File=sip2.log
log4j.appender.R2.Threshold=WARN
...

Is there a way to define default layout?

# Root logger option
log4j.rootLogger=ALL, stdout, A1
log4j.logger.org.apache.jsp=ALL, stdout, A1
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] [%c:%L] - %m%n
# LOG4J daily rolling log files configuration
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=logs/file.log
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] [%c:%L] - %m%n
Most of the time I define several appenders... one for Console and some others into files. But most of the time I used the same layout for the output.
Is there a way to define a default one ?
Something like that ?
log4j.appender.layout=org.apache.log4j.PatternLayout
log4j.appender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%p] [%c:%L] - %m%n
# Root logger option
log4j.rootLogger=ALL, stdout, A1
log4j.logger.org.apache.jsp=ALL, stdout, A1
PATTERN=%d{yyyy-MM-dd HH:mm:ss} [%p] %l - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=${PATTERN}
# LOG4J daily rolling log files configuration
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=logs/file.log
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=${PATTERN}
It seems that the only way to do this is to set a variable, as I've done with PATTERN=%d{yyyy-MM-dd HH:mm:ss} [%p] %l - %m%n

Categories