How do you configure log4j.properties to have exactly one logfile per run of an app.
I've read that you should use a timestamp in the filename but that will create many files per run as time goes by.
I tried DailyRollingFileAppender and RollingFileAppender but can't find a way to configure exctly one log per run. The log should not be broken into multiple logs and it shouldn't be truncated and files of old runs should be preserved.
Each class has a static org.slf4j.Logger for it's own class name:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
This is my current log4j.properties
log4j.rootLogger=error, RootAppender, RootErrorAppender
#log4j.logger.com.example=info, qspaBackendAppender, stderr
log4j.logger.com.example=info, qspaBackendAppender
log4j.additivity.com.example=true
#log4j.logger.com.example.util=trace, qspaBackendAppender, stderr
#log4j.additivity.com.example.util=true
log4j.appender.qspaBackendAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.qspaBackendAppender.file=logs/qspaBackend.log
log4j.appender.qspaBackendAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.qspaBackendAppender.layout.ConversionPattern=<%d{yyyy-MM-dd HH:mm:ss}> %-5p : %C{1} %c{2} : %m%n
log4j.appender.stderr=org.apache.log4j.ConsoleAppender
log4j.appender.stderr.Target=System.err
log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
log4j.appender.stderr.layout.ConversionPattern=%-5p %c{1}:%L - %m%n
log4j.appender.RootAppender=org.apache.log4j.RollingFileAppender
log4j.appender.RootAppender.file=logs/root.log
log4j.appender.RootAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.RootAppender.layout.ConversionPattern=<%d{yyyy-MM-dd HH:mm:ss}> %-5p : %C{1} %c{2} : %m%n
log4j.appender.RootErrorAppender=org.apache.log4j.RollingFileAppender
log4j.appender.RootErrorAppender.file=logs/rootError.log
log4j.appender.RootErrorAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.RootErrorAppender.layout.ConversionPattern=<%d{yyyy-MM-dd HH:mm:ss}> %-5p : %C{1} %c{2} : %m%n
log4j.appender.RootErrorAppender.threshold=error
I had troubles retrieving which Udo Klimaschewski's answer Udy was referring so I put here my solution.
log4j.properties:
# Root logger option
log4j.rootLogger=INFO, fileout
# Direct log messages to file
log4j.appender.fileout=org.apache.log4j.FileAppender
log4j.appender.fileout.File=/logs/myapp_${current.date}.log
log4j.appender.fileout.ImmediateFlush=true
log4j.appender.fileout.Threshold=debug
log4j.appender.fileout.Append=false
log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
log4j.appender.fileout.layout.conversionPattern=%5p | %d | %m%n
Then put in the main class this block:
public class Starter {
static{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hhmmss");
System.setProperty("current.date", dateFormat.format(new Date()));
}
Combine the answer of Udo Klimaschewski and the answer from this question in order to get the desired result.
add the property append = false
add a current.time system property and use it in the file name
To start a new log file on app startup you may want to use OnStartupTriggeringPolicy
Triggering Policies
Example of XML config:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Properties>
<Property name="log-path">C:/Logs/</Property>
</Properties>
<Appenders>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<RollingFile name="RollingFile" fileName="${log-path}/app.log"
filePattern="${log-path}/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<pattern>%d{dd/MM/yyyy HH:mm:ss} [%-5p/%t]: %C{1}(%L): %m%n</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="100"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="root" level="debug" additivity="false">
<appender-ref ref="RollingFile" level="debug"/>
<appender-ref ref="console" level="debug"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
Works well for me
Using filePattern Property
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<property name="filePattern">${date:yyyy-MM-dd-HH_mm_ss}</property>
</Properties>
<Appenders>
<File name="File" fileName="export/logs/app_${filePattern}.log" append="false">
<PatternLayout
pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="File" />
</Root>
</Loggers>
</Configuration>
Related
I'm using log4j (through slf4j) and I'd like logs from some packages to output filename and line numbers but for others I just need the level and the message. Is there a way to achieve this? Is it possible to specific different layout.ConversionPattern for different classes/packages using the log4j2.properties file?
You can use more than one appender of the same type:
Here is an example:
<Appenders>
<Console name="ConsoleA" target="SYSTEM_OUT">
<PatternLayout pattern=="%-4r [%t] %-5p %c %x - %m%n" />
</Console>
<Console name="ConsoleB" target="SYSTEM_OUT">
<PatternLayout pattern=="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.foo.BarA" level="trace">
<AppenderRef ref="ConsoleA"/>
</Logger>
<Logger name="com.foo.BarB" level="trace">
<AppenderRef ref="ConsoleB"/>
</Logger>
</Loggers>
Read more at Log4J configuration manual
I am trying out log4j2 configuration
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<appenders>
<Console name="console-log" target="SYSTEM_OUT" append="false">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36}:%L %M - %msg%xEx%n"/>
</Console>
<File name="debug-log" fileName="${catalina.base}/logs/debug.log" append="false">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss.SSS z} %-5level %class{36}:%L %M - %msg%xEx%n"/>
</File>
<File name="trace-log" fileName="${catalina.base}/logs/trace.log" append="false">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss.SSS z} %-5level %class{36}:%L %M - %msg%xEx%n"/>
</File>
<File name="error-log" fileName="${catalina.base}/logs/error.log" append="false">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss.SSS z} %-5level %class{36}:%L %M - %msg%xEx%n"/>
</File>
</appenders>
<loggers>
<root level="debug" additivity="false">
<appender-ref ref="console-log"/>
</root>
<Logger name="com.mypackage" level="debug" additivity="false">
<appender-ref ref="debug-log" level="debug"/>
<appender-ref ref="trace-log" level="info"/>
<appender-ref ref="error-log" level="error"/>
</Logger>
</loggers>
</configuration>
I am getting logging and data to catalina.out but the rest of the files are not getting created.
Couldn't figure out the silly mistake I might be doing here?
and How do I create one more file which can have the appended logs of debug-log,trace-log,error-log only.
You have an error in your config:
Console appenders shouldn't have an append attribute. Removing that should fix your config.
Additionally the additivity attribute on the Root logger is unnecessary. It does nothing, as there is no higher logger to add to.
You should definitely have seen a line like the following in your output, warning you about the bad config:
ERROR Console contains an invalid element or attribute "append"
i have this configuration in my log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="FileLogger" fileName="HelloLog4j.log" append="false">
<PatternLayout pattern="%d %t %-5p %c{2} - %m%n"/>
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="hello" level="trace">
<AppenderRef ref="FileLogger"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
i put this file in src/resources, and i follow this guide: Guide
but when i run my project i have this error:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
I would avoid the use of DOMConfigurator, stick to the standard: put log4j2.xml in your classpath. Where that is depends on your app and your runtime environment.
The XML file has to be inside the src folder itself and not inside src/resources or anything inside it, it has to be at root level of the folder.However if that does not work out here is a slightly different way of doing it.
You can use DOM Configurator to configure the logger manually.
Below is a sample snippet which describers how you can use it.
private static org.apache.log4j.Logger logger;
public static Logger getLogger(){
if(logger == null){
logger= LogManager.getLogger(ClassName.class);
DOMConfigurator.configure("path/to/log4jxml");
}
return logger;
}
Class name would be the class in which you are instantiating the class.It is good practice to use Singleton design pattern for this in a custom class and then instantiating it via the getLogger method.Don't forget to make your constructor private.
Edit:
A sample config for console appender.The conversion pattern is date layout.
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="console" />
</root>
I'm migrating from log4j 1.2 to log4j 2.0. Earlier all my console logs and logs were printed in specific log files. But after migrating, Console logs are printed in tomcat7-stderr.logs and other logs are printed in specific log file.
Is there a way I can print console logs also to the file I specified in log4j2.xml?
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="all">
<appenders>
<Console name="STDOUT">
<PatternLayout pattern="<%X{UOWID}> [%t] %d{yyyy/MMM/dd HH:mm:ss} %-5p [%c{1}] %m%n"/>
</Console>
<RollingFile name="fileAppender" fileName="${sys:catalina.base}/logs/omp-web-services.log" filePattern="${sys:catalina.base}/logs/omp-web-services.log">
<PatternLayout pattern="<%X{UOWID}> [%t] %d{yyyy/MMM/dd HH:mm:ss} %-5p [%c{1}] %m%n" />
<Policies>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="INFO">
<appenderRef ref="STDOUT" level="info"/>
<appenderRef ref="fileAppender" level="info"/>
</root>
</loggers>
Someone can say me how I can change my log4j2.xml to add 1 log file: one level trace and one level info?
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="debug">
<appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</Console>
<File name="DEBUG_FILE" fileName="debug.txt">
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</File>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
</root>
</loggers>
</configuration>
You could make the root logger TRACE level (all messages) and put a ThresholdFilter on the Console so that only some messages are displayed on the console.
This configuration will log only ERROR messages to the console, and at the same time will log all messages (TRACE, DEBUG, INFO, ERROR...) to the debug.txt file. Error and higher messages are logged both in the console and in the file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="ERROR">
<appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</Console>
<File name="DEBUG_FILE" fileName="debug.txt">
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</File>
</appenders>
<loggers>
<root level="trace">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
</root>
</loggers>
</configuration>
By the way, please be aware that your pattern layout contains conversion patterns that require location information (%C, %F and %L, to be exact).
This means that for every log message, log4j2 needs to take a snapshot of the stack, and then walk the stack trace to find the class and method that did the logging.
This is very, very slow.
Logging will be 2-5 times slower for synchronous logging and 4-20 times slower for asynchronous logging.
If performance is not an issue then it doesn't matter, but it is definitely something to be aware of. Personally I just use %c (the logger name) and my app's log messages are unique enough that I can quickly find where the message came from. Just my 2 cents.
--- update 2013-04-27 ---
I have since learned a simpler way to do this: you can set a level on the appender-ref.
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="debug">
<appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p %c{2} - %m%n" /> <!--without location-->
</Console>
<File name="DEBUG_FILE" fileName="debug.txt">
<PatternLayout pattern="%d %-5p %c{2} - %m%n" />
</File>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="CONSOLE" level="ERROR" />
<appender-ref ref="DEBUG_FILE" />
</root>
</loggers>
</configuration>