- 前言
- Apache Log4j2
- About
- Maven
- Log4j 1.x API Bridge
- Apache Commons Logging Bridge
- SLF4J Bridge
- FAQ
- which JAR files do I need?
- How do I specify the configuration file location?
- How do I send log messages with different levels to different appenders?
- How do I debug my configuration?
- How do I dynamically write to separate log files?
- How do I set my log archive retention policy? How do I delete old log archives?
- MANUAL
- Introduction
- Architecture
- Migrating from Log4j 1.x
- Java API
- Configuration
- Automatic Configuration
- Additivity
- Automatic Reconfiguration
- Chainsaw can automatically process your log files (Advertising appender configurations)
- Configuration Syntax
- Strict XML
- Configuring loggers
- Configuring Appenders
- Configuration with Properties
- Property Substitution
- Lookup Variables with Multiple Leading ‘$’ Characters
- scripts
- XInclude
- Composite Configuration
- Status Messages
- Testing in Maven
- System Properties
- Web Applications and JSPs
- Lookups
- Appenders
- AsyncAddpender
- CassandraAppender
- ConsoleAppender
- FailoverAppender
- FileAppender
- FlumeAppender
- JDBCAppender
- JMS Appender
- JPA Appender
- Http Appender
- Kafka Appender
- MemoryMappedFile Appender
- NoSQL Appender
- NoSQL Appender for MongoDB
- NoSQL Appender for MongoDB 2
- NoSQL Appender for MongoDB 3
- NoSQL Appender for Apache CouchDB
- OutputStreamAppender
- RandomAccessFileAppender
- RewriteAppender
前言
查看官方文档,做个了解说明。对官方文档理解下,翻译说明。
文档地址:http://logging.apache.org/log4j/2.x/index.html
Apache Log4j2
About
log4j2 相比较于log4j 1.x有很多改善,他们不兼容,可以使用Adapters处理。
支持java8,custom log levels
Maven
log4j2拆开了2个jar,一个API,一个implementatio(core)
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
Log4j 1.x API Bridge
如果有组件使用Log4j 1.x,你想要路由到Log4j 2,可以去除任何的log4j 1.x的依赖,然后添加如下。
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
Apache Commons Logging Bridge
如果有组件使用Apache Commons Lgging 1.x,你想要路由到Log4j 2,可以去除任何Commons Logging 1.x的依赖。
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
SLF4J Bridge
如果有组件使用ASLF4J,你想要路由到Log4j 2,可以去除任何SLF4J的依赖。
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
FAQ
which JAR files do I need?
log4j-api-2.x jar log4j-core-2.x jar
How do I specify the configuration file location?
默认情况下,log4j查找log4j2.xml文件,也可以自己制定路径。web程序按照web程序来处理了。
How do I send log messages with different levels to different appenders?
<?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>
How do I debug my configuration?
lo4j-2.9之后,设置下system property log4j2.debug
How do I dynamically write to separate log files?
查看RoutingAppender,你能够再配置文件中定义多个routes。放置这些values到ThreadContext
中去决定该线程中的哪些日志文件后续事件被记录到。也可以使用ThreadContext
去决定log文件的名称。
code …..
How do I set my log archive retention policy? How do I delete old log archives?
Q:(如何设置log文件的保存策略,如何删除旧的log文档)
A:Rolling File appender(and Rolling random Access File appender)的DefaultRolloverStrategy
支持删除。
从指定的基础目录开始,您可以删除所有条件适用的文件,例如与给定文件名模式匹配的所有文件,并且都比某些天数要老。更复杂的条件是可能的,如果内置条件不充分,用户可以通过创建插件条件或编写脚本条件来提供自定义条件。
MANUAL
Introduction
优点:
- 包含了下一代的Asynchronous Logger给予LMAX Disruptor Library
- 使用了Plugin System去容易的扩展通过添加Appenders,Filters,Layouts,Lookups
- 支持custom log levels
- 支持lambda expressions
- 支持Message object
Architecture
程序使用Log4j 2时将向LogManager请求具有特定名称的Logger。LogManager将找到合适的LoggerContext,然后从中获取Logger。如果必须创建Logger,它将与LoggerConfig相关联,该LoggerConfig是这些选择中的一个,a)和这个Logger有相同的名称,b)和一个父类的包有相同的名字,c)Root的LoggerConfig。LoggerConfig对象是通过配置文件中的的Logger声明创建的。LoggerConfig与实际提供LogEvent的Appender相关联。
Logger Hierarchy
在Log4j 1.x中的Logger层级关系是通过Loggers的关系维护的,再Log4j 2中这个关系不存在了,相反,这个层级关系保留在了LoggerConfig对象中。
记录器和记录器构件是命名实体。记录器名称区分大小写,它们遵循分层命名规则:
Named Hierarchy:A LoggerConfig is said to be an ancestor of another LoggerConfig if its name followed by a dot is a prefix of the descendant logger name. A LoggerConfig is said to be a parent of a child LoggerConfig if there are no ancestors between itself and the descendant LoggerConfig.
例如,名称是com.foo
的LoggerConfig是名称com.foo.Bar
的父类。相似的是java
是java.utl
的父类,是java.util.Vector
的祖先。
root LoggerConfig是所有的LoggerConfig层级的最顶层,可以如下方式获取:
Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
Logger logger = LogManager.getRootLogger();
可以使用LogManager.getLogger
静态方法通过传递所需记录器的名称来检索所有其他的记录器。
Logger Context
该LoggerContext
充当锚点的记录系统。但是,根据具体情况,应用程序中可能会有多个活动LoggerContext。
Configuration
每一个LoggerContext拥有一个活动的Configuration
,这个配置包含了所有的Appedners,context-wide Filters,LoggerConfigs等等
Logger
如前所述,通过调用LogManager.getLogger
创建记录器Logger。Logger本身不执行直接操作。它只是一个名称,并与LoggerConfig关联。它扩展了 AbstractLogger
并实现了所需的方法。当配置被修改时,记录器可能与不同的LoggerConfig关联,从而导致其行为被修改。
- 调用具有相同名称的LogManager.getLogger方法将始终返回对同一个Logger对象的引用。
- Log4j的配置通常是在应用程序初始化的时候完成的,首选读取配置文件
- Log4j可以很容易使用组织命名Loggers,一般是在类中实例化logger,采取类的全限定名称,这样记录可以轻松识别日志来源。当然也可以采取自己命名的Logger。
LoggerConfig
当在配置文件中声名Loggres时,LoggerConfig就被创建了。LoggerConfig包含一组必须允许LogEvent在传递给任何Appender之前通过的过滤器。它包含对应用于处理事件的一组Appender的引用。
Log Levels
LoggerConfig会关联Log Level,内置的Level包含了TRACE, DEBUG, INFO, WARN, ERROR, and FATAL。Log4j也支持自定义日志级别。
Log4j 1.x 和 Logback 都有“Level Inheritance”的概念。在Log4j 2中,Loggers和LoggerConfigs是两个不同的对象,所以这个概念的实现方式不同。每个记录器都引用相应的LoggerConfig,这个LoggerConfig可以引用它的父代,从而达到相同的效果。
ALL->TRACE->DEBUG->INFO->WARN->ERROR->FATAL->OFF
Filter
除了正常的自动日志级别过滤之外,Log4j还提供了Filter。可以在将控制权传递给任何LoggerConfig之前应用,在将控制权传递给LoggerConfig之后,但在调用任何Appender之前,控制权之后传递给LoggerConfig,但在调用特定的Appender之前,以及每个Appender上。每一个Filter可以返回三种结果中的Accept
,Deny
,Neutral
的一个。Accept
意思是其他的过滤器不应该被调用,event应该通过。Deny
意思是event应该被立刻忽略,这个控制返回给调用者。Neutral
表明这个事件应该通过其他Filter,如果没有其他的Filter,那么通过。
Appender
Log4j允许请求打印到不同的目的地,这些目的地被当做Appender,包含了console,files,remote socket servers,Apache Flume,JMS,remote UNIX Syslog daemons,various database APIs.一个Logger可以配置多个Appender。
Each enabled logging request for a given logger will be forwarded to all the appenders in that Logger's LoggerConfig as well as the Appenders of the LoggerConfig's parents.
给定记录器的每个启用的记录请求将被转发给该记录器的LoggerConfig中的所有appender以及LoggerConfig的父母的Appender,换句话说,Appender是从LoggerConfig层次结构继承的。例如,如果一个console appender被添加到了root looger,那么所有的日志请求将会打印到console当中。如果一个file appender添加到了一个LoggerConfig,叫C,那么所有C的日志和C孩子的日志请求将会被记录到file中和console中。可以重写这个默认的行为通过设置additivaity=false
属性阻止继续写入。
Appender Additivity
The output of a log statement of Logger L will go to all the Appenders in the LoggerConfig associated with L and the ancestors of that LoggerConfig. This is the meaning of the term "appender additivity".
However, if an ancestor of the LoggerConfig associated with Logger L, say P, has the additivity flag set to false, then L's output will be directed to all the appenders in L's LoggerConfig and it's ancestors up to and including P but not the Appenders in any of the ancestors of P.
Loggers have their additivity flag set to true by default.
Layout
这是Appender的layout相关联的。Layout根据用户的想法格式化LogEvent,而Appender负责将格式化内容输出到目的地。PatternLayout是标准Log4j的一部分,让用户使用类似C语言的方式输出内容。
pattern "%r [%t] %-5p %c - %m%n"
176 [main] INFO org.foo.Bar - Located nearest gas station.
Log4j含有很多不同的Layouts格式为了使用场景,例如JSON,XML,HTML,和SysyLog。其他的例如数据库连接将会使用具体的数据库字段了。
Migrating from Log4j 1.x
Converting to the Log4j 2 API
1.版本1中的包名是org.apache.log4j
,在版本2中是org.apache.logging.log4j
2.调用方式org.apache.log4j.Logger.getLogger()
必须修改成org.apache.logging.log4j.LogManager.getLogger()
Configuring Log4j2
Log4j的配置语法不同于Log4j 1.x,但是大多数还是相同的。可以根据Lookups查看变量。
Log4j 1.x中的PatternLayout
和EnhancedPatternLayout
能够被Log4j.2的PatternLayout
替换。
Simeple configuration using a Console appender
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="info"/>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Simple configuration using a File Appender, XMLLayout and SimpleLayout
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="A1" fileName="A1.log" append="false">
<Log4j1XmlLayout />
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%level - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Java API
Log4j 2 API
简单的使用如下:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorld {
private static final Logger logger = LogManager.getLogger("HelloWorld");
public static void main(String[] args) {
logger.info("Hello, World!");
}
}
Substituting Parameters
日志记录的目的往往是提供有关系统中正在发生的事情的信息,这需要包括有关被操纵对象的信息。在Log4j 1.x中,这可以通过执行以下操作来完成:
if (logger.isDebugEnabled()) {
logger.debug("Logging in user " + user.getName() + " with birthday " + user.getBirthdayCalendar());
}
重复执行此操作会使代码感觉更像是日志记录,而不是实际的任务。另外,它会导致记录级别被检查两次; 一次调用isDebugEnabled,一次调试方法。更好的选择是:
logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());
使用上面的日志级别的代码只会被检查一次,并且String结构只会在调试日志被启用时才会发生。
Java 8 lambda supprot for lazy logging
jav能够执行一个lambda表达式,这样就不用立刻检测log的level:
// Java-8 style optimization: no need to explicitly check the log level:
// the lambda expression is not evaluated if the TRACE level is not enabled
logger.trace("Some long-running operation returned {}", () -> expensiveOperation());
Logger Names
大部分的日志记录采取分层方案匹配Logger的名称和配置。这些是采取.
来进行层次的分割。以下三个表明Logger名称一样是org.apache.test.MyTest
:
private static final Logger logger = LogManager.getLogger(MyTest.class);
private static final Logger logger = LogManager.getLogger(MyTest.class.getName());
private static final Logger logger = LogManager.getLogger();
Configuration
Log4j可以采取4种方式来完成配置:
- 通过xml,json,yaml,properties格式;
- 程序创建ConfigurationFactory和Configuration实现;
- 程序调用Configuration界面中公开的API将组建添加到默认的配置中;
- 程序调用内部Logger类的方法。
Automatic Configuration
log4j会尝试加载一堆的文件看看是否存在。log4j2.properties->log4j2.yaml->log4j2.json->log4j2.xml
如果以上都没有配置,那么僵加载DefaultConfiguration
配置。
DefaultConfiguration将执行如下的操作:
- root logger中附加一个ConsoleAppender
- 给ConsoleAppender配置一个PatternLayout,格式如同
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
这等同于如下的配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Additivity
如果需要给com.foo.Bar
新增一个TRACE的输出,最好是新定义一个Logger。
<Logger name="com.foo.Bar" level="TRACE"/>
<Root level="ERROR">
<AppenderRef ref="STDOUT">
</Root>
使用此配置之后,那么com.foo.Bar
会记录会有的事件,而其他类仅仅记录ERROR情况。此Logger没有配置Appedners,此时将会采取Root的Appender
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.foo.Bar" level="trace">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
按照如上配置之后,那么com.foo.Bar
的消息会被记录2次,首先自己记录一次,其次会将事件传到给父类,父类dappender在调用一次,导致2次,这是的追加性。多数情况下我们不需要追加,可以将additivity属性设置为false即可。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.foo.Bar" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Automatic Reconfiguration
从文件配置时,Log4j能够自动检测配置文件的更改并重新配置自身。如果在配置元素上指定了monitorInterval
属性并将其设置为非零值,则在下一次计算和/或记录日志事件并且自上次检查以来已经过去monitorInterval时,将检查该文件。下面的示例显示了如何配置该属性,以便仅在至少30秒过后才会检查配置文件的更改。最小间隔是5秒。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>
Chainsaw can automatically process your log files (Advertising appender configurations)
广告配置…
Configuration Syntax
为了安全考虑,Log4j将不会再XML文件中处理DTD。
XML文件中Configuration
元素配置属性如下:
- dest:取值err,将发送输出到stderr,或者一个文件的URL
- monitorInterval:检查文件变更的最少时间(单位秒)
- name:配置名称
- packages:用逗号分隔的包名称列表来搜索插件。每个类加载器只加载一次插件,所以更改此值可能对重新配置没有任何影响
- schema:标识类加载程序的位置,以找到用于验证配置的XML模式。只有严格设置为true时才有效。如果没有设置,则不会发生模式验证。
- shutdownHook:指定在JVM关闭时是否自动关闭Log4j。关闭挂钩默认启用,但可以通过将此属性设置为“禁用”来禁用
- shutdownTimeout:指定在JVM关闭时将关闭多少毫秒的附加程序和后台任务。默认值为零表示每个appender使用其默认超时值,并且不等待后台任务。并非所有的appender都会尊重这一点,这只是一个暗示,并不是绝对保证关机程序不会花费更长的时间。将其设置得太低会增加丢失尚未写入最终目的地的未完成日志事件的风险。(如果shutdownHook设置为“禁用”,则不使用。)
- status:应该被记录到控制台的内部Log4j事件的级别。此属性的有效值为”trace”, “debug”, “info”, “warn”, “error” and “fatal”。Log4j会将记录一些细节关于初始化,回滚,和其他内部操作的细节记录下来。如果您需要排除log4j故障,设置
status=trace
是您可以使用的第一个工具之一。
(或者,设置系统属性log4j2.debug也会打印内部Log4j2日志记录到控制台,包括发现配置文件之前发生的内部日志记录。) - strict:允许使用严格的XML格式。在JSON配置中不受支持。
- verbose:加载插件时启用诊断信息。
Log4可以使用2中xml风格:简洁和严谨。简洁的格式是的配置文件和简单,元素名称和她们所代表的组件匹配,但是无法使用XML模式验证。例如,可以采取如下2种方式:
<PatternLayout pattern="%m%n"/>
<PatternLayout>
<Pattern>%m%n</Pattern>
</PatternLayout>
下面的文件表示XML配置的结构,但请注意,以下斜体中的元素表示将显示在其位置上的简洁元素名称。
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<filter ... />
<Appenders>
<appender ... >
<filter ... />
</appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<filter ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
更多的例子参看Appedner,Filter,Logger细节。
Strict XML
除了上述简洁的XML格式之外,Log4j允许以更“正常”的XML方式指定配置,可以使用XML模式进行验证。这是通过用它们的对象类型替换上面的友好元素名称来完成的,如下所示。例如,不是使用名为Console的元素来配置ConsoleAppender,而是将其配置为具有包含“控制台”的类型属性的appender元素。
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<Filter type="type" ... />
<Appenders>
<Appender type="type" name="name">
<Filter type="type" ... />
</Appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<Filter type="type" ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
以下是使用stact模式的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest"
packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="trace"/>
<Appenders>
<Appender type="Console" name="STDOUT">
<Layout type="PatternLayout" pattern="%m MDC%X%n"/>
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
</Filters>
</Appender>
<Appender type="Console" name="FLOW">
<Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</Appender>
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</Layout>
</Appender>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<Filter type="ThreadContextMapFilter">
<KeyValuePair key="test" value="123"/>
</Filter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<AppenderRef ref="File"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
同时也只是json和yaml的配置方式
Configuring loggers
在尝试配置它们之前,了解Log4j中记录器的工作方式至关重要。如果需要更多信息,请参考Log4j 体系结构。尝试在不理解这些概念的情况下配置Log4j会导致沮丧。
一个LoggerConfig将由logger元素配置。这个logger元素必须制定name属性,它通常会有一个level属性和additivity属性。level属性可以配置trace,debug,info,warn,error,all,off。如果没有配置,那么默认是error级别。additivity属性将会是true或false。如果没有指定,那么默认的true将会被指定。
LoggerConfig(包括根LoggerConfig)可以配置属性,这些属性将添加到从ThreadContextMap复制的属性中。这些属性可以从Appender,Filters,Layouts等引用,就像它们是ThreadContext Map的一部分一样。这些属性可以包含将在解析配置时解析的变量,或者在记录每个事件时动态解析的变量。有关使用变量的更多信息,请参阅Property Substitution。
LoggerConfig也可以配置一个或多个AppenderRef元素。每个引用的appender都将与指定的LoggerConfig关联。如果在LoggerConfig上配置了多个appender,则每个appender在处理日志记录事件时都会被调用。
Every configuration must have a root logge。如果没有配置默认root LoggerConfig,它具有ERROR级别并且连接了控制台appender,将被使用。root logger和其他logger之间的主要区别是
- root logger没有名称属性。
- root logger不支持可加性属性,因为它没有父对象。
Configuring Appenders
appender配置使用特定的appender插件的名称或appender元素和类型attibute包含appender插件的名称。此外,每个appender必须具有一个名称属性,该名称属性由一组appender中唯一的值指定。记录器将使用该名称来引用appender,如前一节所述。
大多数appender还支持要配置的布局(可以使用特定布局插件的名称作为元素或使用“布局”作为元素名称以及包含布局插件名称的类型属性来指定布局)。各种appender将包含其正确运行所需的其他属性或元素
###cConfiguring Filter
log4j允许在4个地方指定一个过滤器:
- 与appenders,loggers,properties元素拥有相同级别的,这些filters能够接受或者拒绝事件在被LoggerConfig通过之后。
- 在logger元素中,这些filters能够接受或拒绝特定的loggers
- 在appender元素中,这些filters能够阻止或者导致事件通过这些appender
- 在appender引用元素中,这些filters用于确定记录器是否应将事件路由到appender
尽管仅仅有单个filter能够被配置,但是该元素可能是表示CompositeFilter的filters元素。这些filters元素允许任意数量的filter元素去在内部配置它。以下展示了在ConsoleAppender中配置多个filters。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<ThresholdFilter level="trace"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m MDC%X%n"/>
</Console>
<Console name="FLOW">
<!-- this pattern outputs class name and line number -->
<PatternLayout pattern="%C{1}.%M %m %ex%n"/>
<filters>
<MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
</Console>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<Property name="user">${sys:user.name}</Property>
<AppenderRef ref="File">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
</AppenderRef>
<AppenderRef ref="STDOUT" level="error"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Configuration with Properties
采取properties文件配置…
Property Substitution
Log4j 2支持在配置中将tokens指定为对其他地方定义的属性的引用。其中一些属性将在解释配置文件时解析,而其他属性可能会传递到将在运行时评估它们的组件。为此,Log4j使用Apache Commons Lang的 StrSubstitutor 和StrLookup 类的变体。以类似于Ant或Maven的方式,这允许声明为$ {name}的变量使用配置本身声明的属性来解决。例如,以下示例显示了正在声明为属性的滚动文件appender的文件名。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property>
</Properties>
<ThresholdFilter level="debug"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n"/>
<ThresholdFilter level="debug"/>
</Console>
<Routing name="Routing">
<Routes pattern="$${sd:type}">
<Route>
<RollingFile name="Rolling-${sd:type}" fileName="${filename}"
filePattern="target/rolling1/test1-${sd:type}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
</Route>
<Route ref="STDOUT" key="Audit"/>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="Routing"/>
</Logger>
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
虽然这很有用,但属性可能来自更多地方。为了适应这种情况,Log4j还支持语法$ {prefix:name}
,前缀标识告诉Log4j应该在特定的上下文中评估变量名称。有关更多详细信息,请参阅查找手册页面。Logj4内置的上下文是:
- bundle:资源包。格式是
$ {bundle:BundleName:BundleKey}
。软件包名称遵循软件包命名约定,例如:$ {bundle:com.domain.Messages:MyKey}
- ctx:线程上下文映射(MDC)
- date:使用指定的格式插入当前日期和/或时间
- env:系统环境变量。格式为
$ {env:ENV_NAME}
和$ {env:ENV_NAME:-default_value}
- jndi: 在默认JNDI上下文中设置的值。
- jvmrunargs:通过JMX访问JVM输入参数,但不是主要参数; 请参阅RuntimeMXBean.getInputArguments()。在Android上不可用
- log4j:Log4j配置属性。表达式$ {log4j:configLocation}和 $ {log4j:configParentLocation}分别为log4j配置文件及其父文件夹提供绝对路径。
- main:使用MapLookup.setMainArguments(String [])设置的值
- map:来自MapMessage的值
- sd:来自StructuredDataMessage的值。关键“id”将返回没有企业编号的StructuredDataId的名称。键“type”将返回消息类型。其他键将从地图中检索单个元素
- sys: 系统属性。格式为
$ {sys:some.property}
和$ {sys:some.property:-default_value}
默认的属性映射可以在配置文件中声明。如果该值无法位于指定的查找中,则将使用默认属性图中的值。默认映射预填充“hostName”的值,该值是当前系统的主机名或IP地址,“contextName”是当前日志记录上下文的值。
Lookup Variables with Multiple Leading ‘$’ Characters
$ handler …..
scripts
能够插入scrpits脚本处理
<Scripts>
<Script name="selector" language="javascript"><![CDATA[
var result;
if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
result = "NoLocation";
} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
result = "Flow";
}
result;
]]></Script>
<ScriptFile name="groovy.filter" path="scripts/filter.groovy"/>
</Scripts>
XInclude
xml配置能够包含其他的XInclude。这是个例子
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xi="http://www.w3.org/2001/XInclude"
status="warn" name="XIncludeDemo">
<properties>
<property name="filename">xinclude-demo.log</property>
</properties>
<ThresholdFilter level="debug"/>
<xi:include href="log4j-xinclude-appenders.xml" />
<xi:include href="log4j-xinclude-loggers.xml" />
</configuration>
Composite Configuration
log4j允许指定多个配置文件,然后混合合并成一个文件。
Status Messages
log4j能够进行故障排查,log4j-2.9之后的文件可以打开系统属性log4j2.debug
开关来打印调试log4j日志。
正如希望能够诊断应用程序中的问题一样,经常需要能够诊断日志记录配置或配置组件中的问题。由于日志尚未配置,因此初始化期间无法使用“正常”日志记录。此外,appender中的正常日志记录可能会创建无限递归,Log4j将检测并导致递归事件被忽略。为了适应这种需求,Log4j 2 API包含一个 StatusLogger。组件声明一个StatusLogger的实例,类似于:
protected final static Logger logger = StatusLogger.getLogger();
Testing in Maven
Maven可以在构建过程中运行单元和功能测试。默认情况下,放置在src/test/resources
中的任何文件都会自动复制到target/test-classes,并在执行任何测试期间包含在了类路径中。因此,将log4j2-test.xml
放入此目录将导致使用它而不是可能存在的log4j2.xml
或log4j2.json
。因此,测试期间可以使用不同的日志配置,而不是生产中使用的日志配置。
Log4j 2广泛使用的第二种方法是在junit测试类中用@BeforeClass
注释的方法中设置log4j.configurationFile
属性。这将允许在测试过程中使用任意命名的文件。
Log4j 2广泛使用的第三种方法是使用LoggerContextRule JUnit测试规则,该规则为测试提供了其他便利方法。这需要将 log4j-core 测试jar依赖项添加到测试作用域依赖项中。例如:
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
Log4j文档引用了许多可用于控制Log4j 2行为的各个方面的系统属性。下表列出了这些属性以及它们的默认值和它们控制的内容的描述。属性名称中的任何空格都是用于视觉流动的,应该删除。
请注意,从Log4j 2.10开始,所有系统属性名称都已经过标准化,以遵循一致的命名方案。虽然旧的属性名称仍支持向后兼容性,但建议更新配置以使用新样式。这个系统是可扩展的,并通过PropertySource 接口启用 。其他属性源类可以通过 Java SE中的标准ServiceLoader机制添加。
Web Applications and JSPs
Using Log4j 2 in Web Applications
在Java EE Web应用程序中使用Log4j或任何其他日志框架时,您必须特别小心。当容器关闭或Web应用程序被取消部署时,对日志资源进行适当清理(数据库连接关闭,文件关闭等)非常重要。由于Web应用程序中类加载器的性质,Log4j资源无法通过正常方式清理。当Web应用程序部署时必须“启动”Log4j,并在Web应用程序未使用时“关闭”。它的工作方式取决于您的应用程序是Servlet 3.0还是更新版本或 Servlet 2.5 Web应用程序。
无论哪种情况,您都需要将log4j-web模块添加到您的部署中,详见 Maven,Ivy和Gradle Artifacts手册页。
为了避免问题,当包含log4j-web jar时,Log4j关闭钩子将自动被禁用。
Configuration
Log4j允许使用log4jConfiguration 上下文参数在web.xml中指定配置文件。Log4j将通过以下方式搜索配置文件:
- 如果提供了一个位置,它将被搜索为一个servlet上下文资源。例如,如果 log4jConfiguration包含“logging.xml”,则Log4j将在Web应用程序的根目录中查找具有该名称的文件。
- 如果未定义位置Log4j将搜索以WEB-INF目录中的“log4j2”开头的文件。如果找到多个文件,并且存在以“log4j2- name ” 开头的文件,其中 name是Web应用程序的名称,则会使用它。否则,将使用第一个文件。
- 使用类路径和文件URL的“正常”搜索序列将用于查找配置文件。
Servlet 3.0 and Newer Web Applications
Servlet 3.0或者更新的应用程序版本就是<web-app>
的属性是3.0信息。在这个版本中,Log4j2能够自动检测并启动。主要是由Servlet 3.0版本中的ServletContainerInitializer的API处理,她可以在Web应用程序启动时动态注册相关的Filter和ServletConextListener类。
Log4j 2 Web JAR文件是配置为在应用程序中的任何其他Web碎片之前进行排序的Web碎片。它包含容器自动发现并初始化的ServletContainerInitializer (Log4jServletContainerInitializer)。这将Log4jServletContextListener和Log4jServletFilter添加到ServletContext。这些类正确初始化和取消初始化Log4j配置。
对于某些用户来说,自动启动Log4j是有问题的或不可取的。您可以使用isLog4jAutoInitializationDisabled上下文参数轻松禁用此功能。只需将其添加到您的部署描述符中,值为“true”即可禁用自动初始化。您必须在web.xml中定义上下文参数。如果以编程方式设置,Log4j检测设置就已经太迟了。
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
Servlet 2.5 Web Application
Servlet 2.5应用程序就是<web-app>
的属性是2.5信息。如果你是2.5版本或者你禁用了isLog4jAutoInitializationDisabled
上下文参数,那么你必须要配置Log4jServletContextListener和Log4jServletFilter在程序中。
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>
你同时可以自自定义这些listener和filter的行为,通过使用log4jContextName,log4jConfiguration,isLog4jContextSelectornamed等context params.
Context Params
默认地,Log4j 2使用ServletContext
的context name作为LoggerContext
的名称,并且使用标准的模式定位Log4j的配置文件。这里有3个上下文参数你可使用去控制这些行为。第一个参数是isLog4jContextSelectorNamed
,指定是否使用JndiContextSelector
选择上下文 。如果未指定isLog4jContextSelectorNamed
或者其他值不为true,则假定为false。
如果isLog4jContextSelectorNamed
为true,则必须指定log4jContextName
,或者必须在web.xml
中指定display-name
; 否则,应用程序将无法启动,出现异常。log4jConfiguration
应也可在这种情况下指定的,并且必须是对配置文件的有效URI; 但是,该参数不是必需的。
如果isLog4jContextSelectorNamed
不为true,则可以选择指定log4jConfiguration
,并且必须是配置文件的有效URI或路径,或者以“classpath:”开头以表示可以在类路径中找到的配置文件。如果没有这个参数,Log4j将使用标准机制来查找配置文件。
在指定这些上下文参数时,即使在Servlet 3.0或应用程序中,也必须在部署描述符(web.xml
)中指定它们。如果将它们添加到侦听器中的ServletContext
中,Log4j将在上下文参数可用之前进行初始化,并且它们将不起作用。以下是这些上下文参数的一些示例用途。
Set the Logging Context Name to "myApplication"
<context-param>
<param-name>log4jContextName</param-name>
<param-value>myApplication</param-value>
</context-param>
Set the Configuration Path/File/URI to "/etc/myApp/myLogging.xml"
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///etc/myApp/myLogging.xml</param-value>
</context-param>
Use the JndiContextSelector
<context-param>
<param-name>isLog4jContextSelectorNamed</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>log4jContextName</param-name>
<param-value>appWithJndiSelector</param-value>
</context-param>
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///D:/conf/myLogging.xml</param-value>
</context-param>
Using Web Application Information During the Configuration
您可能想在配置期间使用有关Web应用程序的信息。例如,您可以将Web应用程序的上下文路径嵌入到Rolling File Appender的名称中。请参阅Lookups中的 WebLookup以 获取更多信息。
Javaserver Pages Logging
在jsp中可以直接使用log4j,如果为了界面不能使用这些,可以采取专门的log4j标签去处理。
Asynchronous Requests and Threads
log4j的Log4jServletFilter一般是绑定线程的请求到LoggerContext当中,遇到这种Servlet 3.0支持的异步请求,就需要进行特殊处理了。
Using the Servlet Appender
Log4j提供了一个Servlet Appender,它使用servlet上下文作为日志目标。例如:
<Configuration status="WARN" name="ServletTest">
<Appenders>
<Servlet name="Servlet">
<PatternLayout pattern="%m%n%ex{none}"/>
</Servlet>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Servlet"/>
</Root>
</Loggers>
</Configuration>
为避免对servlet上下文的异常事件进行双重记录,您必须在您的PatternLayout中使用%ex {none}, 如示例中所示。该消息文本中将省略该异常,但将其作为实际的Throwable对象传递给Servlet上下文
Lookups
lookups提供了一种方式将值传递给Log4j配置文件。下面有一部分的插件实现了StrLookup接口。
Context Map Lookup
ContextMapLookup允许程序将数据存储到Log4j的ThreadContext Map中,之后他们会在配置文件中尝试加载Log4j的配置文件。以下就是个例子,程序设置当前用户的user登录id到ThreadContext Map中去,这个key是“loginId”,当配置初始化时,第一个’$’将会被移除。PatternLayout支持查找插值,然后解析每个事件的变量。请注意,模式“%X {loginId}”将获得相同的结果。
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${ctx:loginId} %m%n</pattern>
</PatternLayout>
</File>
Date Loopup
DateLookup与其他查找有些不同寻常,因为它不使用键来定位项目。相反,该键可用于指定对SimpleDateFormat有效的日期格式字符串 。当前日期或与当前日志事件关联的日期将按指定格式化。
<RollingFile name="Rolling-${map:type}" fileName="${filename}" filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
Environment Lookup
EnvironmentLookup允许系统在全局文件(如/ etc / profile)或应用程序的启动脚本中配置环境变量,然后从日志记录配置中检索这些变量。下面的示例包含应用程序日志中当前登录的用户的名称
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${env:USER} %m%n</pattern>
</PatternLayout>
</File>
该查找还支持默认值语法。在下面的示例中,当USER环境变量未定义时,使用默认值jdoe:
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${env:USER:-jdoe} %m%n</pattern>
</PatternLayout>
</File>
Java Lookup
JavaLookup允许使用java:
前缀以方便的预格式化字符串检索Java环境信息。
<File name="Application" fileName="application.log">
<PatternLayout header="${java:runtime} - ${java:vm} - ${java:os}">
<Pattern>%d %m%n</Pattern>
</PatternLayout>
</File>
Jndi Lookup
JVM Input Arguments Lookup(JMX)
Log4j Configuration Location Lookup
Log4j配置属性。表达式$ {log4j:configLocation}
和$ {log4j:configParentLocation}
分别为log4j配置文件及其父文件夹提供绝对路径。
<File name="Application" fileName="${log4j:configParentLocation}/logs/application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
Main Arguments Lookup(Application)
这个lookup需要你手动的提供应用程序参数给Log4j:
import org.apache.logging.log4j.core.lookup.MainMapLookup;
public static void main(String args[]) {
MainMapLookup.setMainArguments(args);
...
}
如果主参数已设置,则此查找允许应用程序从日志记录配置中检索这些主参数值。main:前缀后面的关键字可以是从参数列表中的基于0的索引,也可以是一个字符串,其中$ {main:myString}由主参数列表中的myString后面的值替换 。
Map Lookup
这个MapLookup有以下几个目的。
- 提供配置文件声明的基本Properties。
- 在LogEvents中的MapMessages检索values。
- 通过MapLookup.setMainArguments(String [])来检索数值
Marker Lookup
Structured Data Lookup
System Properties Lookup
由于使用系统属性定义应用程序内部和外部的值是很常见的,所以它们应该可以通过查找来访问是很自然的。由于系统属性通常是在应用程序之外定义的,因此会看到如下所示的常见情况:
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath}/app.log"/>
</Appenders>
这个lookup还支持默认的value语法。当logPath没有定义时,将使用默认值/var/logs
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
</Appenders>
Web Lookup
WebLookup允许应用程序检索与ServletContext关联的变量。除了能够检索ServletContext中的各个字段外,WebLookup还支持查找作为属性存储的值或配置为初始化参数。
首先检查指定的任何其他键名称,以查看是否存在具有该名称的ServletContext属性,然后检查该名称的初始化参数是否存在。如果找到该键,则会返回相应的值。
<Appenders>
<File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
</Appenders>
Appenders
Appender负责提供LogEvents到目的地。每个Appender必须实现Appender 接口。大多数Appender将扩展 AbstractAppender ,它增加了Lifecycle 和Filterable 支持。生命周期允许组件在配置完成后完成初始化并在关闭期间执行清理。Filterable允许组件在事件处理过程中评估附加的过滤器。
Appender通常只负责将事件数据写入目标目标。在大多数情况下,他们将格式化事件的责任委托给布局。一些appender会包装其他appender,以便他们可以修改LogEvent,处理Appender中的故障,根据高级过滤标准将事件路由到下级Appender,或者提供类似的功能,而不直接格式化事件以供查看。
Appender总是有一个名字,以便它们可以从记录器中引用。
在下表中,“类型”列对应于预期的Java类型。对于非JDK类,除非另有说明,否则这些类通常应该位于Log4j Core中。
AsyncAddpender
CassandraAppender
ConsoleAppender
正如人们所预料的那样,ConsoleAppender将其输出写入System.out或System.err,而System.out是默认目标。必须提供布局来格式化LogEven
- filter:一个过滤器确定是否应该有这个Appender处理事件,可以使用CompositeFilter多个。
- layout:格式化LogEvent时间,如果没有提供,默认是”%m%n”格式。
- follow:标识appender是否通过配置后通过System.setOut或System.setErr重新分配System.out或System.err。请注意,跟随属性不能用于Windows上的Jansi。不能直接使用
- direct:直接写入
java.io.FileDescritor
,不经过java.lang.System.out/.err
,能够提供十倍的性能,但是仅仅测试阶段。 - name:Appender的名称
- ignoreExceptions:默认true。导致追加事件被内部记录并被忽略时遇到异常。当设置为false时,异常将被传播给调用者。将此Appender包装在FailoverAppender中时, 必须将其设置为false
- target:取值”SYSTEM_OUT“或”SYSTEM-ERR”。默认”SYSTEM_OUT”
典型的例子:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
FailoverAppender
FailoverAppender包装一组appender。如果主Appender失败,次要appender将按顺序尝试,直到成功或者没有更多的次要尝试。
- filrer:过滤器决定事件是否应该由Appender处理。多个处理器可以使用CompositeFilter
- primary:主要的Appender被使用
- failovers:其他的Appender被使用
- name:Appender名称
- retryIntervalSeconds:尝试多少间隔时间去使用主要的Appender,默认60s
- ignoreExceptions:默认true,缺省值为true,导致追加事件被内部记录并被忽略时遇到异常。当设置为false时,异常将被传播给调用者
- target:取值”SYSTEM_OUT“或”SYSTEM-ERR”。默认”SYSTEM_OUT”
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
<Console name="STDOUT" target="SYSTEM_OUT" ignoreExceptions="false">
<PatternLayout pattern="%m%n"/>
</Console>
<Failover name="Failover" primary="RollingFile">
<Failovers>
<AppenderRef ref="Console"/>
</Failovers>
</Failover>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Failover"/>
</Root>
</Loggers>
</Configuration>
FileAppender
FileAppender是一个OutputStreamAppender,它写入fileName参数中指定的File。FileAppender使用FileManager(它扩展了OutputStreamManager)来实际执行文件I / O。虽然来自不同配置的FileAppender不能共享,但如果Manager可访问,FileManagers可以是。例如,如果Log4j处于两个公共的ClassLoader中,那么servlet容器中的两个Web应用程序可以拥有自己的配置并安全地写入同一文件。
- Append:默认true。文件将会被追加记录。如果是false,那么将会清空文件再进行记录
- bufferedIO:默认true。记录将写入缓冲区,并且在缓冲区已满或设置了immediateFlush时写入记录时将数据写入磁盘。文件锁定不能用于bufferedIO。性能测试表明,即使启用了immediateFlush,使用缓冲的I / O也可显着提高性能。
- bufferSize:当bufferedIO时true时,这是buffer的大小,默认是8192bytes
- createOnDemand:appender按需创建文件。appender只在日志事件通过所有过滤器并且路由到此appender时创建文件。默认为false。
- filter:事件的过滤器
- fileName:文件名称。如果文件或者父类目录不存在,那么将会创建
- immediateFlush:当设置true—默认值,每一次的写入都被刷新。这将保证数据写入磁盘,但可能会影响性能。每次写入后刷新仅在与同步记录器一起使用此appender时有用。即使将immediateFlush设置为false,异步记录器和appender也会在一批事件结束时自动刷新。这也保证数据写入磁盘,但效率更高。
- layout:LogEvent的格式化布局。没有提供时,将使用默认的”%m%n”
- locking:当设置为true时,I / O操作仅在保持文件锁定的情况下发生,允许多个JVM中的FileAppender和潜在的多个主机同时写入同一文件。这将显着影响性能,因此应谨慎使用。此外,在许多系统上,文件锁定是“建议的”,这意味着其他应用程序可以在不获取锁定的情况下对文件执行操作。默认值是false
- name:Appender的名称
- ignoreExceptions:默认true。导致追加事件被内部记录并被忽略时遇到异常。当设置为false时,异常将被传播给调用者。将此Appender包装在FailoverAppender中时, 必须将其设置为false
- filePermissions:每次创建文件时都应用POSIX格式的文件属性权限。底层文件系统应支持POSIX文件属性视图。例如:rw ———-或rw-rw-rw-等…
- fileOwner:文件拥有者去定氮仪是否这个文件应该被创建。
- fileGroup:文件组去定义这个文件是否该创建。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
FlumeAppender
Apache Flume是一个分布式,可靠且可用的系统,用于高效地收集,汇总和将来自多个不同源的大量日志数据移动到集中式数据存储。FlumeAppender将LogEvent作为序列化的Avro事件发送给Flume代理以供消耗。
JDBCAppender
JDBCAppender使用标准JDBC将日志事件写入关系数据库表。它可以配置为使用JNDI DataSource或自定义factory method获取JDBC连接。无论采用哪种方式,它都必须由连接池支持。否则,记录性能将受到很大影响。如果配置的JDBC驱动程序支持批处理语句,并且将 bufferSize配置为正数,则会对批处理事件进行批处理。请注意,从Log4j 2.8开始,有两种方法可以将日志事件配置为列映射:原始的ColumnConfig 样式只允许字符串和时间戳,而新的ColumnMapping插件,它使用Log4j的内置类型转换来允许更多数据类型(这与Cassandra Appender中的插件相同 )。
要在开发过程中快速起步,使用基于JNDI的连接源的替代方法是使用非共享的DriverManager连接源。此连接源使用JDBC连接字符串,用户名和密码。或者,您也可以使用属性。
- name:required,Appender的名称
- ignroeExceptions:默认true。在追加事件以记录内部日志时候,忽略遇到的异常。当设置为false时,异常将会被传播到调用者。你必须设置为false当你使用FailoverAppender时候。
- filter:过滤器
- bufferSize:如果大于0,那么当住家buffer日志时,如果buffer达到了这个大小,就会被刷新纪录。
- connecitonSource:required。哪个数据库应该被连接。
- tableName:required。插入的表名
- columnConfigs:required(and/or columnMappings)记录这些列,这些logEvent应该如何插入数据,需要多个column属性。
- columnMappings:requred(and/or columnConfigs)列映射配置的列表。每列必须指定一个列名称。每列可以有一个由其全限定类名指定的转换类型。默认情况下,转换类型是字符串。如果配置的类型与ReadOnlyStringMap / ThreadContextMap 或 ThreadContextStack分配兼容 ,则该列将分别填充MDC或NDC(这是数据库特定的,它们如何处理插入Map或List值)。如果配置的类型与java.util.Date分配兼容,则日志时间戳将转换为该配置的日期类型。如果配置的类型与java.sql.Clob 或java.sql.NClob是分配兼容的,那么格式化的事件将分别设置为Clob或NClob(类似于传统的ColumnConfig插件)。如果给定了文字属性,那么它的值将在INSERT查询中按原样使用,而不会进行任何转义。否则,指定的布局或模式将转换为配置的类型并存储在该列中。
当配置JDBCAppender时,你必须确定ConnectionSource
实现。必须要指定以下几个元素中的一个:
- Datasource:Uses JNDI
- ConnectionFactory:方法去提供连接
- DriverManager:快速直接的提供连接。没有连接池
- PoolingDriver:使用Apache的Commons DBCP去提供这个连接
其他几个连接方式见网站,此处仅仅列出ConnectionFactory参数:
- class:requred。类的全限量名称饱饭了一个静态的工厂方法来提供JDBC的连接
- method:requred。静态工厂的名称。这个方法必须没有参数,并且返回类型是
java.sql.Connection
或者Datasource
.如果方法返回Connection s,它必须从连接池中获取它们(并且在Log4j完成时它们将返回到池中); 否则,日志会很慢。如果该方法返回一个DataSource,那么DataSource将只被检索一次,并且由于相同的原因它必须由连接池支持。
Column参数:
- name:requred,数据库的列名称
- pattern:使用此属性可以使用PatternLayout模式在此列中的日志事件中插入一个或多个值 。只需在该属性中指定任何合法模式即可。必须指定此属性,literal或isEventTimestamp =“true”,但不得超过其中一个
- parameter:使用这个属性插入一个表达式当参数中含有?参数时。该值将直接包含在插入SQL中,而不进行任何引用(这意味着如果您希望它是一个字符串,那么您的值应该包含单引号,如下所示:
<ColumnMapping name =“instant”parameter =“TIMESTAMPADD('MILLISECOND',?,TIMESTAMP'1970-01-01')”/>
- iseventTimestamp:使用此属性将事件时间戳记插入此列中,该列应该是SQL日期时间。该值将作为java.sql.Types.TIMESTAMP插入。必须指定此属性(等于 true),模式或isEventTimestamp,但不能超过其中一个
- isUnicode:除非指定了模式,否则该属性将被忽略。如果为true或省略(默认),则该值将作为unicode插入(setNString或setNClob)。否则,该值将被插入非Unicode(setString或setClob)
- isClob:除非指定了模式,否则该属性将被忽略。使用此属性可指示该列存储字符大对象(CLOB)。如果为true,则该值将作为CLOB(setClob或setNClob)插入。如果为false或省略(默认),则该值将作为VARCHAR或NVARCHAR(setString或setNString)插入。
ColumnMapping参数:
- name:required,数据库列的名称
- pattern:使用此属性可以使用PatternLayout模式在此列中的日志事件中插入一个或多个值 。只需在该属性中指定任何合法模式即可。必须指定此属性,文字或isEventTimestamp =“true”,但不得超过其中一个。
- literal:使用此属性可在此列中插入文字值。
- layout:LogEvent的格式布局
- type:转化类型名称,全限量的类名称
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JDBC name="databaseAppender" tableName="LOGGING.APPLICATION_LOG">
<ConnectionFactory class="net.example.db.ConnectionFactory" method="getDatabaseConnection" />
<Column name="EVENT_ID" literal="LOGGING.APPLICATION_LOG_SEQUENCE.NEXTVAL" />
<Column name="EVENT_DATE" isEventTimestamp="true" />
<Column name="LEVEL" pattern="%level" />
<Column name="LOGGER" pattern="%logger" />
<Column name="MESSAGE" pattern="%message" />
<Column name="THROWABLE" pattern="%ex{full}" />
</JDBC>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
JMS Appender
JPA Appender
Http Appender
Kafka Appender
MemoryMappedFile Appender
NoSQL Appender
NoSQL Appender for MongoDB
NoSQL Appender for MongoDB 2
NoSQL Appender for MongoDB 3
NoSQL Appender for Apache CouchDB
OutputStreamAppender
OutputStreamAppender为许多其他Appender提供基础,例如将事件写入输出流的File和Socket appender。它不能直接配置。OutputStreamAppender提供对immediateFlush和buffering的支持。OutputStreamAppender使用OutputStreamManager处理实际的I / O,允许Appender在多种配置中共享该流。
RandomAccessFileAppender
RandomAccessFileAppender与标准FileAppender相似, 除了它始终被缓冲(不能关闭),并且它在内部使用 ByteBuffer + RandomAccessFile 而不是 BufferedOutputStream。与我们测量中的 “bufferedIO = true”的FileAppender相比,我们看到了20-200%的性能提升 。类似于FileAppender,RandomAccessFileAppender使用RandomAccessFileManager来实际执行文件I / O。虽然来自不同配置的RandomAccessFileAppender不能共享,但如果Manager可以访问,则可以使用RandomAccessFileManagers。例如,如果Log4j处于两个公共的ClassLoader中,那么servlet容器中的两个Web应用程序可以拥有自己的配置并安全地写入同一文件。
- append:默认是true,追加文件最后记录。设置为false将会清空文件并重新写入
- fileName:文件名称,如果不存在父级目录或者自己,将会创建
- filters:过滤器
- immediateFlush:当设置为true时 - 默认情况下,每次写入后都会进行刷新。这将保证数据写入磁盘,但可能会影响性能。每次写入后刷新仅在与同步记录器一起使用此appender时有用。即使将immediateFlush设置为false,异步记录器和appender也会在一批事件结束时自动刷新。这也保证数据写入磁盘,但效率更高。
- BufferSize:buffer的大小,默认是256*1024bytes
- layout:LogEvent的布局。默认的%m%n将会被使用
- name:appender的名称
- ignoreExceptions:默认为true,同上配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RandomAccessFile name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</RandomAccessFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
RewriteAppender
RewriteAppender允许LogEvent在被另一个Appender处理之前进行操作。这可以用来屏蔽密码等敏感信息或将信息注入每个事件。RewriteAppender必须配置一个RewritePolicy。RewriteAppender应该在它引用的任何Appender之后进行配置,以允许其正确关闭。
RewritePolicy
RewritePolicy是一个接口,允许实现在传递给Appender之前检查并可能修改LogEvent。RewritePolicy声明了一个必须实现的名为rewrite的方法。该方法通过LogEvent并可以返回相同的事件或创建一个新的。
- AppenderRef:在LogEvent被操作后要调用的Appender的名称。可以配置多个AppenderRef元素。
- filter:一个过滤器来确定是否应该由这个Appender处理事件。使用CompositeFilter可以使用多个Filter。
MapRewritePolicy
MapRewritePolicy将评估包含MapMessage的LogEvents,并将添加或更新Map的元素。