287

I'd like a very simple XML configuration file with a console and a file appender using log4j2.

(The Apache Website is killing me with much Information.)

Thorsten Niehues
  • 13,712
  • 22
  • 78
  • 113
  • 100
    Haha - so glad you said this "(The Apache Website is killing me with much Information.)" – thonnor Jan 10 '17 at 15:57
  • 34
    That sentence of yours _(The Apache Website is killing me with much Information.)_ is the main reason why I'm viewing your question! – Ju Oliveira Oct 19 '17 at 15:02

4 Answers4

331
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <File name="MyFile" fileName="all.log" immediateFlush="false" append="false">
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
            <AppenderRef ref="MyFile"/>
        </Root>
    </Loggers>
</Configuration>

Notes:

  • Put the following content in your configuration file.
  • Name the configuration file log4j2.xml
  • Put the log4j2.xml in a folder which is in the class-path (i.e. your source folder "src")
  • Use Logger logger = LogManager.getLogger(); to initialize your logger
  • I did set the immediateFlush="false" since this is better for SSD lifetime. If you need the log right away in your log-file remove the parameter or set it to true
Thorsten Niehues
  • 13,712
  • 22
  • 78
  • 113
  • 1
    For completeness, use of immediateFlush="false" is especially recommended when using Async Loggers or AsyncAppender. – Remko Popma Jan 19 '14 at 02:33
  • 1
    Background: immediateFlush="false" allows Log4J2's async components to batch together multiple log events in a single disc write. As a bonus, your most recent log events are always written to disk and never left hanging in a memory buffer. (Something I found annoying about log4j-1.2.) – Remko Popma Jan 19 '14 at 02:40
  • 2
    I couldnt' get the examples on the Log4j 2.0 site to work but this one did. Thank you. – djangofan Feb 17 '14 at 05:57
  • 14
    **Please** add the fact that a clean may be required for those who use eclipse. For the sake of mankind. – Reut Sharabani Apr 25 '15 at 17:39
  • @ReutSharabani you just did in your comment. Pls specify further. – Thorsten Niehues May 05 '15 at 12:59
  • 2
    @ThorstenNiehues I can't edit my previous comment, but eclipse copies the configuration when you build, and for some reason it doesn't always copy the log4j.xml even if it changed. At least that's what solved it for me. – Reut Sharabani May 05 '15 at 13:07
  • Probably if you edit it ouside of Eclipse. Then it does not detect a file change without cleaning the project – Thorsten Niehues May 05 '15 at 13:28
  • Why doesn't this file have a linked XSD? It's confusing if anyone looks at just the XML, but also there is no autocomplete in Eclipse without it – Navin Israni Jun 26 '17 at 17:31
  • instead of `all.log` file name, how to pass file name dynamically? – Faizan Mubasher May 24 '18 at 07:33
  • What jars do I need for this? – runnerpaul Aug 22 '18 at 21:36
  • What is the policy here? Is it rolling file, or time based? What is the max file size? And how does it write to file? (does file always contains last 10mb of logs?) – Tina J Jan 08 '19 at 17:52
  • @TinaJ It is a file Appender. It doesn’t roll so there is no policy. It will write to the file until the disk is full. You seem to be thinking of the rolling file appender, but that is not what was configured here. – rgoers Jan 09 '20 at 07:46
  • @ThorstenNiehues thanks a LOT dude. If you can do one for a db Appdender, I would really appreciate it. – Beezer Aug 07 '20 at 16:50
26

Here is my simplistic log4j2.xml that prints to console and writes to a daily rolling file:

// java
private static final Logger LOGGER = LogManager.getLogger(MyClass.class);


// log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="logPath">target/cucumber-logs</Property>
        <Property name="rollingFileName">cucumber</Property>
    </Properties>
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%highlight{%-5level}] %d{DEFAULT} %c{1}.%M() - %msg%n%throwable{short.lineNumber}" />
        </Console>
        <RollingFile name="rollingFile" fileName="${logPath}/${rollingFileName}.log" filePattern="${logPath}/${rollingFileName}_%d{yyyy-MM-dd}.log">
            <PatternLayout pattern="[%highlight{%-5level}] %d{DEFAULT} %c{1}.%M() - %msg%n%throwable{short.lineNumber}" />
            <Policies>
                <!-- Causes a rollover if the log file is older than the current JVM's start time -->
                <OnStartupTriggeringPolicy />
                <!-- Causes a rollover once the date/time pattern no longer applies to the active file -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="DEBUG" additivity="false">
            <AppenderRef ref="console" />
            <AppenderRef ref="rollingFile" />
        </Root>
    </Loggers>
</Configuration>

TimeBasedTriggeringPolicy

interval (integer) - How often a rollover should occur based on the most specific time unit in the date pattern. For example, with a date pattern with hours as the most specific item and and increment of 4 rollovers would occur every 4 hours. The default value is 1.

modulate (boolean) - Indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. For example, if the item is hours, the current hour is 3 am and the interval is 4 then the first rollover will occur at 4 am and then next ones will occur at 8 am, noon, 4pm, etc.

Source: https://logging.apache.org/log4j/2.x/manual/appenders.html

Output:

[INFO ] 2018-07-21 12:03:47,412 ScenarioHook.beforeScenario() - Browser=CHROME32_NOHEAD
[INFO ] 2018-07-21 12:03:48,623 ScenarioHook.beforeScenario() - Screen Resolution (WxH)=1366x768
[DEBUG] 2018-07-21 12:03:52,125 HomePageNavigationSteps.I_Am_At_The_Home_Page() - Base URL=http://simplydo.com/projector/
[DEBUG] 2018-07-21 12:03:52,700 NetIncomeProjectorSteps.I_Enter_My_Start_Balance() - Start Balance=348000

A new log file will be created daily with previous day automatically renamed to:

cucumber_yyyy-MM-dd.log

In a Maven project, you would put the log4j2.xml in src/main/resources or src/test/resources.

k_rollo
  • 5,304
  • 16
  • 63
  • 95
  • I wonder if we run our program successfully on the first day and all our logging messages are written to the created file, but suddenly we terminate our program and restart it in the same day. When we restart, will it create a new file and write it there, or will it write to the existing file that it created on the same day? @silver – zordu-nickim-agzivi-sikm Nov 27 '21 at 08:31
12

log4j2 has a very flexible configuration system (which IMHO is more a distraction than a help), you can even use JSON. See https://logging.apache.org/log4j/2.x/manual/configuration.html for a reference.

Personally, I just recently started using log4j2, but I'm tending toward the "strict XML" configuration (that is, using attributes instead of element names), which can be schema-validated.

Here is my simple example using autoconfiguration and strict mode, using a "Property" for setting the filename:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorinterval="30" status="info" strict="true">
    <Properties>
        <Property name="filename">log/CelsiusConverter.log</Property>
    </Properties>
    <Appenders>
        <Appender type="Console" name="Console">
            <Layout type="PatternLayout" pattern="%d %p [%t] %m%n" />
        </Appender>
        <Appender type="Console" name="FLOW">
            <Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n" />
        </Appender>
        <Appender type="File" name="File" fileName="${filename}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="File" />
            <AppenderRef ref="Console" />
            <!-- Use FLOW to trace down exact method sending the msg -->
            <!-- <AppenderRef ref="FLOW" /> -->
        </Root>
    </Loggers>
</Configuration>
Christof Kälin
  • 1,384
  • 2
  • 17
  • 26
  • The flexible configuration comes in handy when you're trying to separate config from build and put config into a repository elsewhere. Unfortunately, the complexities are making it a bit annoying, but just thought I would throw out a benefit to the flexible options for configuration. – adprocas Sep 07 '17 at 12:50
  • What is the `File` policy here? What is the max file size? And how does it write to file? (does file always contains last 10mb of logs?) – Tina J Jan 08 '19 at 17:54
4

There are excellent answers, but if you want to color your console logs you can use the pattern :

<PatternLayout pattern="%style{%date{DEFAULT}}{yellow}
            [%t] %highlight{%-5level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green} %logger{36} - %message\n"/>

The full log4j2 file is:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="APP_LOG_ROOT">/opt/test/log</Property>
    </Properties>
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%style{%date{DEFAULT}}{yellow}
                [%t] %highlight{%-5level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green} %logger{36} - %message\n"/>
        </Console>
        <RollingFile name="XML_ROLLING_FILE_APPENDER"
                     fileName="${APP_LOG_ROOT}/appName.log"
                     filePattern="${APP_LOG_ROOT}/appName-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="%d{DEFAULT} [%t] %-5level %logger{36} - %msg%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="19500KB"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
        <Logger name="com.compName.projectName" level="debug">
            <AppenderRef ref="XML_ROLLING_FILE_APPENDER"/>
        </Logger>
    </Loggers>
</Configuration>

And the logs will look like this: enter image description here

Max.Futerman
  • 1,012
  • 2
  • 9
  • 30