首先声明本文并不教您怎么用log4j2,仅仅只对<Appenders>中常用的子节点进行简单说明。
要看懂本文需要对log4j2有一定的了解,至少能够知道<Appenders>、<Layouts>和<Loggers>的区别。
本文主要参考对象为log4j2官方手册:《Apache Log4j 2 v. 2.1 User's Guide》,但是鉴于官方手册的不少细节描述得并不是非常清楚,甚至还有错误,所以还希望大家自己多试验,毕竟如果官方文档有错误或写得不清楚,我也没办法。
---------------------------------------------这是一条分割线,以下是正文---------------------------------------------------
Appender控制log4j2的输出,有非常多的节点可选,包括:<Async>、<Console>、<Failover>、<File>、<Flume>、<JDBC>、<JMS>、<JPA>、<MemoryMappedFile>、<NoSQL>、<RandomAccessFile>、<Rewrite>、<RollingFile>、<RollingRandomAccessFile>、<Routing>、<SMTP>、<Socket>、<Syslog>,本文只简单介绍最常见的Console、File、RollingFile,提及一下JDBC,其他的都不涉及。
1. <Console>节点
ConsoleAppender将输出结果写到System.err或System.out。默认是System.err。必须要包含用来格式化LogEvent的Layout元素。下面是该节点的属性。注意,是属性,不是子节点。
参数名 |
类型 |
描述 |
filter |
Filter |
判断当前日志事件是否由这个appender来处理。当使用CompositeFilter时,可以使用多个filter |
layout |
Layout |
格式化LogEvent的Layout。如果没指定,则按照%m%n输出。 |
name |
String |
Appender的name。用于Logger节点引用。 |
ignoreException |
Boolean |
ture:内部记录并忽略发生的异常。false:抛出给调用者。默认为ture。如果要将当前appender封装成FailoverAppender,必须要设置为false |
targer |
String |
SYSTEM_OUT或SYSTEM_ERR。默认是SYSTEM_OUT(文档说默认是SYSTEM_ERR,但经我测试默认应该是SYSTEM_OUT)。对于Eclipse来说SYSTEM_OUT是作为普通信息输出,是黑色字体;SYSTEM_ERR作为错误日志输出,是红色字体。 |
2. <File>节点
File即将结果输出到一个指定文件中。下面是该节点的属性。注意,是属性,不是子节点。
参数名 |
类型 |
描述 |
append | boolean | 是否追加,默认为ture。ture是将新日志追加到原日志文件尾部,false则是删除已有文件,重建新文件。 |
bufferIO |
boolean |
默认为true:将数据写入到缓存,缓存满了才写入到磁盘 |
bufferSize |
int |
默认为8192bytes |
filter |
Filter |
判断当前事件是否该这个appender来处理。当使用CompositeFilter时,可以使用多个filter |
filename |
String |
写入的文件名。不存在的文件名和路径名都会自动创建 |
immediateFlush |
boolean |
不经过缓存,直接将日志写入磁盘,对性能影响较大。 |
layout |
Layout |
格式化LogEvent的Layout。 |
locking |
boolean |
锁文件,是否允许并发写入。默认为false,即几个事件可以一起写。true对性能影响很大。 |
name |
String |
Appender的name。 |
ignoreExceptions |
boolean |
ture:内部记录并忽略发生的异常。false:抛出给调用者。默认为ture。如果要将当前appender封装成FailoverAppender,必须要设置为false |
RollingFile和File一样,都是将日志写入到文件中,但File对文件的约束很简单,而RollingFile则较为灵活,比如多大文件时分拆,最多可以分拆成几个文件等等。另外,RollingFile需要触发条件。
触发条件包括:
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20MB" />
<TimeBasedTriggeringPolicy />
</Policies>
OnStartupTriggeringPolicy没有参数,每次JVM重新运行都会触发。
SizeBasedTriggeringPolicy则是由文件大小触发,单位可以是KB/MB/GB。
TimeBasedTriggeringPolicy则是根据日期、时间来触发,例如每隔几个小时重写一次文件。不过文档关于这个节点的描述非常简陋,我这也没什么好写的。
另外还有<DefaultRolloverStrategy>控制保存文件的规则,比如最多保存多少个文件,旧文件的保存规则,文件压缩级别。这个参数理解得有些问题,因此有需要用到的看官请自行翻阅官方手册。
4. <JDBC>节点
使用标准JDBC将日志写到库里。既可以用JNDI,也可以用自定义的工厂方法。请一定使用连接池,否则对性能的拖累会让人崩溃。
Parameter Name |
Type |
Description |
name |
String |
必须的。Appender的name。 |
ignoreExceptions |
boolean |
ture:内部记录并忽略发生的异常。false:抛出给调用者。默认为ture。如果要将当前appender封装成FailoverAppender,必须要设置为false |
filter |
Filter |
判断当前事件是否该这个appender来处理。当使用CompositeFilter时,可以使用多个filter |
bufferSize |
int |
官方文档无有用信息,猜测大小默认为0,单位为byte。 |
connectionSource |
ConnectionSource |
必须的。包含<DataSource>或<ConnectionFactory>节点。 |
tableName |
String |
必须的。 |
columnConfigs |
ColumnConfig[] |
必须的。这个参数官方文档没有提供任何有意义的内容,且官方的例子中也并没有包含这个参数,因此并不是必须的。所以我猜测官方文档写错了,其实不应该有此参数。 |
<DataSource>节点:
Parameter Name |
Type |
Description |
jndiName |
String |
必须的。使用完整的JNDI前缀,如java:/comp/env/jdbc/LoggingDatabase。请一定指向一个连接池,否则速度会非常慢。 |
<ConnectionFactory>节点
Parameter Name |
Type |
Description |
class |
Class |
必须的。一个有能获得JDBC连接的静态工厂方法的完整类名。 |
method |
Method |
必须的。获得JDBC连接的静态工厂方法名。该方法必须无参,且返回类型只能是java.sql.Connection或DataSource。无论如何都请从连接池取连接,否则会非常慢。 |
<Column>节点使用PreparedStatement将数据插入数据库的指定列,以防止SQL注入。该节点如下:
Parameter Name |
Type |
Description |
name |
String |
必须的。插入列的列名 |
pattern |
String |
按照PatternLayout规定的格式获取并插入数据。pattern、literal、isEventTimestamp=”true”必须指定一个且只能指定一个。 |
literal |
String |
插入文字,引号包含,可用于引用Oracle的自增字段。pattern、literal、isEventTimestamp=”true”必须指定一个且只能指定一个。 |
isEventTimestamp |
boolean |
插入java.sql.Types.TIMESTAMP类型的时间戳。pattern、literal、isEventTimestamp=”true”必须指定一个且只能指定一个。 |
isUnicode |
boolean |
如果没有patter,该属性将被忽略。默认为ture,作为unicode插入,否则为non-unicode。 |
isClob |
boolean |
如果没有pattern,该属性将被忽略。true则作为CLOB插入,否则作为varchar或nvarchar插入 |