<?xml version="1.0"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
-->

<document xmlns="http://maven.apache.org/XDOC/2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
    <properties>
        <title>Log4j 2 API</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
        <author email="ggregory@apache.org">Gary Gregory</author>
    </properties>

    <body>
        <section name="Log4j 2 API">
          <a name="Overview"/>
          <subsection name="Overview">
            <p>
              The Log4j 2 API provides the interface that applications should code to and provides the
              adapter components required for implementers to create a logging implementation. Although Log4j 2
              is broken up between an API and an implementation, the primary purpose of doing so was not to
              allow multiple implementations, although that is certainly possible, but to clearly define
              what classes and methods are safe to use in "normal" application code.
            </p>
            <h4>Hello World!</h4>
            <p>
              No introduction would be complete without the customary Hello, World example. Here is ours. First,
              a Logger with the name "HelloWorld" is obtained from the
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html">LogManager</a>.
              Next, the logger is used to write the "Hello, World!" message, however the message will be written
              only if the Logger is configured to allow informational messages.
            </p>
            <pre class="prettyprint linenums">import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class HelloWorld {
    private static final Logger logger = LogManager.getLogger("HelloWorld");
    public static void main(String[] args) {
        logger.info("Hello, World!");
    }
}</pre>
            <p>
              The output from the call to logger.info() will vary significantly depending on the configuration
              used. See the <a href="./configuration.html">Configuration</a> section for more details.
            </p>
            <h4>Substituting Parameters</h4>
            <p>
              Frequently the purpose of logging is to provide information about what is happening in the system,
              which requires including information about the objects being manipulated. In Log4j 1.x this could
              be accomplished by doing:
            </p>
            <pre class="prettyprint linenums">if (logger.isDebugEnabled()) {
    logger.debug("Logging in user " + user.getName() + " with birthday " + user.getBirthdayCalendar());
}</pre>
            <p>
              Doing this repeatedly has the effect of making the code feel like it is more about logging than the
              actual task at hand. In addition, it results in the logging level being checked twice; once on the
              call to isDebugEnabled and once on the debug method. A better alternative would be:
            </p>
            <pre class="prettyprint">logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());</pre>
            <p>
              With the code above the logging level will only be checked once and the String construction will
              only occur when debug logging is enabled.
            </p>
            <h4>Formatting Parameters</h4>
            <p>
              Formatter Loggers leave formatting up to you if <code>toString()</code> is not what you want.
              To facilitate formatting, you can use the same format strings as Java's
              <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax">Formatter</a>.
              For example:
            </p>
            <pre class="prettyprint linenums">public static Logger logger = LogManager.getFormatterLogger("Foo");

logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
logger.debug("Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);
</pre>
            <p>
              To use a formatter Logger, you must call one of the LogManager
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getFormatterLogger(java.lang.Class)">getFormatterLogger</a>
              methods. The output for this example shows that Calendar toString() is verbose compared to custom formatting:
            </p>
            <pre class="prettyprint linenums">2012-12-12 11:56:19,633 [main] DEBUG: User John Smith with birthday java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=1995,MONTH=4,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=23,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
2012-12-12 11:56:19,643 [main] DEBUG: User John Smith with birthday 05 23, 1995
2012-12-12 11:56:19,643 [main] DEBUG: Integer.MAX_VALUE = 2,147,483,647
2012-12-12 11:56:19,643 [main] DEBUG: Long.MAX_VALUE = 9,223,372,036,854,775,807
</pre>
          <h4>Mixing Loggers with Formatter Loggers</h4>
          <p>
          Formatter loggers give fine-grained control over the output format, but have the drawback
          that the correct type must be specified (for example, passing anything other than a decimal integer
          for a %d format parameter gives an exception).
          </p>
          <p>
          If your main usage is to use {}-style parameters, but occasionally you need fine-grained
          control over the output format, you can use the <code>printf</code> method:</p>
            <pre class="prettyprint linenums">public static Logger logger = LogManager.getLogger("Foo");

logger.debug("Opening connection to {}...", someDataSource);
logger.printf(Level.INFO, "Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
</pre>

          <a name="LambdaSupport"/>
            <h4>Java 8 lambda support for lazy logging</h4>
            <p>
              In release 2.4, the <code>Logger</code> interface added support for lambda expressions.
              This allows client code to lazily log messages without explicitly checking if the requested log
              level is enabled. For example, previously you would write:
            </p>
            <pre class="prettyprint linenums">// pre-Java 8 style optimization: explicitly check the log level
// to make sure the expensiveOperation() method is only called if necessary
if (logger.isTraceEnabled()) {
    logger.trace(&quot;Some long-running operation returned {}&quot;, expensiveOperation());
}</pre>
            <p>
              With Java 8 you can achieve the same effect with a lambda expression.
              You no longer need to explicitly check the log level:
            </p>
            <pre class="prettyprint linenums">// Java-8 style optimization: no need to explicitly check the log level:
// the lambda expression is not evaluated if the TRACE level is not enabled
logger.trace(&quot;Some long-running operation returned {}&quot;, () -> expensiveOperation());</pre>

          <h4>Logger Names</h4>
            <p>
              Most logging implementations use a hierarchical scheme for matching logger names with logging
              configuration. In this scheme, the logger name hierarchy is represented by <code>'.'</code> characters 
              in the logger name, in a fashion very similar to the hierarchy used for Java package names. For example,
              <code>org.apache.logging.appender</code> and <code>org.apache.logging.filter</code> both have 
              <code>org.apache.logging</code> as their parent. In most cases, applications name their loggers by 
              passing the current class's name to <code>LogManager.getLogger(...)</code>. Because this usage is so 
              common, Log4j 2 provides that as the default when the logger name parameter is either omitted or is 
              null. For example, in all examples below  the Logger will have a name of 
              <code>"org.apache.test.MyTest"</code>.
            </p>
            <pre class="prettyprint linenums">package org.apache.test;

public class MyTest {
    private static final Logger logger = LogManager.getLogger(MyTest.class);
}</pre>
            <pre class="prettyprint linenums">package org.apache.test;

public class MyTest {
    private static final Logger logger = LogManager.getLogger(MyTest.class.getName());
}</pre>
            <pre class="prettyprint linenums">package org.apache.test;

public class MyTest {
    private static final Logger logger = LogManager.getLogger();
}</pre>
          </subsection>
        </section>
    </body>
</document>
