| //// |
| 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. |
| //// |
| |
| = F.A.Q. |
| |
| This page compiles a list of frequently asked questions. |
| If you don't find the answer to your question, please consult to link:{logging-services-url}/support.html[the support page]. |
| |
| [#config_location] |
| == How do I specify the configuration file location? |
| |
| By default, Log4j looks for a configuration file named `log4j2.xml`, `log4j2.properties`, etc. in the classpath. |
| |
| [WARNING] |
| ==== |
| Log4j 1 (which has reached its end-of-life in 2015!) uses `log4j.xml`. |
| Log4j 2 and onwards use `log4j2.xml`. |
| ==== |
| |
| You can also specify the full path of the configuration file using a system property: + |
| `-Dxref:manual/configuration.adoc#log4j2.configurationFile[log4j2.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 xref:manual/webapp.adoc#ContextParams[the related page on web applications]. |
| |
| Refer to xref:manual/configuration.adoc[the Configuration page] for further details. |
| |
| [#config_from_code] |
| == How do I configure Log4j programmatically? |
| |
| Starting with version `2.4`, Log4j provides xref:manual/customconfig.adoc[an API for programmatic configuration]. |
| link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.html[The new `ConfigurationBuilder` API] allows you to create ``Configuration``s 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 Log4j programmatically? |
| |
| You can reconfigure Log4j programmatically using link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configurator.html[the `Configurator` API] as follows: |
| |
| [source,java] |
| ---- |
| import org.apache.logging.log4j.core.config.Configurator; |
| |
| URI configSourceUri = new File("/path/to/a/different/log4j2.xml").toURI(); |
| Configurator.reconfigure(configSourceUri); |
| ---- |
| |
| [#shutdown] |
| == How do I shut down Log4j programmatically? |
| |
| 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 the `log4j.shutdownHookEnabled` system property is set to `false`. |
| Likewise, xref:manual/webapp.adoc[Web applications] replace the shutdown hook with their own resource management mechanisms. |
| That is, they clean up necessary resources when the web application is stopped. |
| However, if you need to manually shut down Log4j, you can use one of the `shutdown()` methods of link:../javadoc/log4j-api/org/apache/logging/log4j/LogManager.html#shutdown()[`LogManager`]. |
| |
| [#reconfig_level_from_code] |
| == How do I set a logger level programmatically? |
| |
| You can set the level of a logger using link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configurator.html[`Configurator`] from Log4j Core: |
| |
| [source,java] |
| ---- |
| import org.apache.logging.log4j.core.config.Configurator; |
| |
| // Set the level of particular logger associated with a class |
| Configurator.setLevel("com.example.Foo", Level.DEBUG); |
| |
| // Set the level of the root logger |
| Configurator.setRootLevel(Level.DEBUG); |
| ---- |
| |
| [#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 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xmlns="https://logging.apache.org/xml/ns" |
| xsi:schemaLocation=" |
| https://logging.apache.org/xml/ns |
| https://logging.apache.org/xml/ns/log4j-config-2.xsd"> |
| <appenders> |
| <File name="file" fileName="app.log"> |
| <PatternLayout pattern="%d %p %c{1.} [%t] %m %ex%n"/> |
| </File> |
| <Console name="stdout" target="SYSTEM_OUT"> |
| <PatternLayout pattern="%m%n"/> |
| </Console> |
| </appenders> |
| <loggers> |
| <root level="WARN"> |
| <AppenderRef ref="file" level="DEBUG"/> |
| <AppenderRef ref="stdout" level="INFO"/> |
| </root> |
| </loggers> |
| </Configuration> |
| ---- |
| |
| [#troubleshooting] |
| == How do I debug my configuration? |
| |
| . Make sure you have xref:manual/installation.adoc[the right JAR files] on your classpath. |
| |
| . Check the name of your configuration file. |
| By default, Log4j looks for a configuration file named `log4j2.xml` on the classpath. |
| Note the `2` in the file name! |
| (See xref:manual/configuration.adoc[the Configuration page] for more details.) |
| |
| . Increase the logging verbosity of the internal status logger: + |
| `-Dxref:manual/configuration.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel]=TRACE` |
| |
| . Enable all internal debug logging: `-Dxref:manual/configuration.adoc#log4j2.debug[log4j2.debug]`. |
| This disables level-based status logger filtering and effectively allows all status logs. |
| |
| [#separate_log_files] |
| == How do I dynamically write to separate log files? |
| |
| You can use xref:manual/appenders.adoc#RoutingAppender[the routing appender] to evaluate a log message and forward it to a particular appender. |
| |
| [#api-tradeoffs] |
| == What are the trade-offs of using Log4j API versus SLF4J? |
| |
| Log4j 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 Log4j API can help make your application more performant while offering more functionality and more flexibility. |
| |
| There may be a concern that using the Log4j API will tightly couple your application to Log4j. |
| This is not the case: applications coded to Log4j API always have the option to use any SLF4J-compliant logging implementation with the `log4j-to-slf4j` bridge. |
| See xref:manual/installation.adoc[the Installation page] for details. |
| |
| There are several advantages to using Log4j API: |
| |
| * SLF4J forces your application to log ``String``s. |
| Log4j 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 ``String``s. |
| * Log4j API offers support for logging xref:manual/messages.adoc[`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. |
| * Log4j API supports xref:manual/api.adoc#LambdaSupport[lambda expressions] both in its plain and fluent API. |
| * Log4j API has better support for xref:manual/garbagefree.adoc[garbage-free logging]: it avoids creating `vararg` arrays and avoids creating ``String``s when logging ``CharSequence``s. |
| |
| [#gc-free-slf4j] |
| == Is Log4j still garbage-free when I use SLF4J? |
| |
| If you use SLF4J as your logging API and Log4j Core as the logging implementation, yes. |
| The `log4j-slf4j-impl` and `log4j-slf4j2-impl` bridges (together with `log4j-core`) implement the `org.slf4j.Logger` methods to be garbage-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 ``vararg``s, which create a temporary object for the parameter array. |
| In contrast, Log4j API has methods for up to ten unrolled parameters. |
| |
| * SLF4J forces your application to log ``String``s. |
| Log4j API lets you log any `CharSequence` or `Object`. |
| Log4j Core can log any `Object` that implements `CharSequence` or `org.apache.logging.log4j.util.StringBuilderFormattable` without creating garbage. |
| |
| * The https://www.slf4j.org/api/org/slf4j/spi/LocationAwareLogger.html#log(org.slf4j.Marker,java.lang.String,int,java.lang.String,java.lang.Object%5B%5D,java.lang.Throwable)[`org.slf4j.spi.LocationAwareLogger::log`] method is not yet implemented in a garbage-free manner in the `log4j-slf4j-impl` and `log4j-slf4j2-impl` bridges. |
| 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 `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(StringBuilder)` method is called instead of `toString()`. |
| |
| [#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. |
| |
| [WARNING] |
| ==== |
| 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 xref:manual/customloglevels.adoc#CustomLoggers[here]. |
| The generated logger code will take care of the FQCN. |
| |
| [#proguard-rules] |
| == Which rules do I need to add when ProGuard minification is enabled? |
| |
| When you are using Log4j with ProGuard/R8 enabled, you need to add the following rules to your configuration file: |
| |
| [source] |
| ---- |
| -keep,allowoptimization class org.apache.logging.log4j.** { *; } |
| ---- |