1.配置
将日志代码嵌入到程序代码中需要大量的规划和工作。调查表明,程序代码中约有4%的日志记录代码。因此,即使是中等大小的应用程序,其代码中也会嵌入数千个日志记录语句。鉴于它们的数量,管理这些日志语句而不必手动修改它们变得越来越有必要。
Log4j 2 的配置可以通过以下 4 种方式中的 1 种方式完成:
通过以 XML、JSON、YAML 或属性格式编写的配置文件。 以编程方式,通过创建配置设置和配置实现。
以编程方式,通过调用配置界面中公开的 API,将组件添加到默认配置中。 以编程方式,通过调用内部 Logger 类上的方法。
本页主要介绍如何通过配置文件配置 Log4j。有关以编程方式配置 Log4j 的信息,请参阅扩展 Log4j 2和编程 Log4j 配置。
所有可用格式在功能上都是等效的。例如,可以使用属性格式(反之亦然)重写 XML 中的配置文件,而不会丢失任何功能。但是,Log4j配置的分层性质可以更好地捕获自然支持嵌套的格式,因此XML,JSON和YAML文件通常更易于使用。
请注意,与 Log4j 1.x 不同,公共 Log4j 2 API 不会公开用于添加、修改或删除追加器和筛选器的方法,也不会以任何方式操作配置。
2.配置架构
由于添加了对XML文件的支持,Log4j的配置被反映为树结构。事实上,每个配置方式(包括 ConfigurationBuilder)都会为每个配置元素生成一个 Node。节点是一个相当简单的结构,包含一组属性、一组子节点和一个 PluginType。重要的是要注意,每个节点都必须有一个相应的插件,因为插件是实际执行节点所代表的工作的组件。
Log4j支持的每个文档类型都有一个配置库。工厂本身是一个Log4j插件,它声明它支持哪些文件扩展名以及它的优先级是什么。属性具有最高的优先级,值为 8,后跟 yaml、json 和 xml。执行自动配置时,Log4j将调用这些工厂中的每一个,以确定哪些(如果有)支持指定的配置文件格式。如果找到工厂将创建相应的 Configuratoin 对象,并将对配置数据的引用传递给它。
每个配置实现(如 XMLConfiguration、YamlConfiguration、JsonConfiguration 等)的主要任务是将配置文本转换为 Node 树,通常是使用适用于该文档类型的任何工具解析文本。应该注意的是,虽然大多数受支持的文档类型都是固有的树状结构,但Java属性语法却不是。由于需要将语法转换为节点树,因此Log4j使用的Java属性语法要求所有属性都遵循使树结构清晰的命名模式。因此,Java 属性格式往往比使用其他文档类型更冗长。
创建节点树后,控制权将委托给抽象配置,后者使用Log4j的插件系统将节点转换为各自的Java对象,并提供所有常见功能。
3.仲裁器
两种情况:
1. 开发环境与生产环境需要不同的日志记录级别
2. 本机与生产环境的输出源(appender)不同
处理办法:
1. 使用像Spring Cloud Config Server这样的工具,它可以感知环境,并为不同的环境提供不同的配置文件
2. 在配置文件中包含仲裁器
仲裁器是一个Log4j插件,其任务是确定是否应将其他已配置的元素包含在生成的配置中。仲裁器在构建节点树之后,将树转换为配置之前执行。仲裁服务器是节点本身,在处理树之前,它始终从节点树中删除。仲裁服务器真正要做的就是提供一个返回布尔结果的方法,该结果确定仲裁服务器的子节点是应保留在配置中还是应被修剪。
仲裁器可能发生在配置中允许元素的任何位置。因此,Aribiter可以封装一些简单的东西,比如单个属性声明或一整套追加器或记录器。仲裁者也可以嵌套,尽管作为另一个仲裁者的后代的仲裁者只有在祖先返回 true 时才会被评估。仲裁服务器的子元素必须是仲裁服务器父元素的任何元素的有效元素。
此示例显示了配置的两个仲裁器,它们将包括控制台追加器或列表追加器,具体取决于 env 系统属性的值是"dev"还是"prod"。
<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
<Appenders>
<SystemPropertyArbiter propertyName="env" propertyValue="dev">
<Console name="Out">
<PatternLayout pattern="%m%n"/>
</Console>
</SystemPropertyArbiter>
<SystemPropertyArbiter propertyName="env" propertyValue="prod">
<List name="Out">
</List>
</SystemPropertyArbiter>
</Appenders>
<Loggers>
<Logger name="org.apache.test" level="trace" additivity="false">
<AppenderRef ref="Out"/>
</Logger>
<Root level="error">
<AppenderRef ref="Out"/>
</Root>
</Loggers>
</Configuration>
通常,仲裁者的行为与其他仲裁者无关。也就是说,一个仲裁器的结果不会影响任何其他仲裁者。当您只想使用一组选项之一时,这可能会很麻烦。在这种情况下,可以使用名为"Select"的特殊插件。"选择"下的每个元素都必须是仲裁服务器。返回真值的第一个仲裁器将是使用的其他仲裁服务器。如果没有仲裁服务器返回 true,则可以使用默认配置元素配置默认仲裁器。DefaultArbiter 是始终返回 true 的仲裁器,因此在 Select 之外使用它将导致其配置的元素始终被包含,就好像它不存在一样。
此示例显示了一个仲裁服务器,该仲裁服务器使用驻留在单独文件中的 Javascript 来确定是否包括控制台追加器。如果结果为 false,则将包含列表追加器。
<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
<Appenders>
<Select>
<ScriptArbiter>
<ScriptFile language="JavaScript" path="src/test/resources/scripts/prodtest.js" charset="UTF-8" />
<Console name="Out">
<PatternLayout pattern="%m%n"/>
</Console>
</ScriptArbiter>
<DefaultArbiter>
<List name="Out">
</List>
</DefaultArbiter>
</Select>
</Appenders>
<Loggers>
<Logger name="org.apache.test" level="trace" additivity="false">
<AppenderRef ref="Out"/>
</Logger>
<Root level="error">
<AppenderRef ref="Out"/>
</Root>
</Loggers>
</Configuration>
4.自动配置
Log4j能够在初始化期间自动配置自身。当Log4j启动时,它将找到所有配置工具插件,并按从高到低的加权顺序排列它们。交付时,Log4j 包含四个 ConfigurationFactory 实现:一个用于 JSON,一个用于 YAML,一个用于属性,一个用于 XML。
Log4j 将检查"log4j2.configurationFile"系统属性,如果设置,将尝试使用与文件扩展名匹配的
ConfigurationFactory 加载配置。请注意,这不限于本地文件系统上的某个位置,并且可能包含 URL。如果未设置任何系统属性,则属性 ConfigurationFactory 将在类路径中查找 log4j2-test.properties。 如果未找到此类文件,YAML ConfigurationFactory 将在类路径中查找
log4j2-test.yaml 或 log4j2-test.yml。如果未找到此类文件,JSON ConfigurationFactory 将在类路径中查找 log4j2-test.json 或 log4j2-test.jsn。
如果未找到此类文件,XML 配置器将在类路径中查找 log4j2-test.xml。
如果找不到测试文件,则属性 ConfigurationFactory 将在类路径上查找 log4j2.properties。
如果找不到属性文件,YAML ConfigurationFactory 将在类路径上查找 log4j2.yaml 或 log4j2.yml。
如果找不到 YAML 文件,JSON ConfigurationFactory 将在类路径上查找 log4j2.json 或 log4j2.jsn。
如果找不到 JSON 文件,XML 配置库将尝试在类路径上找到 log4j2.xml。
如果找不到配置文件,则将使用默认配置。这将导致日志记录输出转到控制台。
一个名为MyApp的示例应用程序使用log4j来说明如何做到这一点。
import com.foo.Bar;
// Import log4j classes.
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class MyApp {
// Define a static logger variable so that it references the
// Logger instance named "MyApp".
private static final Logger logger = LogManager.getLogger(MyApp.class);
public static void main(final String... args) {
// Set up a simple configuration that logs on the console.
logger.trace("Entering application.");
Bar bar = new Bar();
if (!bar.doIt()) {
logger.error("Didn't do it.");
}
logger.trace("Exiting application.");
}
}
MyApp首先导入log4j相关的类。然后,它定义一个名为 MyApp 的静态记录器变量,该变量恰好是该类的完全限定名称。
MyApp 使用 packagecom.foo 中定义的 Bar 类。
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将提供默认配置。默认配置类中提供的默认配置将设置:
- 连接到根记录器的控制台输出源。
- 将 PatternLayout设置为模式 “%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n” 附加到 ConsoleAppender
请注意,默认情况下,Log4j 将根记录器分配给 Level.ERROR。
MyApp 的输出类似于:
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] ERROR MyApp - Didn't do it.
如前所述,Log4j将首先尝试从配置文件配置自身。与默认值等效的配置如下所示:
<?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>
一旦将上述文件作为log4j2放入类路径中.xml您将获得与上面列出的结果相同的结果。将根级别更改为跟踪将导致类似于以下内容的结果:
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.
请注意,使用默认配置时,状态日志记录处于禁用状态。
5.可加性
也许希望从除 com.foo.Bar 之外的所有内容中删除所有TRACE输出。简单地更改日志级别将无法完成任务。相反,解决方案是将新的记录器定义添加到配置中:
<Logger name="com.foo.Bar" level="TRACE"/>
<Root level="ERROR">
<AppenderRef ref="STDOUT">
</Root>
使用此配置时,将记录来自 com.foo.Bar 的所有日志事件,而仅记录来自所有其他组件的错误事件。
在前面的示例中,com.foo.Bar 中的所有事件仍写入控制台。这是因为 com.foo.Bar 的记录器没有配置任何追加器,而其父级配置了任何追加器。实际上,以下配置
<?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>
将导致
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.
请注意,来自 com.foo.Bar 的跟踪消息出现两次。这是因为首先使用与记录器 com.foo.Bar 关联的追加器,这会将第一个实例写入控制台。接下来,引用 com.foo.Bar 的父级(在本例中为根记录器)。然后,该事件将传递到其追加器,追加器也会写入控制台,从而生成第二个实例。这称为可加性。虽然可加性可能是一个非常方便的功能(如在前面的第一个示例中,不需要配置追加器引用),但在许多情况下,此行为被认为是不可取的,因此可以通过将记录器上的可加性属性设置为 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>
一旦事件到达记录器并将其加性设置为 false,则事件将不会传递给其任何父记录器,无论其加性设置如何。
6. 自动重新配置
从文件配置时,Log4j能够自动检测对配置文件的更改并重新配置自身。如果在配置元素上指定了 monitorInterval 属性并将其设置为非零值,则下次评估和/或记录日志事件并且 monitorInterval 自上次检查以来已过时,将检查该文件。下面的示例演示如何配置属性,以便仅在至少 30 秒后检查配置文件的更改。最小间隔为 5 秒。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>
7. 链条可以自动处理您的日志文件(广播追加器)
Log4j 提供了为所有基于文件的追加器以及基于套接字的追加器"广播"追加器配置详细信息的功能。例如,对于基于文件的追加器,文件中的文件位置和模式布局包含在播发中。链条和其他外部系统可以发现这些广播,并使用该信息智能地处理日志文件。
公开广播机制以及广告格式特定于每个广播客户实现。想要与特定广播客户实现配合使用的外部系统必须了解如何查找广告配置以及广播的格式。例如,"数据库"广播客户可能会将配置详细信息存储在数据库表中。外部系统可以读取该数据库表,以便发现文件位置和文件格式。
Log4j提供了一个广播实现,一个"多播"广播商,它使用http://jmdns.sourceforge.net库通过IP多播公布追加器配置详细信息。
Chainsaw 会自动发现 log4j 的多播生成的广告,并在 Chainsaw 的 Zeroconf 选项卡中显示这些发现的广告(如果 jmdns 库位于 Chainsaw 的类路径中)。要开始解析和跟踪播发中提供的日志文件,只需双击 Chainsaw 的 Zeroconf 选项卡中的播发条目即可。目前,Chainsaw 仅支持 FileAppender 播发。
8. 配置语法
从版本 2.9 开始,出于安全原因,Log4j 不处理 XML 文件中的 DTD。如果要将配置拆分到多个文件中,请使用XInclude或复合配置。
如前面的示例以及后面的示例所示,Log4j 允许您轻松重新定义日志记录行为,而无需修改应用程序。可以禁用应用程序某些部分的日志记录,仅当满足特定条件(例如为特定用户执行的操作,路由输出到Flume或日志报告系统等)时才记录日志。要做到这一点,需要了解配置文件的语法。
XML 文件中的配置元素接受几个属性:
属性名称 | 描述 |
---|---|
advertiser | (可选)广播商插件名称,将用于广播单个 FileAppender 或 SocketAppender 配置。广播商提供的唯一插件是"多播"。 |
dest | stderr 为"err",stdout 为"out",文件路径或 URL。 |
monitorInterval(监视器中断) | 在检查文件配置是否有更改之前必须经过的最短时间(以秒为单位)。 |
name | 配置的名称 |
packages | 以逗号分隔的软件包名称列表,用于搜索插件。每个类装入器只加载插件一次,因此更改此值可能不会对重新配置产生任何影响。 |
schema | 标识类装入器的位置,以定位用于验证配置的 XML 架构。仅当"严格"设置为 true 时才有效。如果未设置,则不会进行架构验证。 |
shutdownHook (关机钩) | 指定 Log4j 在 JVM 关闭时是否应自动关机。关闭挂钩默认处于启用状态,但可以通过将此属性设置为"禁用"来禁用 |
shutdownTimeout | 指定在 JVM 关闭时追加器和后台任务将关闭的毫秒数。默认值为零,这意味着每个追加器都使用其默认超时,并且不等待后台任务。并非所有追加器都会遵守这一点,这是一个提示,而不是绝对保证关闭过程不会花费更长的时间。将此值设置得太低会增加丢失尚未写入最终目标的未完成日志事件的风险。请参阅LoggerContext.stop(long, java.util.concurrent.TimeUnit)。(如果 shutdownHook 设置为"禁用",则不使用。 |
status | 应记录到控制台的内部 Log4j 事件的级别。此属性的有效值为"关闭"、“跟踪”、“调试”、“信息”、“警告”、“错误”、“致命"和"全部”。Log4j会将有关初始化,翻转和其他内部操作的详细信息记录到状态记录器中。设置 status=“trace” 是您需要对 log4j 进行故障排除时可以使用的第一批工具之一。(或者,设置系统属性 log4j2.debug 也会将内部 Log4j2 日志记录输出到控制台,包括找到配置文件之前发生的内部日志记录。 |
strict | 允许使用严格的 XML 格式。在 JSON 配置中不受支持。 |
verbose | 在加载插件时启用诊断信息。 |
9.使用XML进行配置
Log4j可以使用两种XML风格进行配置;简洁而严格。
简洁的语法
简洁的格式使配置非常容易,因为元素名称与它们所表示的组件匹配,但是无法使用XML架构对其进行验证。例如,ConsoleAppender 是通过在其父追加器元素下声明一个名为 Console 的 XML 元素来配置的。但是,元素和属性名称不区分大小写。此外,可以将属性指定为 XML 属性,也可以指定为没有属性但具有文本值的 XML 元素。所以
<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>
除了上面的简明 XML 格式之外,Log4j 还允许以更"正常"的 XML 方式指定配置,该方式可以使用 XML 架构进行验证。这是通过将上面的友好元素名称替换为其对象类型来实现的,如下所示。例如,不是使用名为 Console 的元素配置 ConsoleAppender,而是将其配置为具有包含"控制台"的 type 属性的追加器元素。
<?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>
下面是使用严格格式的示例配置。
<?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>
10. 使用 JSON 进行配置
除了XML之外,Log4j还可以使用JSON进行配置。JSON 格式与简洁的 XML 格式非常相似。每个键代表插件的名称,与之关联的键/值对是其属性。如果密钥包含的不仅仅是一个简单的值,它本身将是一个从属插件。在下面的示例中,ThresholdFilter、Console 和 PatternLayout 都是插件,而 Console 插件将为其 name 属性分配 STDOUT 值,而 ThresholdFilter 将被分配一个调试级别。
{ "configuration": { "status": "error", "name": "RoutingTest",
"packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename",
"value" : "target/rolling1/rollingtest-$${sd:type}.log" }
},
"ThresholdFilter": { "level": "debug" },
"appenders": {
"Console": { "name": "STDOUT",
"PatternLayout": { "pattern": "%m%n" },
"ThresholdFilter": { "level": "debug" }
},
"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"},
"SizeBasedTriggeringPolicy": { "size": "500" }
}
},
{ "AppenderRef": "STDOUT", "key": "Audit"}
]
}
}
},
"loggers": {
"logger": { "name": "EventLogger", "level": "info", "additivity": "false",
"AppenderRef": { "ref": "Routing" }},
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
}
}
使用 JSON,YAML 配置文件需要其他运行时依赖项。
11. 使用properties文件进行配置
从2.4版本开始,Log4j现在支持通过属性文件进行配置。请注意,属性语法与 Log4j 1 中使用的语法不同。与 XML 和 JSON 配置一样,属性配置根据插件和插件属性来定义配置。
在版本 2.6 之前,属性配置要求您在具有这些名称的属性中以逗号分隔的列表中列出追加器、筛选器和记录器的标识符。然后,这些组件中的每一个都将在以component.<.identifier>开头的属性集中进行定义。标识符不必与所定义组件的名称匹配,但必须唯一标识作为组件一部分的所有属性和子组件。如果标识符列表不存在,则标识不得包含"."。每个单独的组件必须指定一个"type"属性,用于标识组件的插件类型。
从 2.6 版开始,不再需要此标识符列表,因为名称是在首次使用时推断出来的,但是如果您希望使用更复杂的标识,您仍必须使用该列表。如果该列表存在,则将使用它。
与基本组件不同,在创建子组件时,不能指定包含标识符列表的元素。相反,您必须定义包装元素及其类型,如下面的滚动文件追加器中的策略定义所示。然后,定义该包装元素下方的每个子组件,因为下面定义了"基于时间的触发策略"和"基于大小的触发策略"。
属性配置文件支持广告客户、监视器中断、名称、包、关闭挂钩、关闭超时、状态、详细和 dest attrbutes。有关这些属性的定义,请参阅配置语法。
12.配置记录器(Loggers)
在尝试配置记录器之前,了解它们在Log4j中的工作方式至关重要。如果需要更多信息,请参考Log4j架构。试图在不理解这些概念的情况下配置Log4j会导致挫败感。
记录器配置是使用记录器元素配置的。记录器元素必须指定了 name 属性,通常指定了级别属性,并且还可以指定了加法属性。该级别可以配置为
TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF 之一。如果未指定级别,它将默认为
ERROR。可为可加性属性赋值为 true 或 false。如果省略该属性,则将使用默认值 true。捕获位置信息(类名、文件名、方法名和调用方的行号)可能会很慢。Log4j
尝试通过减小堆栈的大小来优化这一点,该堆栈必须遍历才能找到日志记录方法的调用方。它通过确定可能访问的任何组件是否需要位置信息来实现此目的。如果记录器配置为跟踪或调试等级别,并且期望大多数日志将在追加器引用或追加器上进行筛选,则可能会导致性能问题,因为即使日志事件将被丢弃,Log4j也会计算位置信息。若要禁用此行为,可以在
LoggerConfig 上将 includeLocation 属性设置为 false。这将导致Log4j推迟计算位置信息,直到绝对必要。LoggerConfig(包括根 LoggerConfig)可以配置属性,这些属性将添加到从 ThreadContextMap
复制的属性中。这些属性可以从追加器,过滤器,布局等中引用,就像它们是ThreadContext
Map的一部分一样。这些属性可以包含将在分析配置时解析或在记录每个事件时动态解析的变量。有关使用变量的详细信息,请参阅属性替换。LoggerConfig 还可以配置一个或多个 AppenderRef 元素。引用的每个追加器都将与指定的 LoggerConfig
相关联。如果在 LoggerConfig 上配置了多个追加器,则在处理日志记录事件时会调用每个追加器。每个配置都必须有一个根记录器。如果未配置一个,则将使用默认的根 LoggerConfig,该配置具有 ERROR
级别并附加了控制台追加器。根记录器和其他记录器之间的主要区别是
根记录器没有 name 属性。 根记录器不支持加法属性,因为它没有父级。
配置追加器
附加器使用特定追加器插件的名称或附加器元素和包含追加器插件名称的类型属性进行配置。此外,每个追加器必须具有一个名称属性,该属性在追加器集中具有唯一的值。记录程序将使用该名称来引用追加器,如上一节所述。
大多数追加器还支持要配置的布局(同样可以使用特定布局插件的名称作为元素或将"layout"作为元素名称以及包含布局插件名称的类型属性来指定)。各种追加器将包含它们正常运行所需的其他属性或元素。
配置过滤器
Log4j允许在以下4个位置中的任何一个位置指定过滤器:
与追加器、记录器和属性元素处于同一级别。这些筛选器可以在将事件传递到 LoggerConfig 之前接受或拒绝事件。
在记录器元素中。这些筛选器可以接受或拒绝特定记录器的事件。
在追加器元素中。这些筛选器可以阻止或导致追加程序处理事件。
在追加器引用元素中。这些筛选器用于确定记录器是否应将事件路由到追加器。
虽然只能配置单个滤镜元素,但该滤芯可能是表示 CompositeFilter 的滤镜滤芯。过滤器元件允许在其中配置任意数量的过滤器元件。下面的示例演示如何在控制台应用程序上配置多个筛选器。