Repository: logging-log4j2
Updated Branches:
  refs/heads/master 9ef1cc933 -> 15cd6ac1c


LOG4J2-1802: Convert FAQ to asciidoc


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/15cd6ac1
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/15cd6ac1
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/15cd6ac1

Branch: refs/heads/master
Commit: 15cd6ac1c7f1d6838994490c15d5e1bcc006d987
Parents: 9ef1cc9
Author: Matt Sicker <boa...@gmail.com>
Authored: Fri Apr 6 19:50:03 2018 -0500
Committer: Matt Sicker <boa...@gmail.com>
Committed: Fri Apr 6 19:50:03 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/faq.adoc  | 497 +++++++++++++++++++++++++++++++++++++++
 src/site/markdown/faq.md.vm | 480 -------------------------------------
 2 files changed, 497 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/15cd6ac1/src/site/asciidoc/faq.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/faq.adoc b/src/site/asciidoc/faq.adoc
new file mode 100644
index 0000000..b5cfd78
--- /dev/null
+++ b/src/site/asciidoc/faq.adoc
@@ -0,0 +1,497 @@
+////
+    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
+
+        https://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.
+////
+= Frequently Asked Questions
+:toc:
+
+'''
+
+[#missing_core]
+== I'm seeing this error "Unable to locate a logging implementation, using 
SimpleLogger". What is wrong?
+
+You have the log4j-api-2.x jar file in your classpath but you still need
+to add the log4j-core-2.x jar to the classpath. (Also, it looks like you
+are using an old version of Log4j 2. You may want to upgrade.)
+
+[#which_jars]
+== Which JAR files do I need?
+
+You need at least the log4j-api-2.x and the log4j-core-2.x jar files.
+
+The other jars are necessary if your application calls the API of
+another logging framework and you want to route logging calls to the
+Log4j 2 implementation.
+
+image:images/whichjar-2.x.png[Diagram showing which JARs correspond to
+which systems]
+
+You can use the log4j-to-slf4j adapter jar when your application calls
+the Log4j 2 API and you want to route logging calls to a SLF4J
+implementation.
+
+image:images/whichjar-slf4j-2.x.png[Diagram showing the dependency flow
+to use Log4j 2 API with SLF4J]
+
+Some of the Log4j components have features with optional dependencies.
+The component page will have more detail. For example, the
+link:log4j-core/index.html[log4j-core component page] has an outline of
+which log4j-core features have external dependencies.
+
+[#exclusions]
+== How do I exclude conflicting dependencies?
+
+There are several scenarios where you may end up with conflicting
+dependencies, especially transitively included ones. The following table
+shows for each Log4j dependency on the left (implicit groupId of
+`org.apache.logging.log4j`), the following dependencies on the right can
+be safely excluded (given in the format `groupId:artifactId`).
+
+[cols="4*"]
+|===
+|Log4j Dependency
+3+|Dependencies to Exclude
+
+|log4j-1.2-api
+|log4j:log4j
+2+|org.slf4j:log4j-over-slf4j
+
+|log4j-core
+|log4j:log4j
+|ch.qos.logback:logback-core
+|org.apache.logging.log4j:log4j-to-slf4j
+
+|log4j-jcl
+3+|org.slf4j:jcl-over-slf4j
+
+|log4j-jul
+3+|org.slf4j:jul-to-slf4j
+
+|log4j-slf4j-impl
+|org.apache.logging.log4j:log4j-to-slf4j
+2+|ch.qos.logback:logback-core
+|===
+
+Using Apache Maven, dependencies can be globally excluded in your
+project like so:
+
+[source,xml]
+----
+<dependencies>
+  <dependency>
+    <groupId>log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>1.2.17</version>
+    <scope>provided</scope>
+  </dependency>
+</dependencies>
+----
+
+Dependencies can be explicitly excluded for specific dependencies as
+well. For example, to use a project with Log4j 2 instead of Log4j 1.x:
+
+[source,xml,subs="attributes,specialchars"]
+----
+<dependencies>
+  <dependency>
+    <groupId>com.example</groupId>
+    <artifactId>example-project</artifactId>
+    <version>1.0</version>
+    <exclusions>
+      <exclusion>
+        <groupId>log4j</groupId>
+        <artifactId>log4j</artifactId>
+      </exclusion>
+      <exclusion>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-log4j12</artifactId>
+      </exclusion>
+    </exclusions>
+  </dependency>
+  <dependency>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-core</artifactId>
+    <version>{Log4jReleaseVersion}</version>
+  </dependency>
+  <dependency>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-slf4j-impl</artifactId>
+    <version>{Log4jReleaseVersion}</version>
+  </dependency>
+  <dependency>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j-1.2-api</artifactId>
+    <version>{Log4jReleaseVersion}</version>
+  </dependency>
+</dependencies>
+----
+
+Dependencies can be globally excluded in Gradle like so:
+
+[source,groovy]
+----
+configurations {
+  all*.exclude group: 'log4j', module: 'log4j'
+}
+----
+
+The equivalent Gradle config for the above Maven exclusion would look
+like:
+
+[source,groovy,subs=attributes]
+----
+dependencies {
+  compile('com.example:example-project:1.0') {
+    exclude group: 'log4j', module: 'log4j'
+    exclude group: 'org.slf4j', module: 'slf4j-log4j12'
+  }
+  compile('org.apache.logging.log4j:log4j-core:{Log4jReleaseVersion}')
+  compile('org.apache.logging.log4j:log4j-slf4j-impl:{Log4jReleaseVersion}')
+  compile('org.apache.logging.log4j:log4j-1.2-api:{Log4jReleaseVersion}')
+}
+----
+
+[#config_location]
+== How do I specify the configuration file location?
+
+By default, Log4j looks for a configuration file named *log4j2.xml* (not
+log4j.xml) in the classpath.
+
+You can also specify the full path of the configuration file with this
+system property: `-Dlog4j.configurationFile=path/to/log4j2.xml`
+
+That property can also be included in a classpath resource file named
+`log4j2.component.properties`.
+
+Web applications can specify the Log4j configuration file location with
+a servlet context parameter. See
+http://logging.apache.org/log4j/2.x/manual/webapp.html#ContextParams[this
+section] of the Using Log4j 2 in Web Applications manual page.
+
+[#config_from_code]
+== How do I configure log4j2 in code without a configuration file?
+
+Starting with version 2.4, Log4j 2 provides an
+link:manual/customconfig.html[API for programmatic configuration] The
+new
+link:log4j-core/apidocs/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.html[`ConfigurationBuilder`
+API] allows you to create Configurations in code by constructing
+component definitions without requiring you to know about the internals
+of actual configuration objects like Loggers and Appenders.
+
+[#reconfig_from_code]
+== How do I reconfigure log4j2 in code with a specific configuration file?
+
+See the below example. Be aware that this LoggerContext class is not
+part of the public API so your code may break with any minor release.
+
+[source,java]
+----
+// import org.apache.logging.log4j.core.LoggerContext;
+
+LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) 
LogManager.getContext(false);
+File file = new File("path/to/a/different/log4j2.xml");
+
+// this will force a reconfiguration
+context.setConfigLocation(file.toURI());
+----
+
+[#shutdown]
+== How do I shut down log4j2 in code?
+
+Normally there is no need to do this manually. Each `LoggerContext`
+registers a shutdown hook that takes care of releasing resources when
+the JVM exits (unless system property `log4j.shutdownHookEnabled` is set
+to `false`). Web applications should include the log4j-web module in
+their classpath which disables the shutdown hook but instead cleans up
+log4j resources when the web application is stopped.
+
+However, if you need to manually shut down Log4j, you can do so as in
+the below example. Note that there is an optional parameter for
+specifying which `LoggerContext` to shut down.
+
+[source,java]
+----
+import org.apache.logging.log4j.LogManager;
+
+// ...
+
+LogManager.shutdown();
+----
+
+[#config_sep_appender_level]
+== How do I send log messages with different levels to different
+appenders? You don’t need to declare separate loggers to achieve this.
+You can set the logging level on the `AppenderRef` element.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <File name="file" fileName="app.log">
+      <PatternLayout>
+        <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
+      </PatternLayout>
+    </File>
+    <Console name="STDOUT" target="SYSTEM_OUT">
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="trace">
+      <AppenderRef ref="file" level="DEBUG"/>
+      <AppenderRef ref="STDOUT" level="INFO"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#troubleshooting]
+== How do I debug my configuration?
+
+First, make sure you have link:#which_jars[the right jar files] on your
+classpath. You need at least log4j-api and log4j-core.
+
+Next, check the name of your configuration file. By default, log4j2 will
+look for a configuration file named `log4j2.xml` on the classpath. Note
+the ``2'' in the file name! (See the
+link:manual/configuration.html#AutomaticConfiguration[configuration
+manual page] for more details.)
+
+*From log4j-2.9 onward*
+
+From log4j-2.9 onward, log4j2 will print all internal logging to the
+console if system property `log4j2.debug` is defined (with any or no
+value).
+
+*Prior to log4j-2.9*
+
+Prior to log4j-2.9, there are two places where internal logging can be
+controlled:
+
+If the configuration file is found correctly, log4j2 internal status
+logging can be controlled by setting `<Configuration status="trace">` in
+the configuration file. This will display detailed log4j2-internal log
+statements on the console about what happens during the configuration
+process. This may be useful to trouble-shoot configuration issues. By
+default the status logger level is WARN, so you only see notifications
+when there is a problem.
+
+If the configuration file is not found correctly, you can still enable
+log4j2 internal status logging by setting system property
+`-Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE`.
+
+[#separate_log_files]
+== How do I dynamically write to separate log files?
+
+Look at the
+http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender[RoutingAppender].
+You can define multiple routes in the configuration, and put values in
+the `ThreadContext` map that determine which log file subsequent events
+in this thread get logged to.
+
+You can use the `ThreadContext` map value to determine the log file
+name.
+
+[source,xml]
+----
+<Routing name="Routing">
+  <Routes pattern="$${ctx:ROUTINGKEY}">
+
+    <!-- This route is chosen if ThreadContext has value 'special' for key 
ROUTINGKEY. -->
+    <Route key="special">
+      <RollingFile name="Rolling-${ctx:ROUTINGKEY}" 
fileName="logs/special-${ctx:ROUTINGKEY}.log"
+    
filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-special-%d{yyyy-MM-dd}-%i.log.gz">
+    <PatternLayout>
+      <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
+    </PatternLayout>
+    <Policies>
+      <TimeBasedTriggeringPolicy interval="6" modulate="true" />
+          <SizeBasedTriggeringPolicy size="10 MB" />
+    </Policies>
+      </RollingFile>
+    </Route>
+
+    <!-- This route is chosen if ThreadContext has no value for key 
ROUTINGKEY. -->
+    <Route key="$${ctx:ROUTINGKEY}">
+      <RollingFile name="Rolling-default" fileName="logs/default.log"
+    filePattern="./logs/${date:yyyy-MM}/default-%d{yyyy-MM-dd}-%i.log.gz">
+        <PatternLayout>
+      <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
+        </PatternLayout>
+        <Policies>
+          <TimeBasedTriggeringPolicy interval="6" modulate="true" />
+          <SizeBasedTriggeringPolicy size="10 MB" />
+        </Policies>
+      </RollingFile>
+    </Route>
+
+    <!-- This route is chosen if ThreadContext has a value for ROUTINGKEY
+         (other than the value 'special' which had its own route above).
+         The value dynamically determines the name of the log file. -->
+    <Route>
+      <RollingFile name="Rolling-${ctx:ROUTINGKEY}" 
fileName="logs/other-${ctx:ROUTINGKEY}.log"
+    
filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-other-%d{yyyy-MM-dd}-%i.log.gz">
+    <PatternLayout>
+      <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
+    </PatternLayout>
+    <Policies>
+      <TimeBasedTriggeringPolicy interval="6" modulate="true" />
+      <SizeBasedTriggeringPolicy size="10 MB" />
+    </Policies>
+      </RollingFile>
+    </Route>
+  </Routes>
+</Routing>
+----
+
+[#reconfig_level_from_code]
+== How do I set a logger’s level programmatically?
+
+You can set a logger’s level with the class
+link:log4j-core/apidocs/org/apache/logging/log4j/core/config/Configurator.html[`Configurator`]
+from Log4j Core. Be aware that the `Configurator` class is not part of
+the public API.
+
+[source,xml]
+----
+// org.apache.logging.log4j.core.config.Configurator;
+
+Configurator.setLevel("com.example.Foo", Level.DEBUG);
+
+// You can also set the root logger:
+Configurator.setRootLevel(Level.DEBUG);
+----
+
+[#retention]
+== How do I set my log archive retention policy? How do I delete old log 
archives?
+
+The `DefaultRolloverStrategy` of the Rolling File appender (and Rolling
+Random Access File appender) supports a
+link:manual/appenders.html#CustomDeleteOnRollover[Delete] element.
+
+Starting at a specified base directory, you can delete all files for
+which some condition holds true, for example all files that match a
+given file name pattern and are older than some number of days. More
+complex conditions are possible, and if the built-in conditions are not
+sufficient, users can provide custom conditions by creating
+link:manual/appenders.html#DeletePathCondition[plugin conditions] or by
+writing a link:manual/appenders.html#ScriptCondition[script condition].
+
+[#api-tradeoffs]
+== What are the trade-offs of using the Log4j 2 API versus the SLF4J API?
+
+The Log4j 2 API and SLF4J have a lot in common. They both share the
+objective of cleanly separating the logging API from the implementation.
+We believe that the Log4j 2 API can help make your application more
+performant while offering more functionality and more flexibility.
+
+There may be a concern that using the Log4j 2 API will tightly couple
+your application to Log4j 2. This is not the case: applications coded to
+the Log4j 2 API always have the option to use any SLF4J-compliant
+library as their logging implementation with the log4j-to-slf4j adapter.
+See the link:#which_jars_log4j-to-slf4j[which jars] FAQ entry for
+details.
+
+There are several advantages to using the Log4j 2 API:
+
+* SLF4J forces your application to log Strings. The Log4j 2 API supports
+logging any CharSequence if you want to log text, but also supports
+logging any Object as is. It is the responsibility of the logging
+implementation to handle this object, and we consider it a design
+mistake to limit applications to logging Strings.
+* The Log4j 2 API offers support for logging
+link:manual/messages.html[Message objects]. Messages allow support for
+interesting and complex constructs to be passed through the logging
+system and be efficiently manipulated. Users are free to create their
+own Message types and write custom Layouts, Filters and Lookups to
+manipulate them.
+* The Log4j 2 API has support for Java 8
+link:manual/api.html#LambdaSupport[lambda expressions].
+* The Log4j 2 API has better support for
+link:manual/garbagefree.html[garbage-free logging]: it avoids creating
+vararg arrays and avoids creating Strings when logging CharSequence
+objects.
+
+[#gc-free-slf4j]
+== Is Log4j 2 still garbage-free when I use the SLF4J API?
+
+Yes, the log4j-slf4j-impl binding (together with log4j-core) implements
+the `org.slf4j.Logger` methods to be GC-free. However, bear in mind that
+there are some limitations:
+
+The SLF4J API only offers up to two parameters for a parameterized
+message. More than that uses varargs which creates a temporary object
+for the parameter array. The Log4j 2.6 API has methods for up to ten
+unrolled parameters.
+
+Another consideration is that the SLF4J API forces your application to
+log Strings. Log4j 2 API lets you log any java.lang.CharSequence, and
+even any Objects. Log4j can log any Object that implements
+`java.lang.CharSequence` or
+`org.apache.logging.log4j.util.StringBuilderFormattable` without
+creating garbage.
+
+The
+http://www.slf4j.org/api/org/slf4j/spi/LocationAwareLogger.html#log(org.slf4j.Marker,%20java.lang.String,%20int,%20java.lang.String,%20java.lang.Object%5B%5D,%20java.lang.Throwable)[`org.slf4j.spi.LocationAwareLogger::log`]
+method is not yet implemented in a garbage-free manner in the
+log4j-slf4j-impl binding. It creates a new message object for each call.
+
+[#gc-free-domain-object]
+== How do I log my domain object without creating garbage?
+
+One option is to let the domain object implement java.lang.CharSequence.
+However, for many domain objects it may not be trivial to implement this
+without allocating temporary objects.
+
+An alternative is to implement the
+`org.apache.logging.log4j.util.StringBuilderFormattable` interface. If
+an object is logged that implements this interface, its `formatTo`
+method is called instead of `toString()`.
+
+[source,java]
+----
+package org.apache.logging.log4j.util;
+public interface StringBuilderFormattable {
+    /**
+     * Writes a text representation of this object into the specified {@code 
StringBuilder},
+     * ideally without allocating temporary objects.
+     *
+     * @param buffer the StringBuilder to write into
+     */
+     void formatTo(StringBuilder buffer);
+}
+----
+
+[#logger-wrapper]
+== How do I create a custom logger wrapper that shows the correct class, 
method and line number?
+
+Log4j remembers the fully qualified class name (FQCN) of the logger and
+uses this to walk the stack trace for every log event when configured to
+print location. (Be aware that logging with location is slow and may
+impact the performance of your application.)
+
+The problem with custom logger wrappers is that they have a different
+FQCN than the actual logger, so Log4j can’t find the place where your
+custom logger was called.
+
+The solution is to provide the correct FQCN. The easiest way to do this
+is to let Log4j generate the logger wrapper for you. Log4j comes with a
+Logger wrapper generator tool. This tool was originally meant to support
+custom log levels and is documented
+https://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers[here].
+
+The generated logger code will take care of the FQCN.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/15cd6ac1/src/site/markdown/faq.md.vm
----------------------------------------------------------------------
diff --git a/src/site/markdown/faq.md.vm b/src/site/markdown/faq.md.vm
deleted file mode 100644
index 132e6fe..0000000
--- a/src/site/markdown/faq.md.vm
+++ /dev/null
@@ -1,480 +0,0 @@
-<!-- vim: set syn=markdown : -->
-<!--
-    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.
--->
-#set($dollar = '$')
-#set($h1='#')
-#set($h4='####')
-
-$h1 Frequently Asked Questions
-
-* [I'm seeing this error "Unable to locate a logging implementation, using 
SimpleLogger". What is wrong?](#missing_core)
-* [Which JAR files do I need?](#which_jars)
-* [How do I exclude conflicting dependencies?](#exclusions)
-* [How do I specify the configuration file location?](#config_location)
-* [How do I configure log4j2 in code without a configuration 
file?](#config_from_code)
-* [How do I reconfigure log4j2 in code with a specific configuration 
file?](#reconfig_from_code)
-* [How do I shut down log4j2 in code?](#shutdown)
-* [How do I send log messages with different levels to different 
appenders?](#config_sep_appender_level)
-* [How do I debug my configuration?](#troubleshooting)
-* [How do I dynamically write to separate log files?](#separate_log_files)
-* [How do I set a logger's level programmatically?](#reconfig_level_from_code)
-* [How do I set my log archive retention policy? How do I delete old log 
archives?](#retention)
-* [What are the trade-offs of using the Log4j 2 API versus the SLF4J 
API?](#api-tradeoffs)
-* [Is Log4j 2 still garbage-free when I use the SLF4J API?](#gc-free-slf4j)
-* [How do I log my domain object without creating 
garbage?](#gc-free-domain-object)
-* [How do I create a custom logger wrapper that shows the correct class, 
method and line number?](#logger-wrapper)
-
-<a name="missing_core"/>
-$h4 I'm seeing this error "Unable to locate a logging implementation, using 
SimpleLogger". What is wrong?
-
-You have the log4j-api-2.x jar file in your classpath but you still need to 
add the log4j-core-2.x jar to the
-classpath. (Also, it looks like you are using an old version of Log4j 2. You 
may want to upgrade.)
-
-<a name="which_jars"/>
-$h4 Which JAR files do I need?
-
-You need at least the log4j-api-2.x and the log4j-core-2.x jar files.
-
-The other jars are necessary if your application calls the API
-of another logging framework and you want to route logging calls to the Log4j 
2 implementation.
-
-![Diagram showing which JARs correspond to which 
systems](images/whichjar-2.x.png)
-
-<a name="which_jars_log4j-to-slf4j" />
-You can use the log4j-to-slf4j adapter jar when your application calls the 
Log4j 2 API and you
-want to route logging calls to a SLF4J implementation.
-
-![Diagram showing the dependency flow to use Log4j 2 API with 
SLF4J](images/whichjar-slf4j-2.x.png)
-
-Some of the Log4j components have features with optional dependencies.
-The component page will have more detail. For example, the
-[log4j-core component page](log4j-core/index.html)
-has an outline of which log4j-core features have external dependencies.
-
-<a name="exclusions"/>
-$h4 How do I exclude conflicting dependencies?
-
-There are several scenarios where you may end up with conflicting 
dependencies, especially transitively
-included ones. The following table shows for each Log4j dependency on the left 
(implicit groupId of
-`org.apache.logging.log4j`), the following dependencies on the right can be 
safely excluded
-(given in the format `groupId:artifactId`).
-
-<table class="table table-bordered">
-  <tr>
-    <th>Log4j Dependency</th>
-    <th colspan="3">Dependencies to Exclude</th>
-  </tr>
-  <tr>
-    <td>[log4j-1.2-api](log4j-1.2-api)</td>
-    <td>log4j:log4j</td>
-    <td>org.slf4j:log4j-over-slf4j</td>
-    <td/>
-  </tr>
-  <tr>
-    <td>[log4j-core](log4j-core)</td>
-    <td>log4j:log4j</td>
-    <td>ch.qos.logback:logback-core</td>
-    <td>org.apache.logging.log4j:log4j-to-slf4j</td>
-  </tr>
-  <tr>
-    <td>[log4j-jcl](log4j-jcl)</td>
-    <td>org.slf4j:jcl-over-slf4j</td>
-    <td/>
-    <td/>
-  </tr>
-  <tr>
-    <td>[log4j-jul](log4j-jul)</td>
-    <td>org.slf4j:jul-to-slf4j</td>
-    <td/>
-    <td/>
-  </tr>
-  <tr>
-    <td>[log4j-slf4j-impl](log4j-slf4j-impl)</td>
-    <td>org.apache.logging.log4j:log4j-to-slf4j</td>
-    <td>ch.qos.logback:logback-core</td>
-    <td/>
-  </tr>
-</table>
-
-Using Apache Maven, dependencies can be globally excluded in your project like 
so:
-
-```
-<dependencies>
-  <dependency>
-    <groupId>log4j</groupId>
-    <artifactId>log4j</artifactId>
-    <version>1.2.17</version>
-    <scope>provided</scope>
-  </dependency>
-</dependencies>
-```
-
-Dependencies can be explicitly excluded for specific dependencies as well. For 
example, to use a project
-with Log4j 2 instead of Log4j 1.x:
-
-```
-<dependencies>
-  <dependency>
-    <groupId>com.example</groupId>
-    <artifactId>example-project</artifactId>
-    <version>1.0</version>
-    <exclusions>
-      <exclusion>
-        <groupId>log4j</groupId>
-        <artifactId>log4j</artifactId>
-      </exclusion>
-      <exclusion>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-log4j12</artifactId>
-      </exclusion>
-    </exclusions>
-  </dependency>
-  <dependency>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j-core</artifactId>
-    <version>${Log4jReleaseVersion}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j-slf4j-impl</artifactId>
-    <version>${Log4jReleaseVersion}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j-1.2-api</artifactId>
-    <version>${Log4jReleaseVersion}</version>
-  </dependency>
-</dependencies>
-```
-
-Dependencies can be globally excluded in Gradle like so:
-
-```
-configurations {
-  all*.exclude group: 'log4j', module: 'log4j'
-}
-```
-
-The equivalent Gradle config for the above Maven exclusion would look like:
-
-```
-dependencies {
-  compile('com.example:example-project:1.0') {
-    exclude group: 'log4j', module: 'log4j'
-    exclude group: 'org.slf4j', module: 'slf4j-log4j12'
-  }
-  compile('org.apache.logging.log4j:log4j-core:${Log4jReleaseVersion}')
-  compile('org.apache.logging.log4j:log4j-slf4j-impl:${Log4jReleaseVersion}')
-  compile('org.apache.logging.log4j:log4j-1.2-api:${Log4jReleaseVersion}')
-}
-```
-
-<a name="config_location"/>
-$h4 How do I specify the configuration file location?
-
-By default, Log4j looks for a configuration file named **log4j2.xml** (not 
log4j.xml) in the classpath.
-
-You can also specify the full path of the configuration file with this system 
property:
-`-Dlog4j.configurationFile=path/to/log4j2.xml`
-
-That property can also be included in a classpath resource file named 
`log4j2.component.properties`.
-
-Web applications can specify the Log4j configuration file location with a 
servlet context parameter.
-See [this 
section](http://logging.apache.org/log4j/2.x/manual/webapp.html#ContextParams)
-of the Using Log4j 2 in Web Applications manual page.
-
-<a name="config_from_code"/>
-$h4 How do I configure log4j2 in code without a configuration file?
-
-Starting with version 2.4, Log4j 2 provides an [API for programmatic 
configuration](manual/customconfig.html)
-The new
-[`ConfigurationBuilder` 
API](log4j-core/apidocs/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.html)
-allows you to create Configurations in code by constructing component 
definitions
-without requiring you to know about the internals of actual configuration 
objects like Loggers and Appenders.
-
-<a name="reconfig_from_code"/>
-$h4 How do I reconfigure log4j2 in code with a specific configuration file?
-
-See the below example.
-Be aware that this LoggerContext class is not part of the public API so your 
code may break with any minor release.
-
-```
-// import org.apache.logging.log4j.core.LoggerContext;
-
-LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) 
LogManager.getContext(false);
-File file = new File("path/to/a/different/log4j2.xml");
-
-// this will force a reconfiguration
-context.setConfigLocation(file.toURI());
-```
-
-<a name="shutdown"/>
-$h4 How do I shut down log4j2 in code?
-
-Normally there is no need to do this manually.
-Each `LoggerContext` registers a shutdown hook that takes care of releasing 
resources
-when the JVM exits (unless system property `log4j.shutdownHookEnabled` is set 
to `false`).
-Web applications should include the log4j-web
-module in their classpath which disables the shutdown hook but instead
-cleans up log4j resources when the web application is stopped.
-
-However, if you need to manually shut down Log4j, you can do so as in the 
below example.
-Note that there is an optional parameter for specifying which `LoggerContext` 
to
-shut down.
-
-```
-import org.apache.logging.log4j.LogManager;
-
-// ...
-
-LogManager.shutdown();
-```
-
-<a name="config_sep_appender_level"/>
-$h4 How do I send log messages with different levels to different appenders?
-You don't need to declare separate loggers to achieve this.
-You can set the logging level on the `AppenderRef` element.
-
-```
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-  <Appenders>
-    <File name="file" fileName="app.log">
-      <PatternLayout>
-        <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
-      </PatternLayout>
-    </File>
-    <Console name="STDOUT" target="SYSTEM_OUT">
-      <PatternLayout pattern="%m%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Root level="trace">
-      <AppenderRef ref="file" level="DEBUG"/>
-      <AppenderRef ref="STDOUT" level="INFO"/>
-    </Root>
-  </Loggers>
-</Configuration>
-```
-
-<a name="troubleshooting"/>
-$h4 How do I debug my configuration?
-
-First, make sure you have [the right jar files](#which_jars) on your classpath.
-You need at least log4j-api and log4j-core.
-
-Next, check the name of your configuration file. By default, log4j2 will look
-for a configuration file named `log4j2.xml` on the classpath. Note the "2" in 
the file name!
-(See the [configuration manual 
page](manual/configuration.html#AutomaticConfiguration) for more details.)
-
-**From log4j-2.9 onward**
-
-From log4j-2.9 onward, log4j2 will print all internal logging to the console 
if system property `log4j2.debug`
-is defined (with any or no value).
-
-**Prior to log4j-2.9**
-
-Prior to log4j-2.9, there are two places where internal logging can be 
controlled:
-
-If the configuration file is found correctly, log4j2 internal status logging 
can be controlled by
-setting `<Configuration status="trace">` in the configuration file. This will 
display detailed log4j2-internal
-log statements on the console about what happens during the configuration 
process.
-This may be useful to trouble-shoot configuration issues.
-By default the status logger level is WARN, so you only see notifications when 
there is a problem.
-
-If the configuration file is not found correctly, you can still enable
-log4j2 internal status logging by setting system property
-`-Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE`.
-
-<a name="separate_log_files"/>
-$h4 How do I dynamically write to separate log files?
-
-Look at the 
[RoutingAppender](http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender).
-You can define multiple routes in the configuration, and put values in the 
`ThreadContext`
-map that determine which log file subsequent events in this thread get logged 
to.
-
-You can use the `ThreadContext` map value to determine the log file name.
-
-```
-<Routing name="Routing">
-  <Routes pattern="${dollar}${dollar}{ctx:ROUTINGKEY}">
-
-    <!-- This route is chosen if ThreadContext has value 'special' for key 
ROUTINGKEY. -->
-    <Route key="special">
-      <RollingFile name="Rolling-${dollar}{ctx:ROUTINGKEY}" 
fileName="logs/special-${dollar}{ctx:ROUTINGKEY}.log"
-       
filePattern="./logs/${dollar}{date:yyyy-MM}/${dollar}{ctx:ROUTINGKEY}-special-%d{yyyy-MM-dd}-%i.log.gz">
-       <PatternLayout>
-         <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
-       </PatternLayout>
-       <Policies>
-         <TimeBasedTriggeringPolicy interval="6" modulate="true" />
-          <SizeBasedTriggeringPolicy size="10 MB" />
-       </Policies>
-      </RollingFile>
-    </Route>
-
-    <!-- This route is chosen if ThreadContext has no value for key 
ROUTINGKEY. -->
-    <Route key="$${dollar}{ctx:ROUTINGKEY}">
-      <RollingFile name="Rolling-default" fileName="logs/default.log"
-       
filePattern="./logs/${dollar}{date:yyyy-MM}/default-%d{yyyy-MM-dd}-%i.log.gz">
-        <PatternLayout>
-         <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
-        </PatternLayout>
-        <Policies>
-          <TimeBasedTriggeringPolicy interval="6" modulate="true" />
-          <SizeBasedTriggeringPolicy size="10 MB" />
-        </Policies>
-      </RollingFile>
-    </Route>
-
-    <!-- This route is chosen if ThreadContext has a value for ROUTINGKEY
-         (other than the value 'special' which had its own route above).
-         The value dynamically determines the name of the log file. -->
-    <Route>
-      <RollingFile name="Rolling-${dollar}{ctx:ROUTINGKEY}" 
fileName="logs/other-${dollar}{ctx:ROUTINGKEY}.log"
-       
filePattern="./logs/${dollar}{date:yyyy-MM}/${dollar}{ctx:ROUTINGKEY}-other-%d{yyyy-MM-dd}-%i.log.gz">
-       <PatternLayout>
-         <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
-       </PatternLayout>
-       <Policies>
-         <TimeBasedTriggeringPolicy interval="6" modulate="true" />
-         <SizeBasedTriggeringPolicy size="10 MB" />
-       </Policies>
-      </RollingFile>
-    </Route>
-  </Routes>
-</Routing>
-```
-
-<a name="reconfig_level_from_code"/>
-$h4 How do I set a logger's level programmatically?
-
-You can set a logger's level with the class
-[`Configurator`](log4j-core/apidocs/org/apache/logging/log4j/core/config/Configurator.html)
-from Log4j Core. Be aware that the `Configurator` class is not part of the 
public API.
-
-```
-// org.apache.logging.log4j.core.config.Configurator;
-
-Configurator.setLevel("com.example.Foo", Level.DEBUG);
-
-// You can also set the root logger:
-Configurator.setRootLevel(Level.DEBUG);
-```
-
-<a name="retention"/>
-$h4 How do I set my log archive retention policy? How do I delete old log 
archives?
-
-The `DefaultRolloverStrategy` of the Rolling File appender (and Rolling Random 
Access File
-appender) supports a [Delete](manual/appenders.html#CustomDeleteOnRollover) 
element.
-
-Starting at a specified base directory, you can delete all files for which 
some condition
-holds true, for example all files that match a given file name pattern and are 
older
-than some number of days. More complex conditions are possible, and if the 
built-in
-conditions are not sufficient, users can provide custom conditions by creating
-[plugin conditions](manual/appenders.html#DeletePathCondition) or by writing a
-[script condition](manual/appenders.html#ScriptCondition).
-
-<a name="api-tradeoffs" />
-$h4 What are the trade-offs of using the Log4j 2 API versus the SLF4J API?
-
-The Log4j 2 API and SLF4J have a lot in common.
-They both share the objective of cleanly separating the logging API from the 
implementation.
-We believe that the Log4j 2 API can help make your application more performant
-while offering more functionality and more flexibility.
-
-There may be a concern that using the Log4j 2 API will tightly couple your 
application to Log4j 2.
-This is not the case: applications coded to the Log4j 2 API always have the 
option to use any SLF4J-compliant
-library as their logging implementation with the log4j-to-slf4j adapter.
-See the [which jars](#which_jars_log4j-to-slf4j) FAQ entry for details.
-
-There are several advantages to using the Log4j 2 API:
-
-* SLF4J forces your application to log Strings.
-The Log4j 2 API supports logging any CharSequence if you want to log text, but 
also
-supports logging any Object as is.
-It is the responsibility of the logging <em>implementation</em> to handle this 
object,
-and we consider it a design mistake to limit applications to logging Strings.
-* The Log4j 2 API offers support for logging [Message 
objects](manual/messages.html).
-Messages allow support for interesting and complex constructs to be passed
-through the logging system and be efficiently manipulated.
-Users are free to create their own Message types and write custom Layouts,
-Filters and Lookups to manipulate them.
-* The Log4j 2 API has support for Java 8 [lambda 
expressions](manual/api.html#LambdaSupport).
-* The Log4j 2 API has better support for [garbage-free 
logging](manual/garbagefree.html):
-it avoids creating vararg arrays and avoids creating Strings when logging 
CharSequence objects.
-
-<a name="gc-free-slf4j" />
-$h4 Is Log4j 2 still garbage-free when I use the SLF4J API?
-
-Yes, the log4j-slf4j-impl binding (together with log4j-core) implements the
-`org.slf4j.Logger` methods to be GC-free.
-However, bear in mind that there are some limitations:
-
-The SLF4J API only offers up to two parameters for a parameterized message.
-More than that uses varargs which creates a temporary object for the parameter 
array.
-The Log4j 2.6 API has methods for up to ten unrolled parameters.
-
-Another consideration is that the SLF4J API forces your application to log 
Strings.
-Log4j 2 API lets you log any java.lang.CharSequence, and even any Objects.
-Log4j can log any Object that implements `java.lang.CharSequence`
-or `org.apache.logging.log4j.util.StringBuilderFormattable` without creating 
garbage.
-
-The 
[`org.slf4j.spi.LocationAwareLogger::log`](http://www.slf4j.org/api/org/slf4j/spi/LocationAwareLogger.html#log(org.slf4j.Marker,
 java.lang.String, int, java.lang.String, java.lang.Object[], 
java.lang.Throwable))
-method is not yet implemented
-in a garbage-free manner in the log4j-slf4j-impl binding. It creates a new 
message object for each call.
-
-<a name="gc-free-domain-object" />
-$h4 How do I log my domain object without creating garbage?
-
-One option is to let the domain object implement java.lang.CharSequence.
-However, for many domain objects it may not be trivial to implement this 
without allocating temporary
-objects.
-
-An alternative is to implement the 
`org.apache.logging.log4j.util.StringBuilderFormattable` interface.
-If an object is logged that implements this interface, its `formatTo` method 
is called instead of
-`toString()`.
-
-```
-package org.apache.logging.log4j.util;
-public interface StringBuilderFormattable {
-    /**
-     * Writes a text representation of this object into the specified {@code 
StringBuilder},
-     * ideally without allocating temporary objects.
-     *
-     * @param buffer the StringBuilder to write into
-     */
-     void formatTo(StringBuilder buffer);
-}
-```
-
-<a name="logger-wrapper" />
-$h4 How do I create a custom logger wrapper that shows the correct class, 
method and line number?
-
-Log4j remembers the fully qualified class name (FQCN) of the logger and uses 
this to walk the stack trace
-for every log event when configured to print location.
-(Be aware that logging with location is slow and may impact the performance of 
your application.)
-
-The problem with custom logger wrappers is that they have a different FQCN 
than the actual logger,
-so Log4j can't find the place where your custom logger was called.
-
-The solution is to provide the correct FQCN. The easiest way to do this is to 
let Log4j generate
-the logger wrapper for you. Log4j comes with a Logger wrapper generator tool.
-This tool was originally meant to support custom log levels and is documented
-[here](https://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers).
-
-The generated logger code will take care of the FQCN.

Reply via email to