14

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
lilalinux
  • 2,903
  • 3
  • 43
  • 53

4 Answers4

16

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()));
    }
Tobia Zambon
  • 7,479
  • 3
  • 37
  • 69
  • you stole Klimaschewski's answer :( – Salaros May 10 '18 at 10:57
  • 4
    @salaros: Stole !!! If you follow previous link, you don't see any answer from Klimaschewsky ! What have done Tobia Zambon is perfectly correct. He has even the honesty to reference his author. Bravo ! – schlebe Jul 20 '18 at 10:22
  • The code to define System Property can be put at begin of main() function that has been defined as static. – schlebe Jul 20 '18 at 11:16
  • A property is not equal to DOS environment variable. To use USERNAME in Log filename, you must define it in static {} bloc or main function. It would be interesting that Tobia Zambon add USERNAME in file name :-) On Windows 7, the code to add is ` System.setProperty("USERNAME", System.getenv("USERNAME"));` – schlebe Jul 20 '18 at 11:19
  • @tobia-zambon -_- – Salaros Jul 24 '18 at 04:15
  • the environmental variable is not getting set. – Stunner Jun 16 '20 at 03:19
4

Combine the answer of Udo Klimaschewski and the answer from this question in order to get the desired result.

  1. add the property append = false
  2. add a current.time system property and use it in the file name
Community
  • 1
  • 1
Udy
  • 2,492
  • 4
  • 23
  • 33
  • Perfect! Exactly what I was looking for and much simpler than a custom FileAppender like this: http://veerasundar.com/blog/2009/08/how-to-create-a-new-log-file-for-each-time-the-application-runs/ But probably it's not safe for concurrent executions, but this is not an issue for me – lilalinux Oct 02 '13 at 10:30
  • 3
    'The answer of Udo Klimaschewski' -> you are just linking to the user profile. We don't know what you are referring to. – Olivier Masseau Apr 27 '16 at 09:55
  • 1
    Although, this answer might provide solution, it is a very poor experience for a new user to find which you are referring to. Please reproduce the important code in the answer so that the user need not navigate between several links. – Pardhu Sep 07 '20 at 15:51
2

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

Vadim Zin4uk
  • 1,716
  • 22
  • 18
1

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>
Gautam Savaliya
  • 1,403
  • 2
  • 20
  • 31