Configuration
Inserting log requests into the application code requires a fair amount of planning and effort. Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even moderately sized applications will have thousands of logging statements embedded within their code. Given their number, it becomes imperative to manage these log statements without the need to modify them manually.(在應用程序代碼中插入日志需要大量的計划和努力。觀察表明,約百分之4的代碼專門用於日志管理。因此,即使是中等大小的應用程序也會有成千上萬的日志語句嵌入到它們的代碼中。考慮到它們的數量,就必須對這些日志語句進行管理,而不需要手工修改代碼。)
Configuration of Log4j 2 can be accomplished in 1 of 4 ways:(配置Log4j 2可以使用下面4個方法中的一個來完成:)
- Through a configuration file written in XML, JSON, YAML, or properties format.(通過一個XML, JSON, YAML, 或properties 格式的配置文件)
- Programmatically, by creating a ConfigurationFactory and Configuration implementation.(以編程方式)
- Programmatically, by calling the APIs exposed in the Configuration interface to add components to the default configuration.(以編程方式)
- Programmatically, by calling methods on the internal Logger class.(以編程方式)
This page focuses primarily on configuring Log4j through a configuration file. Information on programmatically configuring Log4j can be found at Extending Log4j 2 and Programmatic Log4j Configuration.(這個章節的焦點是通過配置文件來配置Log4j。通過編程方式來配置Log4j的相關信息可以在Extending Log4j 2 和Programmatic Log4j Configuration 中找到。)
Note that unlike Log4j 1.x, the public Log4j 2 API does not expose methods to add, modify or remove appenders and filters or manipulate the configuration in any way.(請注意,與log4j 1.x不同,log4j 2 的Public API沒有公開用來添加、修改或刪除appender和filters或以任何方式操縱配置的方法)
Automatic Configuration(自動配置)
Log4j has the ability to automatically configure itself during initialization. When Log4j starts it will locate all the ConfigurationFactory plugins and arrange them in weighted order from highest to lowest. As delivered, Log4j contains four ConfigurationFactory implementations: one for JSON, one for YAML, one for properties, and one for XML.(log4j具有在初始化過程中自動配置自身的能力。當log4j啟動就會找到所有的configurationfactory插件和安排他們在從最高到最低的加權進行排序。log4j包含四種ConfigurationFactory 實現:一個JSON,一個YAML,一個properties,和一個XML。)
- Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt to load the configuration using the ConfigurationFactory that matches the file extension.(log4j將檢查 "log4j.configurationFile" 系統屬性,如果設置了這個屬性,將嘗試使用匹配這個文件擴展名的 ConfigurationFactory 加載配置。)
- If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.(如果"log4j.configurationFile"系統屬性沒有被設置,properties ConfigurationFactory 就會去查找classpath 中的 log4j2-test.properties )
- If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.(如果上面的文件都沒有找到,YAML ConfigurationFactory 就會去查找classpath 中的log4j2-test.yaml 或log4j2-test.yml )
- If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.(如果上面的文件都沒有找到,JSON ConfigurationFactory 就會去查找classpath 中的 log4j2-test.json or log4j2-test.jsn)
- If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.(如果上面的文件都沒有找到,XML ConfigurationFactory 就會去查找classpath 中的log4j2-test.xml)
- If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.(如果找不到測試文件,properties ConfigurationFactory 就會去查找classpath 中的 log4j2.properties )
- If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the classpath.(如果找不到 properties 文件,YAML ConfigurationFactory 就會去查找classpath 中的 log4j2.yaml or log4j2.yml )
- If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.(如果找不到 YAML 文件, JSON ConfigurationFactory 就會去查找classpath 中的 log4j2.json or log4j2.jsn )
- If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.(如果找不到 JSON 文件, XML ConfigurationFactory 就會去查找classpath 中的 log4j2.xml )
- If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.(如果找不到任何配置文件, 就會使用 DefaultConfiguration 。它會將日志輸出在控制台中 )
An example application named MyApp that uses log4j can be used to illustrate how this is done.(一個使用log4j 的例子,可以用來說明Log4j的自動配置是如何完成的。)
1 import com.foo.Bar; 2 3 // Import log4j classes. 4 import org.apache.logging.log4j.Logger; 5 import org.apache.logging.log4j.LogManager; 6 7 public class MyApp { 8 9 // Define a static logger variable so that it references the 10 // Logger instance named "MyApp". 11 private static final Logger logger = LogManager.getLogger(MyApp.class); 12 13 public static void main(final String... args) { 14 15 // Set up a simple configuration that logs on the console. 16 17 logger.trace("Entering application."); 18 Bar bar = new Bar(); 19 if (!bar.doIt()) { 20 logger.error("Didn't do it."); 21 } 22 logger.trace("Exiting application."); 23 } 24 }
MyApp begins by importing log4j related classes. It then defines a static logger variable with the name MyApp which happens to be the fully qualified name of the class.(MyApp通過導入log4j相關的類開始。然后使用了MyApp的全限定類名定義了一個靜態的日志記錄器。)
MyApp uses the Bar class defined in the packagecom.foo.
package com.foo; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; public class Bar { static final Logger logger = LogManager.getLogger(Bar.class.getName()); public boolean doIt() { logger.entry(); logger.error("Did it again!"); return logger.exit(false); } }
Log4j will provide a default configuration if it cannot locate a configuration file. The default configuration, provided in the DefaultConfiguration class, will set up:(Log4j在找不到配置文件的時候,提供了一個默認的配置。默認配置由DefaultConfiguration 類提供,會建立:)
- A ConsoleAppender attached to the root logger.(為root logger添加一個ConsoleAppender )
- A PatternLayout set to the pattern "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" attached to the ConsoleAppender(為ConsoleAppender 添加一個模式為"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" 的PatternLayout )
Note that by default Log4j assigns the root logger to Level.ERROR.(注意root logger 的默認級別為 Level.ERROR)
The output of MyApp would be similar to:
17:13:01.540 [main] ERROR com.foo.Bar - Did it again! 17:13:01.540 [main] ERROR MyApp - Didn't do it.
As was described previously, Log4j will first attempt to configure itself from configuration files. A configuration equivalent to the default would look like:(正如上面描述的那樣,Log4j首先會嘗試從配置文件中讀取配置。和默認配置等價的配置文件如下:)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="WARN"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> 6 </Console> 7 </Appenders> 8 <Loggers> 9 <Root level="error"> 10 <AppenderRef ref="Console"/> 11 </Root> 12 </Loggers> 13 </Configuration>
Once the file above is placed into the classpath as log4j2.xml you will get results identical to those listed above. Changing the root level to trace will result in results similar to:(一旦上面的文件被命名為log4j2.xml並放在classpath 下,你就會得到和上面的輸出結果等價的結果。將 root level 修改為trace會得到類似如下的結果:)
17:13:01.540 [main] TRACE MyApp - Entering application. 17:13:01.540 [main] TRACE com.foo.Bar - entry 17:13:01.540 [main] ERROR com.foo.Bar - Did it again! 17:13:01.540 [main] TRACE com.foo.Bar - exit with (false) 17:13:01.540 [main] ERROR MyApp - Didn't do it. 17:13:01.540 [main] TRACE MyApp - Exiting application.
Note that status logging is disabled when the default configuration is used.(如果提供了默認的level 則 Configuration 節點中的status 無效)
Additivity(附加性)
Perhaps it is desired to eliminate all the TRACE output from everything except com.foo.Bar. Simply changing the log level would not accomplish the task. Instead, the solution is to add a new logger definition to the configuration:(也許你想讓所有的Trace級別的日志都不輸出,除了com.foo.bar。僅僅更改日志級別將無法達到你的目的。相反,解決方法是添加一個新的日志記錄器定義:)
1 <Logger name="com.foo.Bar" level="TRACE"/> 2 <Root level="ERROR"> 3 <AppenderRef ref="STDOUT"> 4 </Root>
With this configuration all log events from com.foo.Bar will be recorded while only error events will be recorded from all other components. (使用這個配置,所有的來自於com.foo.Bar 包下的日志事件都會被記錄,然而其它包下的只有error級別的日志事件會被記錄。)
In the previous example all the events from com.foo.Bar were still written to the Console. This is because the logger for com.foo.Bar did not have any appenders configured while its parent did. In fact, the following configuration(在先前的例子中,所有的來自於 com.foo.Bar 包下的事件仍然會寫入到Console 。這是因為 com.foo.Bar 的日志記錄器沒有配置任何的appenders 然而它的父元素Root 卻配置了。實際上,它的配置如下: )
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="WARN"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> 6 </Console> 7 </Appenders> 8 <Loggers> 9 <Logger name="com.foo.Bar" level="trace"> 10 <AppenderRef ref="Console"/> 11 </Logger> 12 <Root level="error"> 13 <AppenderRef ref="Console"/> 14 </Root> 15 </Loggers> 16 </Configuration>
would result in
17:13:01.540 [main] TRACE com.foo.Bar - entry 17:13:01.540 [main] TRACE com.foo.Bar - entry 17:13:01.540 [main] ERROR com.foo.Bar - Did it again! 17:13:01.540 [main] TRACE com.foo.Bar - exit (false) 17:13:01.540 [main] TRACE com.foo.Bar - exit (false) 17:13:01.540 [main] ERROR MyApp - Didn't do it.
Notice that the trace messages from com.foo.Bar appear twice. This is because the appender associated with logger com.foo.Bar is first used, which writes the first instance to the Console. Next, the parent of com.foo.Bar, which in this case is the root logger, is referenced. The event is then passed to its appender, which is also writes to the Console, resulting in the second instance. This is known as additivity. While additivity can be quite a convenient feature (as in the first previous example where no appender reference needed to be configured), in many cases this behavior is considered undesirable and so it is possible to disable it by setting the additivity attribute on the logger to false:(注意,來自於 com.foo.Bar 包下的日志出現了兩次。這是因為和com.foo.Bar 日志記錄器相關的appender 被第一次使用時,它會將第一個實例寫到控制台。接下來又被com.foo.Bar 的父級--root logger 引用。然后當事件被傳遞給root logger的appender時,它也會將信息寫入到控制台,這就導致了兩次輸出。這就是所謂的附加性。然而additivity 可以是一個相當方便的功能(正如在先前的第一個例子中,他不需要配置 AppenderRef 而是直接使用root logger 的AppenderRef ),在許多情況下,這種行為被視為不受歡迎的,並且很可能通過設置additivity 屬性值為false將它禁用 。)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="WARN"> 3 <Appenders> 4 <Console name="Console" target="SYSTEM_OUT"> 5 <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> 6 </Console> 7 </Appenders> 8 <Loggers> 9 <Logger name="com.foo.Bar" level="trace" additivity="false"> 10 <AppenderRef ref="Console"/> 11 </Logger> 12 <Root level="error"> 13 <AppenderRef ref="Console"/> 14 </Root> 15 </Loggers> 16 </Configuration>
Once an event reaches a logger with its additivity set to false the event will not be passed to any of its parent loggers, regardless of their additivity setting.(一旦一個事件傳遞到一個additivity屬性值為false的logger ,這個事件就不會再被傳遞到它的父loggers )
Automatic Reconfiguration(自動重新配置)
When configured from a File, Log4j has the ability to automatically detect changes to the configuration file and reconfigure itself. If the monitorInterval attribute is specified on the configuration element and is set to a non-zero value then the file will be checked the next time a log event is evaluated and/or logged and the monitorInterval has elapsed since the last check. The example below shows how to configure the attribute so that the configuration file will be checked for changes only after at least 30 seconds have elapsed. The minimum interval is 5 seconds.(當從配置文件中讀取配置時,log4j具有自動檢測配置文件變化和重新配置自身的能力。如果在配置元素上指定 monitorInterval 屬性並且它的值為非0,則日志文件會在下一次的日志事件評估/日志記錄並且經過monitorinterval設置的時間后被重新檢查。下面的示例演示如何配置屬性,以便在至少30秒之后檢查配置文件的更改。最小間隔為5秒。)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration monitorInterval="30"> 3 ... 4 </Configuration>
Chainsaw can automatically process your log files (Advertising appender configurations)(Chainsaw能夠自動處理你的日志文件(通知 appender 配置))
Log4j provides the ability to 'advertise' appender configuration details for all file-based appenders as well as socket-based appenders. For example, for file-based appenders, the file location and the pattern layout in the file are included in the advertisement. Chainsaw and other external systems can discover these advertisements and use that information to intelligently process the log file.(log4j提供了為所有基於文件以及基於Socket的appenders ‘宣傳’ appender的配置細節的能力 。例如,基於文件的appender,它們的文件位置和pattern layout都被包含在”廣告“中。Chainsaw 和其他外部系統可以發現這些”廣告“並使用這些信息智能化地處理日志文件)
The mechanism by which an advertisement is exposed, as well as the advertisement format, is specific to each Advertiser implementation. An external system which would like to work with a specific Advertiser implementation must understand how to locate the advertised configuration as well as the format of the advertisement. For example, a 'database' Advertiser may store configuration details in a database table. An external system can read that database table in order to discover the file location and the file format.(針對每個廣告商實現 都有其廣告暴露的機制,以及這個廣告的格式。要與特定的廣告商實現一起工作的外部系統必須了解如何定位廣告配置以及廣告格式。例如,“數據庫”廣告商可以將配置細節存儲在數據庫表中。外部系統可以讀取數據庫表以發現文件位置和文件格式。)
Log4j provides one Advertiser implementation, a 'multicastdns' Advertiser, which advertises appender configuration details via IP multicast using the http://jmdns.sourceforge.net library.(Log4j提供了一個廣告商實現---'multicastdns' Advertiser 它會通過使用 http://jmdns.sourceforge.net 庫的IP廣播對appender的配置細節進行廣告)
Chainsaw automatically discovers log4j's multicastdns-generated advertisements and displays those discovered advertisements in Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's classpath). To begin parsing and tailing a log file provided in an advertisement, just double-click the advertised entry in Chainsaw's Zeroconf tab. Currently, Chainsaw only supports FileAppender advertisements.(Chainsaw 自動發現Log4j的multicastdns生成的廣告並且會在 Chainsaw's Zeroconf tab 展示那些被發現的廣告(如果jmdnslibrary 在Chainsaw的 classpath)。開始解析並且跟蹤在廣告中提供的日志文件,只要在Chainsaw的Zeroconf tab 中雙擊廣告記錄。目前,Chainsaw 只支持FileAppender廣告。)
To advertise an appender configuration:(為了廣告一個appender 的配置:)
- Add the JmDns library from http://jmdns.sourceforge.net to the application classpath(從 http://jmdns.sourceforge.net 將JmDns庫添加到應用程序的classpath中)
- Set the 'advertiser' attribute of the configuration element to 'multicastdns'(設置configuration 元素的‘advertiser ’屬性值為 'multicastdns')
- Set the 'advertise' attribute on the appender element to 'true'(設置appender 元素的‘advertiser ’屬性值為 'true')
- If advertising a FileAppender-based configuration, set the 'advertiseURI' attribute on the appender element to an appropriate URI(如果廣告一個基於FileAppender 的配置,設置 appender 元素的‘advertiseURI’屬性值為 一個合適的URI )
FileAppender-based configurations require an additional 'advertiseURI' attribute to be specified on the appender. The 'advertiseURI' attribute provides Chainsaw with information on how the file can be accessed. For example, the file may be remotely accessible to Chainsaw via ssh/sftp by specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/) sftp:// URI, an http:// URI may be used if the file is accessible through a web server, or a file:// URI can be specified if accessing the file from a locally-running instance of Chainsaw.(基於FileAppender 的配置需要指定一個額外的 'advertiseURI' 。'advertiseURI' 將如何去訪問文件的信息提供給Chainsaw。例如,文件可能要Chainsaw 通過 ssh/sftp 進行遠程訪問,通過指定一個通用的VFS (http://commons.apache.org/proper/commons-vfs/) sftp:// URI ,如果文件可以通過web 服務器訪問可以使用 http:// URI,如果可以通過本地允許的Chainsaw 實例來訪問文件則可以使用file:// URI )
Here is an example advertisement-enabled appender configuration which can be used by a locally-running Chainsaw to automatically tail the log file (notice the file:// advertiseURI):(這是一個激活了廣告的appender配置,它可以使用本地允許的Chainsaw 來自動跟蹤日志文件 (注意使用 file:// advertiseURI))
Please note, you must add the JmDns library from http://jmdns.sourceforge.net to your application classpath in order to advertise with the 'multicastdns' advertiser.(請注意,你一定要從http://jmdns.sourceforge.net 將JmDns 庫添加到你的應用程序中的classpath ,這樣才能夠成功使用 'multicastdns' 進行廣告。 )
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration advertiser="multicastdns"> 3 ... 4 </Configuration> 5 <Appenders> 6 <File name="File1" fileName="output.log" bufferedIO="false" advertiseURI="file://path/to/output.log" advertise="true"> 7 ... 8 </File> 9 </Appenders>
Configuration Syntax(配置語法)
As the previous examples have shown as well as those to follow, Log4j allows you to easily redefine logging behavior without needing to modify your application. It is possible to disable logging for certain parts of the application, log only when specific criteria are met such as the action being performed for a specific user, route output to Flume or a log reporting system, etc. Being able to do this requires understanding the syntax of the configuration files.(如前面的例子所顯示的那樣,Log4j允許您輕松地重新定義記錄行為,而不需要修改應用程代碼。可以禁用應用程序的某些部分的日志,日志只有當特定條件滿足才會將日志信息輸出到Flume 或日志報告系統等。要能夠做到這一點需要去了解配置文件的語法。)
The configuration element in the XML file accepts several attributes:(在XML文件中的配置元素接受的幾個屬性:)
Attribute Name | Description |
---|---|
advertiser | (Optional) The Advertiser plugin name which will be used to advertise individual FileAppender or SocketAppender configurations. The only Advertiser plugin provided is 'multicastdns".((可選的)廣告商插件名,他會被用來廣告 FileAppender 或 SocketAppender 的配置信息。現在只支持 'multicastdns"廣告商插件 ) |
dest | Either "err", which will send output to stderr, or a file path or URL.(值為”err",a file path,URL 3者之一。如果為“err”,信息會被輸出到stderr) |
monitorInterval | The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.(下一次檢查配置文件需要間隔的秒數) |
name | The name of the configuration.(配置的名稱) |
packages | A comma separated list of package names to search for plugins. Plugins are only loaded once per classloader so changing this value may not have any effect upon reconfiguration.(查找插件的包名,多個包名用逗號分隔。每個類加載器只會加載一次插件,所有改變它的值在reconfiguration 時不會有任何的效果) |
schema | Identifies the location for the classloader to located the XML Schema to use to validate the configuration. Only valid when strict is set to true. If not set no schema validation will take place.(類加載器加載用來校驗配置文件的XML Schema文件的位置。只有當strict屬性設置為true時才會校驗。如果沒有設置,那么schema就不會起作用。) |
shutdownHook | Specifies whether or not Log4j should automatically shutdown when the JVM shuts down. The shutdown hook is enabled by default but may be disabled by setting this attribute to "disable"(指定當JVM關閉的時候是否允許Log4j自動關閉。默認的值為enable但是可以將值設置為“disable"來關閉該功能。) |
shutdownTimeout | Specifies how many milliseconds appenders and background tasks will get to shutdown when the JVM shuts down. Default is zero which mean that each appender uses its default timeout, and don't wait for background tasks. Not all appenders will honor this, it is a hint and not an absolute guarantee that the shutdown procedure will not take longer. Setting this too low increase the risk of losing outstanding log events not yet written to the final destination. See LoggerContext.stop(long, java.util.concurrent.TimeUnit). (Not used if shutdownHook is set to "disable".)(指定當JVM關閉的時候再過多少毫秒會關閉appenders和后台任務。默認值為0,意味着每個appender使用它們默認的超市,並且不會等待后台任務。並不是對所有的appenders都有效,它只是一個微量的並且不會絕對的保證關閉處理不會花更長的時間。參考 LoggerContext.stop(long, java.util.concurrent.TimeUnit) (如果shutdownHook 設置為”disable“不要使用該屬性。)) |
status | The level of internal Log4j events that should be logged to the console. Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal". Log4j will log details about initialization, rollover and other internal actions to the status logger. Setting status="trace" is one of the first tools available to you if you need to troubleshoot log4j.(Log4j日志事件的等級打印在控制台。校驗已下的這些值 "trace", "debug", "info", "warn", "error" and "fatal" 。Log4j會將初始化時的詳細信息 ,rollover和其它內部操作都記錄到status日志記錄器中。設置 status="trace" 這是對你來說可以用來排除log4j故障的第一個工具。) |
strict | Enables the use of the strict XML format. Not supported in JSON configurations.(激活嚴格XML格式的使用。在JSON配置中不支持) |
verbose | Enables diagnostic information while loading plugins.(在加載插件的時候激活診斷性測試信息) |
Log4j can be configured using two XML flavors; concise and strict. The concise format makes configuration very easy as the element names match the components they represent however it cannot be validated with an XML schema. For example, the ConsoleAppender is configured by declaring an XML element named Console under its parent appenders element. However, element and attribute names are are not case sensitive. In addition, attributes can either be specified as an XML attribute or as an XML element that has no attributes and has a text value. So(Log4j能夠使用XML風格進行配置;簡潔的或者是嚴格的。簡潔的格式使得配置非常容易,因為元素名匹配了他們表示的組件,即使它在XML schema中校驗不通過。例如,可以在父appenders下申明一個叫做Console的XML元素來配置一個 ConsoleAppender 。但是元素和屬性名是不區分大小寫的。此外,屬性也可以指定為一個沒有屬性只有一個文本值得XML元素。)
<PatternLayout pattern="%m%n"/>
and
<PatternLayout> <Pattern>%m%n</Pattern> </PatternLayout>
are equivalent.
The file below represents the structure of an XML configuration, but note that the elements in italics below represent the concise element names that would appear in their place.(下面的文件呈現的是一個XML配置的結構,但是注意下面的斜體內容表示是簡潔方式配置的。)
1 <?xml version="1.0" encoding="UTF-8"?>; 2 <Configuration> 3 <Properties> 4 <Property name="name1">value</property> 5 <Property name="name2" value="value2"/> 6 </Properties> 7 <filter ... /> 8 <Appenders> 9 <appender ... > 10 <filter ... /> 11 </appender> 12 ... 13 </Appenders> 14 <Loggers> 15 <Logger name="name1"> 16 <filter ... /> 17 </Logger> 18 ... 19 <Root level="level"> 20 <AppenderRef ref="name"/> 21 </Root> 22 </Loggers> 23 </Configuration>
See the many examples on this page for sample appender, filter and logger declarations.(查看該頁面的更多其它的例子來比較sample appender, filter and logger declarations)
Strict XML(嚴格模式)
In addition to the concise XML format above, Log4j allows configurations to be specified in a more "normal" XML manner that can be validated using an XML Schema. This is accomplished by replacing the friendly element names above with their object type as shown below. For example, instead of the ConsoleAppender being configuerd using an element named Console it is instead configured as an appender element with a type attribute containing "Console".(此外)
1 <?xml version="1.0" encoding="UTF-8"?>; 2 <Configuration> 3 <Properties> 4 <Property name="name1">value</property> 5 <Property name="name2" value="value2"/> 6 </Properties> 7 <Filter type="type" ... /> 8 <Appenders> 9 <Appender type="type" name="name"> 10 <Filter type="type" ... /> 11 </Appender> 12 ... 13 </Appenders> 14 <Loggers> 15 <Logger name="name1"> 16 <Filter type="type" ... /> 17 </Logger> 18 ... 19 <Root level="level"> 20 <AppenderRef ref="name"/> 21 </Root> 22 </Loggers> 23 </Configuration>
Below is a sample configuration using the strict format.(使用嚴格模式的一個例子)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="debug" strict="true" name="XMLConfigTest" 3 packages="org.apache.logging.log4j.test"> 4 <Properties> 5 <Property name="filename">target/test.log</Property> 6 </Properties> 7 <Filter type="ThresholdFilter" level="trace"/> 8 9 <Appenders> 10 <Appender type="Console" name="STDOUT"> 11 <Layout type="PatternLayout" pattern="%m MDC%X%n"/> 12 <Filters> 13 <Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/> 14 <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/> 15 </Filters> 16 </Appender> 17 <Appender type="Console" name="FLOW"> 18 <Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number --> 19 <Filters> 20 <Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/> 21 <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/> 22 </Filters> 23 </Appender> 24 <Appender type="File" name="File" fileName="${filename}"> 25 <Layout type="PatternLayout"> 26 <Pattern>%d %p %C{1.} [%t] %m%n</Pattern> 27 </Layout> 28 </Appender> 29 <Appender type="List" name="List"> 30 </Appender> 31 </Appenders> 32 33 <Loggers> 34 <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false"> 35 <Filter type="ThreadContextMapFilter"> 36 <KeyValuePair key="test" value="123"/> 37 </Filter> 38 <AppenderRef ref="STDOUT"/> 39 </Logger> 40 41 <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false"> 42 <AppenderRef ref="File"/> 43 </Logger> 44 45 <Root level="trace"> 46 <AppenderRef ref="List"/> 47 </Root> 48 </Loggers> 49 50 </Configuration>
Configuration with JSON(沒有翻譯,詳見官網)
Configuration with YAML(沒有翻譯,詳見官網)
Configuring loggers
An understanding of how loggers work in Log4j is critical before trying to configure them. Please reference the Log4j architecture if more information is required. Trying to configure Log4j without understanding those concepts will lead to frustration.(在嘗試配置日志記錄器 前, 理解它們是如何工作的是非常重要的。如果需要更多的信息請參考Log4j architecture 。在沒有理解這些概念前嘗試配置Log4j將會導致失敗。)
A LoggerConfig is configured using the logger element. The logger element must have a name attribute specified, will usually have a level attribute specified and may also have an additivity attribute specified. The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF. If no level is specified it will default to ERROR. The additivity attribute may be assigned a value of true or false. If the attribute is omitted the default value of false will be used.(使用logger 元素來配置日志記錄器。 logger 元素一定要指定一個name屬性,通常還會指定level和additivity屬性。level屬性值可以為 TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF之一。如果沒有指定level屬性,則默認的為error。additivity屬性值可以為true或false,它的默認值為false。)
A LoggerConfig (including the root LoggerConfig) can be configured with properties that will be added to the properties copied from the ThreadContextMap. These properties can be referenced from Appenders, Filters, Layouts, etc just as if they were part of the ThreadContext Map. The properties can contain variables that will be resolved either when the configuration is parsed or dynamically when each event is logged. See Property Substitution for more information on using variables.(LoggerConfig(包括root LogerConfig)都可以使用從ThreadContextMap 拷貝過來的屬性進行配置。這些屬性可以被 Appenders, Filters, Layouts 等引用,就好像它們是ThreadContext Map 的一部分。這些屬性中可以包含變量,它們會在分析配置文件的時候被解析或者當日志被記錄的時候動態解析。如何使用變量,查看 Property Substitution)
The LoggerConfig may also be configured with one or more AppenderRef elements. Each appender referenced will become associated with the specified LoggerConfig. If multiple appenders are configured on the LoggerConfig each of them be called when processing logging events.(LoggerConfig也可以使用一個或多個AppenderRef引用元素進行配置。如果在一個LoggerConfig中配置多個appenders,當處理日志事件的時候,每個appender都會被調用)
Every configuration must have a root logger. If one is not configured the default root LoggerConfig, which has a level of ERROR and has a Console appender attached, will be used. The main differences between the root logger and other loggers are(每一個配置都必須有一個root logger。如果沒有配置,一個默認的root LoggerConfig就會被使用,它的級別為ERROR並且有一個Console的appender。root logger和其它的logger的主要區別為:)
- The root logger does not have a name attribute.(root logger沒有name屬性)
- The root logger does not support the additivity attribute since it has no parent.(root logger不會支持additivity屬性,因為它沒有父元素)
Configuring Appenders(配置Appender元素)
An appender is configured either using the specific appender plugin's name or with an appender element and the type attibute containing the appender plugin's name. In addition each appender must have a name attribute specified with a value that is unique within the set of appenders. The name will be used by loggers to reference the appender as described in the previous section.(appender要么是通過使用一個指定的appender插件的名稱進行配置,要么是通過一個appender元素並且type屬性的值為appender插件的名稱進行配置。此外每一個appender一定要指定一個在appenders集合中獨一無二的name屬性。這個name屬性會被logger的AppenderRef引用)
Most appenders also support a layout to be configured which again may be specified either using the specific Layout plugin's name as the element or with "layout" as the element name along with a type attribute that contains the layout plugin's name. The various appenders will contain other attributes or elements that are required for them to function properly.(大多數的appenders也支持配置layout,layout可以通過指定Layout插件的名稱進行配置,也可以通過使用“layout”作為元素名並為其指定type屬性(type屬性的值為layout插件的名稱)。各種各樣的appender將包含其他屬性或是他們的正常功能所需的元素 )
Configuring Filters(配置過濾器元素)
Log4j allows a filter to be specified in any of 4 places:(Log4j允許在4個位置配置過濾器元素)
- At the same level as the appenders, loggers and properties elements. These filters can accept or reject events before they have been passed to a LoggerConfig.(和appenders,loggers,properties元素在同一個級別。這些過濾器在日志事件傳遞給LoggerConfig之前對日志事件進行接受或者是拒絕)
- In a logger element. These filters can accept or reject events for specific loggers.(在一個logger元素中。為指定的logger接受和拒絕日志事件)
- In an appender element. These filters can prevent or cause events to be processed by the appender.(在一個appender中。阻止或者導致日志事件被appender處理)
- In an appender reference element. These filters are used to determine if a Logger should route the event to an appender.(在一個AppenderRef元素中。用來判斷一個日志記錄器是有應該將日志事件傳遞到appender中)
Although only a single filter element can be configured, that element may be the filters element which represents the CompositeFilter. The filters element allows any number of filter elements to be configured within it. The following example shows how multiple filters can be configured on the ConsoleAppender.(即使只有一個過濾器可以配置,這個元素可能是filters 元素,它表示過濾元素的復合。可以在filters 元素中配置任意個 filter 元素。下面的例子顯示在ConsoleAppender中配置多個filter )
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test"> 3 <Properties> 4 <Property name="filename">target/test.log</Property> 5 </Properties> 6 <ThresholdFilter level="trace"/> 7 8 <Appenders> 9 <Console name="STDOUT"> 10 <PatternLayout pattern="%m MDC%X%n"/> 11 </Console> 12 <Console name="FLOW"> 13 <!-- this pattern outputs class name and line number --> 14 <PatternLayout pattern="%C{1}.%M %m %ex%n"/> 15 <filters> 16 <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/> 17 <MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/> 18 </filters> 19 </Console> 20 <File name="File" fileName="${filename}"> 21 <PatternLayout> 22 <pattern>%d %p %C{1.} [%t] %m%n</pattern> 23 </PatternLayout> 24 </File> 25 <List name="List"> 26 </List> 27 </Appenders> 28 29 <Loggers> 30 <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false"> 31 <ThreadContextMapFilter> 32 <KeyValuePair key="test" value="123"/> 33 </ThreadContextMapFilter> 34 <AppenderRef ref="STDOUT"/> 35 </Logger> 36 37 <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false"> 38 <Property name="user">${sys:user.name}</Property> 39 <AppenderRef ref="File"> 40 <ThreadContextMapFilter> 41 <KeyValuePair key="test" value="123"/> 42 </ThreadContextMapFilter> 43 </AppenderRef> 44 <AppenderRef ref="STDOUT" level="error"/> 45 </Logger> 46 47 <Root level="trace"> 48 <AppenderRef ref="List"/> 49 </Root> 50 </Loggers> 51 52 </Configuration>
Configuration with Properties(未翻譯,詳見官網)
Property Substitution(屬性替換)
Log4j 2 supports the ability to specify tokens in the configuration as references to properties defined elsewhere. Some of these properties will be resolved when the configuration file is interpreted while others may be passed to components where they will be evaluated at runtime. To accomplish this, Log4j uses variations of Apache Commons Lang's StrSubstitutor and StrLookup classes. In a manner similar to Ant or Maven, this allows variables declared as ${name} to be resolved using properties declared in the configuration itself. For example, the following example shows the filename for the rolling file appender being declared as a property.(Log4j 2支持指定token,這些token可以被其它地方的屬性進行引用。當配置文件被解釋時,一些屬性將被解決,而另一些屬性將傳遞給組件,這些組件將在運行時對它們進行評估。為了實現這一目標,log4j的使用 Apache Commons Lang's StrSubstitutor 和StrLookup類的變量。在某種程度上類似於Ant或Maven,這允許變量聲明為 ${name} ,它們會被解析成該配置文件中的name屬性定義的值。例如,下面的示例顯示rolling file appender的文件名被作為一個屬性聲明。 )
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="debug" name="RoutingTest" packages="org.apache.logging.log4j.test"> 3 <Properties> 4 <Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property> 5 </Properties> 6 <ThresholdFilter level="debug"/> 7 8 <Appenders> 9 <Console name="STDOUT"> 10 <PatternLayout pattern="%m%n"/> 11 </Console> 12 <List name="List"> 13 <ThresholdFilter level="debug"/> 14 </List> 15 <Routing name="Routing"> 16 <Routes pattern="$${sd:type}"> 17 <Route> 18 <RollingFile name="Rolling-${sd:type}" fileName="${filename}" 19 filePattern="target/rolling1/test1-${sd:type}.%i.log.gz"> 20 <PatternLayout> 21 <pattern>%d %p %c{1.} [%t] %m%n</pattern> 22 </PatternLayout> 23 <SizeBasedTriggeringPolicy size="500" /> 24 </RollingFile> 25 </Route> 26 <Route ref="STDOUT" key="Audit"/> 27 <Route ref="List" key="Service"/> 28 </Routes> 29 </Routing> 30 </Appenders> 31 32 <Loggers> 33 <Logger name="EventLogger" level="info" additivity="false"> 34 <AppenderRef ref="Routing"/> 35 </Logger> 36 37 <Root level="error"> 38 <AppenderRef ref="STDOUT"/> 39 </Root> 40 </Loggers> 41 42 </Configuration>
While this is useful, there are many more places properties can originate from. To accommodate this, Log4j also supports the syntax ${prefix:name} where the prefix identifies tells Log4j that variable name should be evaluated in a specific context. See the Lookups manual page for more details. The contexts that are built in to Logj4 are:(這是很有用的,但是引用的屬性會來自於很多的地方。為了適應這種情況,log4j也支持語法 ${prefix:name} 在前綴標識告訴log4j,變量的名字應該在一個特定的上下文進行評估。看到Lookups 手冊頁來了解更多細節。建立在logj4的上下文包括:)
Prefix | Context |
---|---|
bundle | Resource bundle. The format is ${bundle:BundleName:BundleKey}. The bundle name follows package naming conventions, for example: ${bundle:com.domain.Messages:MyKey}. |
ctx | Thread Context Map (MDC) |
date | Inserts the current date and/or time using the specified format |
env | System environment variables |
jndi | A value set in the default JNDI Context. |
jvmrunargs | A JVM input argument accessed through JMX, but not a main argument; see RuntimeMXBean.getInputArguments(). Not available on Android. |
log4j | Log4j configuration properties. The expressions ${log4j:configLocation} and ${log4j:configParentLocation} respectively provide the absolute path to the log4j configuration file and its parent folder. |
main | A value set with MapLookup.setMainArguments(String[]) |
map | A value from a MapMessage |
sd | A value from a StructuredDataMessage. The key "id" will return the name of the StructuredDataId without the enterprise number. The key "type" will return the message type. Other keys will retrieve individual elements from the Map. |
sys | System properties |
Lookup Variables with Multiple Leading '$' Characters(查找帶有多個前導"$"字符的變量)
An interesting feature of StrLookup processing is that when a variable reference is declared with multiple leading '$' characters each time the variable is resolved the leading '$' is simply removed. In the previous example the "Routes" element is capable of resolving the variable at runtime. To allow this the prefix value is specified as a variable with two leading '$' characters. When the configuration file is first processed the first variable is simply removed. Thus, when the Routes element is evaluated at runtime it is the variable declaration "${sd:type}" which causes the event to be inspected for a StructuredDataMessage and if one is present the value of its type attribute to be used as the routing key. Not all elements support resolving variables at runtime. Components that do will specifically call that out in their documentation.(StrLookup 處理的一個有趣的特點是,當一個變量引用聲明了帶有多個前導'$'字符,在解析時只是簡單的將'$'刪除。在前面的示例中,“Routes”元素能夠在運行時解決變量。為了允許這個,前綴值被指定為帶有兩個前導$字符的變量。當配置文件被第一次處理時,第一個變量會被刪除。因此,當線路元件在運行時計算它的變量聲明 "${sd:type}" ,這會引起事件來檢查一個StructuredDataMessage 和如果類型屬性的值存在則作為 routing key。不是所有元素都支持在運行時解析變量。組件將在其文檔中明確調用該文件。 )
If no value is found for the key in the Lookup associated with the prefix then the value associated with the key in the properties declaration in the configuration file will be used. If no value is found the variable declaration will be returned as the value. Default values may be declared in the configuration by doing:(如果與前綴相關聯的查找中的鍵沒有找到值,則將使用配置文件中的屬性聲明中的鍵關聯的值。如果沒有找到值,變量聲明將被作為值返回。默認值可以在配置中聲明 ,如下:)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration> 3 <Properties> 4 <Property name="type">Audit</property> 5 </Properties> 6 ... 7 </Configuration>
As a footnote, it is worth pointing out that the variables in the RollingFile appender declaration will also not be evaluated when the configuration is processed. This is simply because the resolution of the whole RollingFile element is deferred until a match occurs. See RoutingAppender for more information.(作為一個注腳,值得指出的是,當配置文件被處理的時候,在rollingfile appender聲明中的變量也不會被評估時。這是因為整個rollingfile元素的解析被推遲到匹配發生的時候。更多信息見RoutingAppender。 )
Scripts(腳本)
Log4j provides support for JSR 223 scripting languages to be used in some of its components. Any language that provides support for the JSR 223 scripting engine may be used. A list of the languages and bindings for them can be found at the Scripting Engine web site. However, some of the languages listed there, such as JavaScript, Groovy and Beanshell, directly support the JSR 223 scripting framework and only require that the jars for that language be installed.
The components that support using scripts do so by allowing a <script>, <scriptFile>, or <scriptRef> element to be configured on them. The script element contains a name for the script, the language of the script, and the script text. The scriptFile element contains the name of the script, its location, its language, its charset, and whether the file should be watched for changes. The scriptRef element contains the name of the script that is defined in the <scripts> configuration element. The name of the script is used to store the script, along with its ScriptEngine, so it can quickly be located each time the script needs to be run. While the name is not required, providing it will help in debugging problems when the script is running. The language must be provided on the script element and must specify one of the language names that appear in the Configuration status log as described in the next section. If the language is not specified on the scriptFile element the language will be determined by the file extension of the script path. If file monitoring is requested it will only be enabled if a non-zero monitorInterval is specified on the configuration element. That interval will be used to check for changes in the file.
1 <?xml version="1.0" encoding="UTF-8"?> 2 <Configuration status="debug" name="RoutingTest"> 3 <Scripts> 4 <Script name="selector" language="javascript"><![CDATA[ 5 var result; 6 if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { 7 result = "NoLocation"; 8 } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { 9 result = "Flow"; 10 } 11 result; 12 ]]></Script> 13 <ScriptFile name="groovy.filter" path="scripts/filter.groovy"/> 14 </Scripts> 15 16 <Appenders> 17 <Console name="STDOUT"> 18 <ScriptPatternSelector defaultPattern="%d %p %m%n"> 19 <ScriptRef ref="selector"/> 20 <PatternMatch key="NoLocation" pattern="[%-5level] %c{1.} %msg%n"/> 21 <PatternMatch key="Flow" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/> 22 </ScriptPatternSelector> 23 <PatternLayout pattern="%m%n"/> 24 </Console> 25 </Appenders> 26 27 <Loggers> 28 <Logger name="EventLogger" level="info" additivity="false"> 29 <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY"> 30 <Script name="GroovyFilter" language="groovy"><![CDATA[ 31 if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { 32 return true; 33 } else if (logEvent.getContextMap().containsKey("UserId")) { 34 return true; 35 } 36 return false; 37 ]]> 38 </Script> 39 </ScriptFilter> 40 <AppenderRef ref="STDOUT"/> 41 </Logger> 42 43 <Root level="error"> 44 <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY"> 45 <ScriptRef ref="groovy.filter"/> 46 </ScriptFilter> 47 <AppenderRef ref="STDOUT"/> 48 </Root> 49 </Loggers> 50 51 </Configuration>
If the status attribute on the Configuration element is set to DEBUG the list of script engines currently installed and their attributes will be listed. Although some engines may say they are not thread safe, Log4j takes steps to insure that the scripts will run in a thread-safe manner if the engine advertises that it is not thread safe.
2015-09-27 16:13:22,925 main DEBUG Installed script engines 2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe, Compile: false, Names: {AppleScriptEngine, AppleScript, OSA} 2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED, Compile: true, Names: {groovy, Groovy} 2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED, Compile: true, Names: {beanshell, bsh, java} 2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED, Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript}
When the scripts are executed they will be provided with a set of variables that should allow them to accomplish whatever task they are expected to perform. See the documentation for the individual components for the list of variables that are available to the script.
The components that support scripting expect a return value to be passed back to the calling Java code. This is not a problem for several of the scripting languages, but Javascript does not allow a return statement unless it is within a function. However, Javascript will return the value of the last statement executed in the script. As a consequence, code such as that shown below will result in the desired behavior.
var result; if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { result = "NoLocation"; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { result = "Flow"; } result;
A special note on Beanshell
JSR 223 scripting engines are supposed to identify that they support the Compilable interface if they support compiling their scripts. Beanshell does this. However, whenever the compile method is called it throws an Error (not an Exception). Log4j catches this but will log the warning shown below for each Beanshell script when it tries to compile them. All Beanshell scripts will then be interpreted on each execution.
2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable 2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175) at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154) at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.<init>(ScriptManager.java:125) at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94)
XInclude
XML configuration files can include other files with XInclude. Here is an example log4j2.xml file that includes two other files:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <configuration xmlns:xi="http://www.w3.org/2001/XInclude" 3 status="warn" name="XIncludeDemo"> 4 <properties> 5 <property name="filename">xinclude-demo.log</property> 6 </properties> 7 <ThresholdFilter level="debug"/> 8 <xi:include href="log4j-xinclude-appenders.xml" /> 9 <xi:include href="log4j-xinclude-loggers.xml" /> 10 </configuration>
log4j-xinclude-appenders.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <appenders> 3 <Console name="STDOUT"> 4 <PatternLayout pattern="%m%n" /> 5 </Console> 6 <File name="File" fileName="${filename}" bufferedIO="true" immediateFlush="true"> 7 <PatternLayout> 8 <pattern>%d %p %C{1.} [%t] %m%n</pattern> 9 </PatternLayout> 10 </File> 11 </appenders>
log4j-xinclude-loggers.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <loggers> 3 <logger name="org.apache.logging.log4j.test1" level="debug" additivity="false"> 4 <ThreadContextMapFilter> 5 <KeyValuePair key="test" value="123" /> 6 </ThreadContextMapFilter> 7 <AppenderRef ref="STDOUT" /> 8 </logger> 9 10 <logger name="org.apache.logging.log4j.test2" level="debug" additivity="false"> 11 <AppenderRef ref="File" /> 12 </logger> 13 14 <root level="error"> 15 <AppenderRef ref="STDOUT" /> 16 </root> 17 </loggers>
Composite Configuration
Log4j allows multiple configuration files to be used by specifying them as a list of comma separated file paths on log4j.configurationFile. The merge logic can be controlled by specifying a class that implements the MergeStrategy interface on the log4j.mergeStrategy property. The default merge strategy will merge the files using the following rules:
- The global configuration attributes are aggregated with those in later configurations replacing those in previous configurations, with the exception that the highest status level and the lowest monitorInterval greater than 0 will be used.
- Properties from all configurations are aggregated. Duplicate properties replace those in previous configurations.
- Filters are aggregated under a CompositeFilter if more than one Filter is defined. Since Filters are not named duplicates may be present.
- Scripts and ScriptFile references are aggregated. Duplicate definiations replace those in previous configurations.
- Appenders are aggregated. Appenders with the same name are replaced by those in later configurations, including all of the Appender's subcomponents.
- Loggers are all aggregated. Logger attributes are individually merged with duplicates being replaced by those in later configurations. Appender references on a Logger are aggregated with duplicates being replaced by those in later configurations. Filters on a Logger are aggregated under a CompositeFilter if more than one Filter is defined. Since Filters are not named duplicates may be present. Filters under Appender references included or discarded depending on whether their parent Appender reference is kept or discarded.
Status Messages
Troubleshooting tip for the impatient:
|
protected final static Logger logger = StatusLogger.getLogger();
Since StatusLogger implements the Log4j 2 API's Logger interface, all the normal Logger methods may be used.
When configuring Log4j it is sometimes necessary to view the generated status events. This can be accomplished by adding the status attribute to the configuration element or a default value can be provided by setting the "Log4jDefaultStatusLevel" system property. Valid values of the status attribute are "trace", "debug", "info", "warn", "error" and "fatal". The following configuration has the status attribute set to debug.
1 <?xml version="1.0" encoding="UTF-8"?>; 2 <Configuration status="debug" name="RoutingTest"> 3 <Properties> 4 <Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property> 5 </Properties> 6 <ThresholdFilter level="debug"/> 7 8 <Appenders> 9 <Console name="STDOUT"> 10 <PatternLayout pattern="%m%n"/> 11 </Console> 12 <List name="List"> 13 <ThresholdFilter level="debug"/> 14 </List> 15 <Routing name="Routing"> 16 <Routes pattern="$${sd:type}"> 17 <Route> 18 <RollingFile name="Rolling-${sd:type}" fileName="${filename}" 19 filePattern="target/rolling1/test1-${sd:type}.%i.log.gz"> 20 <PatternLayout> 21 <pattern>%d %p %c{1.} [%t] %m%n</pattern> 22 </PatternLayout> 23 <SizeBasedTriggeringPolicy size="500" /> 24 </RollingFile> 25 </Route> 26 <Route ref="STDOUT" key="Audit"/> 27 <Route ref="List" key="Service"/> 28 </Routes> 29 </Routing> 30 </Appenders> 31 32 <Loggers> 33 <Logger name="EventLogger" level="info" additivity="false"> 34 <AppenderRef ref="Routing"/> 35 </Logger> 36 37 <Root level="error"> 38 <AppenderRef ref="STDOUT"/> 39 </Root> 40 </Loggers> 41 42 </Configuration>
During startup this configuration produces:
2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds 2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log") 2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log}) 2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds 2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") 2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null") 2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds 2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null") 2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") 2011-11-23 17:08:00,806 DEBUG Calling createAppender on class org.apache.logging.log4j.test.appender.ListAppender for element List with params(name="List", entryPerNewLine="null", raw="null", null, ThresholdFilter(DEBUG)) 2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route) 2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route) 2011-11-23 17:08:00,824 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="List", key="Service", Node=Route) 2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit'), Route(type=static Reference=List key='Service')}) 2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit'),Route(type=static Reference=List key='Service')}), Configuration(RoutingTest), null, null) 2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, List, Routing}) 2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing") 2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null) 2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT") 2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null) 2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root}) 2011-11-23 17:08:00,834 DEBUG Reconfiguration completed 2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null") 2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500") 2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null") 2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds 2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39 2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds 2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds 2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds 2011-11-23 17:08:00,965 WARN No Loggers were configured, using default 2011-11-23 17:08:00,976 DEBUG Reconfiguration completed
If the status attribute is set to error than only error messages will be written to the console. This makes troubleshooting configuration errors possible. As an example, if the configuration above is changed to have the status set to error and the logger declaration is:
<logger name="EventLogger" level="info" additivity="false"> <AppenderRef ref="Routng"/> </logger>
the following error message will be produced.
2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger
Applications may wish to direct the status output to some other destination. This can be accomplished by setting the dest attribute to either "err" to send the output to stderr or to a file location or URL. This can also be done by insuring the configured status is set to OFF and then configuring the application programmatically such as:
StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); StatusLogger.getLogger().registerListener(listener);
Testing in Maven
Maven can run unit and functional tests during the build cycle. By default, any files placed in src/test/resources are automatically copied to target/test-classes and are included in the classpath during execution of any tests. As such, placing a log4j2-test.xml into this directory will cause it to be used instead of a log4j2.xml or log4j2.json that might be present. Thus a different log configuration can be used during testing than what is used in production.
A second approach, which is extensively used by Log4j 2, is to set the log4j.configurationFile property in the method annotated with @BeforeClass in the junit test class. This will allow an arbitrarily named file to be used during the test.
A third approach, also used extensively by Log4j 2, is to use the LoggerContextRule JUnit test rule which provides additional convenience methods for testing. This requires adding the log4j-core test-jar dependency to your test scope dependencies. For example:
public class AwesomeTest { @Rule public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml"); @Test public void testSomeAwesomeFeature() { final LoggerContext ctx = init.getContext(); final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger"); final Configuration cfg = init.getConfiguration(); final ListAppender app = init.getListAppender("List"); logger.warn("Test message"); final List<LogEvent> events = app.getEvents(); // etc. } }
System Properties
The Log4j documentation references a number of System Properties that can be used to control various aspects of Log4j 2 behavior. The table below lists these properties along with their default value and a description of what they control. Any spaces present in the property name are for visual flow and should be removed.
The properties listed below can also be specified by creating a file named log4j2.component.properties, adding the desired keys and value to the file, and then including the file in the classpath of the application.
System Property | Default Value | Description |
---|---|---|
log4j.configurationFile | Path to an XML or JSON Log4j 2 configuration file. May also contain a comma separated list of configuration file names. | |
log4j.mergeFactory | The name of the class that implements the MergeStrategy interface. If not specified DefaultMergeStrategy will be used when creating a CompositeConfiguration.. | |
Log4jContextSelector | ClassLoaderContextSelector | Creates the LoggerContexts. An application can have one or more active LoggerContexts depending on the circumstances. See Log Separation for more details. Available context selector implementation classes: org.apache.logging.log4j.core.async .AsyncLoggerContextSelector - makes all loggers asynchronous. org.apache.logging.log4j.core.selector .BasicContextSelector - creates a single shared LoggerContext. org.apache.logging.log4j.core.selector .ClassLoaderContextSelector - separate LoggerContexts for each web application. org.apache.logging.log4j.core.selector .JndiContextSelector - use JNDI to locate each web application's LoggerContext. org.apache.logging.log4j.core.osgi .BundleContextSelector - separate LoggerContexts for each OSGi bundle. |
Log4jLogEventFactory | org.apache.logging.log4j.core.impl .DefaultLogEventFactory | Factory class used by LoggerConfig to create LogEvent instances. (Ignored when the AsyncLoggerContextSelector is used.) |
log4j2.loggerContextFactory | org.apache.logging.log4j.simple .SimpleLoggerContextFactory | Factory class used by LogManager to bootstrap the logging implementation. The core jar provides org.apache.logging.log4j.core.impl.Log4jContextFactory. |
log4j.configurationFactory | Fully specified class name of a class extending org.apache.logging.log4j.core.config.ConfigurationFactory. If specified, an instance of this class is added to the list of configuration factories. | |
log4j.shutdownHookEnabled | true | Overrides the global flag for whether or not a shutdown hook should be used to stop a LoggerContext. By default, this is enabled and can be disabled on a per-configuration basis. When running with the log4j-web module, this is automatically disabled. |
log4j.shutdownCallbackRegistry | org.apache.logging.log4j.core.util .DefaultShutdownCallbackRegistry | Fully specified class name of a class implementing ShutdownCallbackRegistry. If specified, an instance of this class is used instead of DefaultShutdownCallbackRegistry. The specified class must have a default constructor. |
log4j.Clock | SystemClock | Implementation of the org.apache.logging.log4j.core.util.Clock interface that is used for timestamping the log events. By default, System.currentTimeMillis is called on every log event. You can also specify a fully qualified class name of a custom class that implements the Clock interface. |
org.apache.logging.log4j.level | ERROR | Log level of the default configuration. The default configuration is used if the ConfigurationFactory could not successfully create a configuration (e.g. no log4j2.xml file was found). |
disableThreadContext | false | If true, the ThreadContext stack and map are disabled. (May be ignored if a custom ThreadContext map is specified.) |
disableThreadContextStack | false | If true, the ThreadContext stack is disabled. |
disableThreadContextMap | false | If true, the ThreadContext map is disabled. (May be ignored if a custom ThreadContext map is specified.) |
log4j2.threadContextMap | Fully specified class name of a custom ThreadContextMap implementation class. | |
isThreadContextMapInheritable | false | If true use a InheritableThreadLocal to implement the ThreadContext map. Otherwise, use a plain ThreadLocal. (May be ignored if a custom ThreadContext map is specified.) |
log4j2.ContextDataInjector | Fully specified class name of a custom ContextDataInjector implementation class. | |
log4j2.garbagefree.threadContextMap | false | Specify "true" to make the ThreadContext map garbage-free. |
log4j2.disable.jmx | false | If true, Log4j configuration objects like LoggerContexts, Appenders, Loggers, etc. will not be instrumented with MBeans and cannot be remotely monitored and managed. |
log4j2.jmx.notify.async | false for web apps, true otherwise | If true, log4j's JMX notifications are sent from a separate background thread, otherwise they are sent from the caller thread. If system property log4j2.is.webapp is true or the javax.servlet.Servlet class is on the classpath, the default behaviour is to use the caller thread to send JMX notifications. |
log4j.skipJansi | false | If true, the ConsoleAppender will not try to use the Jansi output stream on Windows. |
log4j.ignoreTCL | false | If true, classes are only loaded with the default class loader. Otherwise, an attempt is made to load classes with the current thread's context class loader before falling back to the default class loader. |
org.apache.logging.log4j.uuidSequence | 0 | System property that may be used to seed the UUID generation with an integer value. |
org.apache.logging.log4j.simplelog .showContextMap | false | If true, the full ThreadContext map is included in each SimpleLogger log message. |
org.apache.logging.log4j.simplelog .showlogname | false | If true, the logger name is included in each SimpleLogger log message. |
org.apache.logging.log4j.simplelog .showShortLogname | true | If true, only the last component of a logger name is included in SimpleLogger log messages. (E.g., if the logger name is "mycompany.myproject.mycomponent", only "mycomponent" is logged. |
org.apache.logging.log4j.simplelog .showdatetime | false | If true, SimpleLogger log messages contain timestamp information. |
org.apache.logging.log4j.simplelog .dateTimeFormat | "yyyy/MM/dd HH:mm:ss:SSS zzz" | Date-time format to use. Ignored if org.apache.logging.log4j.simplelog.showdatetime is false. |
org.apache.logging.logj.simplelog .logFile | system.err | "system.err" (case-insensitive) logs to System.err, "system.out" (case-insensitive) logs to System.out, any other value is interpreted as a file name to save SimpleLogger messages to. |
org.apache.logging.log4j.simplelog .level | ERROR | Default level for new SimpleLogger instances. |
org.apache.logging.log4j.simplelog.<loggerName>level | SimpleLogger default log level | Log level for a the SimpleLogger instance with the specified name. |
org.apache.logging.log4j.simplelog .StatusLogger.level | ERROR | This property is used to control the initial StatusLogger level, and can be overridden in code by calling StatusLogger.getLogger().setLevel(someLevel). Note that the StatusLogger level is only used to determine the status log output level until a listener is registered. In practice, a listener is registered when a configuration is found, and from that point onwards, status messages are only sent to the listeners (depending on their statusLevel). |
Log4jDefaultStatusLevel | ERROR | The StatusLogger logs events that occur in the logging system to the console. During configuration, AbstractConfiguration registers a StatusConsoleListener with the StatusLogger that may redirect status log events from the default console output to a file. The listener also supports fine-grained filtering. This system property specifies the default status log level for the listener to use if the configuration does not specify a status level. Note: this property is used by the log4j-core implementation only after a configuration file has been found. |
log4j2.StatusLogger.level | WARN | The initial "listenersLevel" of the StatusLogger. If StatusLogger listeners are added, the "listenerLevel" is changed to that of the most verbose listener. If any listeners are registered, the listenerLevel is used to quickly determine if an interested listener exists. By default, StatusLogger listeners are added when a configuration is found and by the JMX StatusLoggerAdmin MBean. For example, if a configuration contains <Configuration status="trace">, a listener with statusLevel TRACE is registered and the StatusLogger listenerLevel is set to TRACE, resulting in verbose status messages displayed on the console. If no listeners are registered, the listenersLevel is not used, and the StatusLogger output level is determined by StatusLogger.getLogger().getLevel() (see property org.apache.logging.log4j.simplelog .StatusLogger.level). |
log4j2.status.entries | 200 | Number of StatusLogger events that are kept in a buffer and can be retrieved with StatusLogger.getStatusData(). |
AsyncLogger.ExceptionHandler | default handler | See Async Logger System Properties for details. |
AsyncLogger.RingBufferSize | 256 * 1024 | See Async Logger System Properties for details. |
AsyncLogger.WaitStrategy | Timeout | See Async Logger System Properties for details. |
AsyncLogger.ThreadNameStrategy | CACHED | See Async Logger System Properties for details. |
AsyncLoggerConfig.ExceptionHandler | default handler | See Mixed Async/Synchronous Logger System Properties for details. |
AsyncLoggerConfig.RingBufferSize | 256 * 1024 | See Mixed Async/Synchronous Logger System Properties for details. |
AsyncLoggerConfig.WaitStrategy | Timeout | See Mixed Async/Synchronous Logger System Properties for details. |
log4j.jul.LoggerAdapter | org.apache.logging.log4j.jul .ApiLoggerAdapter | Default LoggerAdapter to use in the JUL adapter. By default, if log4j-core is available, then the class org.apache.logging.log4j.jul .CoreLoggerAdapter will be used. Otherwise, the ApiLogggerAdapter will be used. Custom implementations must provide a public default constructor. |
log4j.format.msg.async | false | If false (the default), Log4j will make sure the message is formatted in the caller thread, to ensure the value at the time of the call to the logger is the value that is logged. |
log4j2.AsyncQueueFullPolicy | Used by Async Loggers and the AsyncAppender to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. If no value is specified (the default) events are never discarded. If the queue is full, the logger call blocks until the event can be added to the queue. Specify Discard to drop events whose level is equal or less than the threshold level (INFO by default) when the queue is full. |
|
log4j2.DiscardThreshold | INFO | Used by the DiscardingAsyncQueueFullPolicy to determine which events to drop when the queue becomes full. By default, INFO, DEBUG and TRACE level events are discarded when the queue is full. This property only has effect if Discard is specified as the log4j2.AsyncQueueFullPolicy. |
log4j2.messageFactory | org.apache.logging.log4j.message. ParameterizedMessageFactory or org.apache.logging.log4j.message. ReusableMessageFactory in garbage-free mode | Default message factory used by Loggers if no factory was specified. |
log4j2.flowMessageFactory | org.apache.logging.log4j.message. DefaultFlowMessageFactory | Default flow message factory used by Loggers. |
log4j2.is.webapp | true if Servlet class on class path | This system property can be used to force Log4j 2 to behave as if it is part of a web application (when true) or as if it is not part of a web application (when false). |
log4j2.enable.threadlocals | true | This system property can be used to switch off the use of threadlocals, which will partly disable Log4j's garbage-free behaviour: to be fully garbage-free, Log4j stores objects in ThreadLocal fields to reuse them, otherwise new objects are created for each log event. Note that this property is not effective when Log4j detects it is running in a web application. |
log4j2.enable.direct.encoders | true | This property can be used to force garbage-aware Layouts and Appenders to revert to the pre-2.6 behaviour where converting log events to text generates temporary objects like Strings and char[] arrays, and converting this text to bytes generates temporary byte[] arrays. By default, this property is true and garbage-aware Layouts and Appenders that convert log events to text will convert this text to bytes without creating temporary objects. |
log4j.initialReusableMsgSize | 128 | In GC-free mode, this property determines the initial size of the reusable StringBuilders where the message text is formatted and potentially passed to background threads. |
log4j.maxReusableMsgSize | 518 | In GC-free mode, this property determines the maximum size of the reusable StringBuilders where the message text is formatted and potentially passed to background threads. |
log4j.layoutStringBuilder.maxSize | 2048 | This property determines the maximum size of the thread-local reusable StringBuilders used to format the log event to text by Layouts that extend AbstractStringLayout. |
log4j.unbox.ringbuffer.size | 32 | The org.apache.logging.log4j.util.Unbox utility manages a small thread-local ring buffer of StringBuilders. Each time one of the box() methods is called, the next slot in the ring buffer is used, until the ring buffer is full and the first slot is reused. By default the Unbox ring buffer has 32 slots, so user code can have up to 32 boxed primitives in a single logger call. If more slots are required, set system property log4j.unbox.ringbuffer.size to the desired ring buffer size. Note that the specified number will be rounded up to the nearest power of 2. |
log4j.LoggerContext.stacktrace.on.start | false | Prints a stacktrace to the status logger at DEBUG level when the LoggerContext is started. For debug purposes. |