配置

将日志请求插入应用程序代码需要大量的计划和工作。观察表明,大约 4% 的代码专门用于日志记录。因此,即使是中等规模的应用程序也会在其代码中嵌入数千个日志记录语句。鉴于其数量,在无需手动修改的情况下管理这些日志记录语句变得至关重要。

Log4j 2 的配置可以通过以下 4 种方式之一完成

  1. 通过以 XML、JSON、YAML 或属性格式编写的配置文件。
  2. 以编程方式,通过创建 ConfigurationFactory 和 Configuration 实现。
  3. 以编程方式,通过调用 Configuration 接口中公开的 API 将组件添加到默认配置中。
  4. 以编程方式,通过调用内部 Logger 类上的方法。

此页面主要关注通过配置文件配置 Log4j。有关以编程方式配置 Log4j 的信息,请参见 扩展 Log4j 2以编程方式配置 Log4j

所有可用格式在功能上都是等效的。例如,可以使用属性格式重写 XML 中的配置文件(反之亦然),而不会丢失任何功能。但是,Log4j 配置的层次结构可以在自然支持嵌套的格式中更好地捕获,因此 XML、JSON 和 YAML 文件通常更容易使用。

请注意,与 Log4j 1.x 不同,公共 Log4j 2 API 不公开用于添加、修改或删除附加器和过滤器或以任何方式操作配置的方法。

配置架构

部分原因是首先添加了对 XML 的支持,Log4j 的配置反映为树结构。实际上,每种配置方言,包括 ConfigurationBuilder,都会为每个配置元素生成一个节点。节点是一个相当简单的结构,包含一组属性、一组子节点和一个 PluginType。重要的是要注意,每个节点都必须有一个相应的插件,因为插件是实际执行节点表示的工作的组件。

Log4j 支持的每种文档类型都有一个 ConfigurationFactory。工厂本身是一个 Log4j 插件,它声明其支持的文件扩展名及其优先级。属性具有最高优先级,值为 8,其次是 yaml、json 和 xml。当执行自动配置时,Log4j 将按顺序调用每个工厂,以确定哪些(如果有)支持指定的配置文件格式。如果找到一个支持该格式的工厂,该工厂将创建相应的 Configuration 对象并将对配置数据的引用传递给它。

每个配置实现,例如 XMLConfiguration、YamlConfiguration、JsonConfiguration 等,的主要任务是将配置文本转换为节点树,通常通过使用该文档类型可用的任何工具解析文本。需要注意的是,虽然大多数支持的文档类型本质上是树结构的,但 Java 属性语法不是。由于需要将语法转换为节点树,Log4j 使用的 Java 属性语法要求所有属性遵循使树结构清晰的命名模式。因此,与使用其他文档类型相比,Java 属性格式往往更冗长。

创建节点树后,控制权将委托给 AbstractConfiguration,它使用 Log4j 的插件系统将节点转换为各自的 Java 对象,并提供所有通用功能。

仲裁器

在某些情况下,希望使用单个日志记录配置,该配置可以在任何部署环境中使用。例如,可能需要在生产环境中使用不同的默认日志记录级别,而在开发环境中使用不同的默认日志记录级别。另一种情况可能是,在本地运行时使用一种类型的附加器,而在部署到 Docker 容器时使用另一种类型的附加器。处理此问题的一种方法是使用 Spring Cloud Config Server 等工具,该工具可以感知环境并为每个环境提供不同的文件。另一种选择是在配置中包含仲裁器。

仲裁器是一个 Log4j 插件,其工作是确定是否应将其他配置的元素包含在生成的配置中。虽然所有其他“核心”插件都设计为在 Log4j 的运行时逻辑中执行,但仲裁器在节点树构建后但在树转换为配置之前执行。仲裁器本身就是一个节点,它在树被处理之前总是从节点树中删除。仲裁器实际上所做的就是提供一个返回布尔值结果的方法,该方法决定仲裁器的子节点是否应该保留在配置中或被修剪。

仲裁器可能出现在配置中允许元素的任何位置。因此,仲裁器可以封装一个简单的单个属性声明或一组完整的附加器或日志记录器。仲裁器也可以嵌套,尽管另一个仲裁器的后代仲裁器只有在祖先返回 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”的特殊插件。Select 下面的每个元素都必须是仲裁器。返回 true 值的第一个仲裁器将是使用的仲裁器,而其他仲裁器将被忽略。如果没有任何仲裁器返回 true,则可以使用默认配置元素配置 DefaultArbiter。DefaultArbiter 是一个始终返回 true 的仲裁器,因此在 Select 之外使用它会导致其配置的元素始终被包含,就像它不存在一样。

此示例展示了一个仲裁器,它使用位于单独文件中的 JavaScript 来确定是否包含控制台追加器。如果结果为假,则将包含列表追加器。

<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>

Log4j 本身包含 SystemProperty 仲裁器,它可以根据系统属性是否为空或具有特定值来评估是否包含元素,ClassArbiter 根据指定类是否存在来做出决定,ScriptArbiter 根据与其配置的脚本的结果来做出决定。

对于 Spring Boot 用户,已提供名为 SpringProfile 的仲裁器。指定的配置文件由 Spring 的 Environment.acceptsProfiles() 方法评估,因此它支持的任何表达式都可以用作 name 属性。

此示例将在 Spring 配置文件为“dev”或“staging”时使用控制台追加器,并在活动配置文件为“prod”时使用列表追加器。

<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
  <Appenders>

    <SpringProfile name="dev | staging">
      <Console name="Out">
        <PatternLayout pattern="%m%n"/>
      </Console>
    </SpringProfile>
    <SpringProfile name="prod">
      <List name="Out">
      </List>
    </SpringProfile>

  </Appenders>
  <Loggers>
    <Logger name="org.apache.test" level="trace" additivity="false">
      <AppenderRef ref="Out"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Out"/>
    </Root>
  </Loggers>
</Configuration>

自动配置

Log4j 能够在初始化期间自动配置自身。当 Log4j 启动时,它将找到所有 ConfigurationFactory 插件,并按权重从最高到最低排列。在交付时,Log4j 包含四个 ConfigurationFactory 实现:一个用于 JSON,一个用于 YAML,一个用于属性,一个用于 XML。

  1. Log4j 将检查 "log4j2.configurationFile" 系统属性,如果已设置,将尝试使用与文件扩展名匹配的 ConfigurationFactory 加载配置。请注意,这并不限于本地文件系统上的位置,并且可能包含 URL。
  2. 如果未设置任何系统属性,则属性 ConfigurationFactory 将在类路径中查找 log4j2-test.properties
  3. 如果未找到此类文件,则 YAML ConfigurationFactory 将在类路径中查找 log4j2-test.yamllog4j2-test.yml
  4. 如果未找到此类文件,则 JSON ConfigurationFactory 将在类路径中查找 log4j2-test.jsonlog4j2-test.jsn
  5. 如果未找到此类文件,则 XML ConfigurationFactory 将在类路径中查找 log4j2-test.xml
  6. 如果找不到测试文件,则属性 ConfigurationFactory 将在类路径中查找 log4j2.properties
  7. 如果找不到属性文件,则 YAML ConfigurationFactory 将在类路径中查找 log4j2.yamllog4j2.yml
  8. 如果找不到 YAML 文件,则 JSON ConfigurationFactory 将在类路径中查找 log4j2.jsonlog4j2.jsn
  9. 如果找不到 JSON 文件,则 XML ConfigurationFactory 将尝试在类路径中找到 log4j2.xml
  10. 如果找不到任何配置文件,将使用 DefaultConfiguration。这将导致日志输出到控制台。

使用 log4j 的名为 MyApp 的示例应用程序可以用来说明如何做到这一点。

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 使用包 com.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 找不到配置文件,它将提供默认配置。默认配置(在 DefaultConfiguration 类中提供)将设置

  • 附加到根记录器的 ConsoleAppender
  • 设置为模式“%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n”并附加到 ConsoleAppender 的 PatternLayout

请注意,默认情况下,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.

请注意,使用默认配置时,状态日志记录被禁用。

来自 URI 的配置

log4j2.configurationFile 引用 URL 时,Log4j 将首先确定 URL 是否使用文件协议引用文件。如果是,Log4j 将验证文件 URL 是否有效,并继续按前面描述的方式进行处理。如果它包含除文件以外的其他协议,则 Log4j 将检查 log4j2.Configuration.allowedProtocols 系统属性的值。如果提供的列表包含指定的协议,则 Log4j 将使用 URI 来查找指定的配置文件。否则,将抛出异常并记录错误消息。如果未为系统属性提供任何值,它将默认为“https、file、jar”。通过将系统属性值设置为“_none”,可以阻止使用除“file”以外的任何协议。此值将是一个无效的协议,因此不会与可能存在的任何自定义协议冲突。

Log4j 支持访问需要身份验证的远程 URL。Log4j 开箱即用地支持基本身份验证。如果指定了 log4j2.Configuration.usernamelog4j2.Configuration.password,则这些值将用于执行身份验证。如果密码已加密,则可以通过在 log4j2.Configuration.passwordDecryptor 系统属性中指定完全限定的类名来提供自定义密码解密器。可以通过将 log4j2.Configuration.authenticationProvider 系统属性设置为提供程序的完全限定类名来使用自定义 AuthenticationProvider

累加性

也许希望消除除 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 的记录器,事件将不会传递到其任何父记录器,无论其累加性设置如何。

自动重新配置

当从文件配置时,Log4j 能够自动检测对配置文件的更改并重新配置自身。如果在配置元素上指定了 monitorInterval 属性并将其设置为非零值,则将在下次评估和/或记录日志事件时检查文件,并且自上次检查以来已过去 monitorInterval。以下示例展示了如何配置属性,以便仅在至少经过 30 秒后才检查配置文件是否有更改。最小间隔为 5 秒。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>

Chainsaw 可以自动处理您的日志文件(广告追加器配置)

Log4j 提供了为所有基于文件的追加器以及基于套接字的追加器“广告”追加器配置详细信息的能力。例如,对于基于文件的追加器,广告中包含文件位置和文件中的模式布局。Chainsaw 和其他外部系统可以发现这些广告,并使用这些信息来智能地处理日志文件。

公开广告的机制以及广告格式特定于每个广告商实现。希望与特定广告商实现一起工作的外部系统必须了解如何找到已发布的配置以及广告的格式。例如,“数据库”广告商可能会将配置详细信息存储在数据库表中。外部系统可以读取该数据库表以发现文件位置和文件格式。

Log4j 提供了一个广告商实现,“multicastdns”广告商,它通过使用 JmDNS 库的 IP 多播来发布追加器配置详细信息。

Chainsaw 自动发现 log4j 生成的 multicastdns 广告,并在 Chainsaw 的 Zeroconf 选项卡中显示这些已发现的广告(如果 jmdns 库在 Chainsaw 的类路径中)。要开始解析和尾随广告中提供的日志文件,只需双击 Chainsaw 的 Zeroconf 选项卡中已发布的条目。目前,Chainsaw 仅支持 FileAppender 广告。

要发布追加器配置

  • 将 JmDNS 库从 JmDNS GitHub Releases 添加到应用程序类路径
  • 将配置元素的“advertiser”属性设置为“multicastdns”
  • 将追加器元素上的“advertise”属性设置为“true”
  • 如果发布基于 FileAppender 的配置,请在追加器元素上设置“advertiseURI”属性为适当的 URI

基于 FileAppender 的配置需要在追加器上指定一个额外的“advertiseURI”属性。“advertiseURI”属性为 Chainsaw 提供有关如何访问文件的信息。例如,可以通过指定 Commons VFS (https://commons.apache.org/proper/commons-vfs/) sftp:// URI 来让 Chainsaw 通过 ssh/sftp 远程访问该文件,如果文件可以通过 Web 服务器访问,则可以使用 http:// URI,或者如果从本地运行的 Chainsaw 实例访问该文件,则可以指定 file:// URI。

以下是一个示例广告启用追加器配置,本地运行的 Chainsaw 可以使用它来自动尾随日志文件(注意 file:// advertiseURI)

请注意,您必须添加上面提到的 JmDNS 库。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration advertiser="multicastdns">
...
</Configuration>
<Appenders>
  <File name="File1" fileName="output.log" bufferedIO="false" advertiseURI="file://path/to/output.log" advertise="true">
  ...
  </File>
</Appenders>

配置语法

从 2.9 版开始,出于安全原因,Log4j 不会处理 XML 文件中的 DTD。如果您想将配置拆分为多个文件,请使用 XInclude组合配置

如前面的示例以及接下来的示例所示,Log4j 允许您轻松地重新定义日志记录行为,而无需修改应用程序。可以禁用应用程序某些部分的日志记录,仅在满足特定条件时记录日志(例如,为特定用户执行的操作、将输出路由到 Flume 或日志报告系统等)。能够做到这一点需要了解配置文件的语法。

XML 文件中的配置元素接受多个属性

属性名称 描述
advertiser (可选)将用于发布单个 FileAppender 或 SocketAppender 配置的广告商插件名称。提供的唯一广告商插件是“multicastdns”。
dest stderr 的“err”,stdout 的“out”,文件路径或 URL。
monitorInterval 检查文件配置是否有更改之前必须经过的最短时间(以秒为单位)。
name 配置的名称。
packages “packages” 属性的使用已弃用,将在 Log4j 3.0 中移除。插件应使用 Log4j 注解处理器进行处理。一个用逗号分隔的包名列表,用于搜索插件。插件在每个类加载器中只加载一次,因此更改此值可能不会对重新配置产生任何影响。
schema 标识类加载器用于查找 XML 架构以验证配置的位置。仅在将 strict 设置为 true 时有效。如果未设置,则不会进行架构验证。
shutdownHook 指定 JVM 关闭时 Log4j 是否应自动关闭。关闭钩子默认情况下处于启用状态,但可以通过将此属性设置为“disable”来禁用。
shutdownTimeout 指定 JVM 关闭时附加程序和后台任务可以关闭的毫秒数。默认值为零,这意味着每个附加程序使用其默认超时,并且不等待后台任务。并非所有附加程序都将遵守此设置,它只是一个提示,不能绝对保证关闭过程不会花费更长时间。将此值设置得太低会增加丢失尚未写入最终目标的未决日志事件的风险。请参阅 LoggerContext.stop(long, java.util.concurrent.TimeUnit)。 (如果 shutdownHook 设置为“disable”,则不使用。)
status

应记录到控制台的内部 Log4j 事件的级别。此属性的有效值为“off”、“trace”、“debug”、“info”、“warn”、“error”、“fatal”和“all”。Log4j 将将有关初始化、滚动和其他内部操作的详细信息记录到状态记录器。设置 status="trace" 是您在需要对 log4j 进行故障排除时可用的第一个工具之一。

(或者,设置系统属性 log4j2.debug 也会将内部 Log4j2 日志打印到控制台,包括在找到配置文件之前发生的内部日志。)

strict 启用严格 XML 格式的使用。在 JSON 配置中不支持。
verbose 在加载插件时启用诊断信息。

使用 XML 进行配置

Log4j 可以使用两种 XML 格式进行配置:简洁和严格。

简洁语法
简洁格式使配置非常容易,因为元素名称与其代表的组件匹配,但不能使用 XML 架构进行验证。例如,ConsoleAppender 通过在父 appenders 元素下声明名为 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

除了上面的简洁 XML 格式之外,Log4j 还允许使用更“正常”的 XML 方式指定配置,可以使用 XML 架构对其进行验证。这是通过用其对象类型替换上面的友好元素名称来实现的。例如,ConsoleAppender 不是使用名为 Console 的元素进行配置,而是作为具有包含“Console”的 type 属性的 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>

下面是一个使用严格格式的示例配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest">
  <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 进行配置

除了 XML 之外,Log4j 还可以使用 JSON 进行配置。JSON 格式与简洁的 XML 格式非常相似。每个键代表插件的名称,与其关联的键值对是其属性。如果键包含多个简单值,它本身将是一个下级插件。在下面的示例中,ThresholdFilter、Console 和 PatternLayout 都是插件,而 Console 插件将为其 name 属性分配一个 STDOUT 值,ThresholdFilter 将分配一个 debug 级别。

{ "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" }}
    }
  }
}

请注意,在 RoutingAppender 中,Route 元素已声明为数组。这是有效的,因为每个数组元素将是一个 Route 组件。这对于 appenders 和 filters 等元素不起作用,因为每个元素在简洁格式中都有不同的名称。如果每个附加程序或过滤器都声明了一个名为“type”的属性,该属性包含附加程序的类型,则附加程序和过滤器可以定义为数组元素。以下示例说明了这一点,以及如何将多个记录器声明为数组。

{ "configuration": { "status": "debug", "name": "RoutingTest",
                      "packages": "org.apache.logging.log4j.test",
      "properties": {
        "property": { "name": "filename",
                      "value" : "target/rolling1/rollingtest-$${sd:type}.log" }
      },
    "ThresholdFilter": { "level": "debug" },
    "appenders": {
      "appender": [
         { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }},
         { "type": "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" }},
        { "name": "com.foo.bar", "level": "error", "additivity": "false",
          "AppenderRef": { "ref": "STDOUT" }}
      ],
      "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
    }
  }
}

使用 JSON 配置文件需要额外的 运行时依赖项

使用 YAML 进行配置

Log4j 还支持使用 YAML 进行配置文件。结构遵循与 XML 和 YAML 配置格式相同的模式。例如

Configuration:
  status: warn
  name: YAMLConfigTest
  properties:
    property:
      name: filename
      value: target/test-yaml.log
  thresholdFilter:
    level: debug
  appenders:
    Console:
      name: STDOUT
      target: SYSTEM_OUT
      PatternLayout:
        Pattern: "%m%n"
    File:
      name: File
      fileName: ${filename}
      PatternLayout:
        Pattern: "%d %p %C{1.} [%t] %m%n"
      Filters:
        ThresholdFilter:
          level: error

  Loggers:
    logger:
      -
        name: org.apache.logging.log4j.test1
        level: debug
        additivity: false
        ThreadContextMapFilter:
          KeyValuePair:
            key: test
            value: 123
        AppenderRef:
          ref: STDOUT
      -
        name: org.apache.logging.log4j.test2
        level: debug
        additivity: false
        AppenderRef:
          ref: File
    Root:
      level: error
      AppenderRef:
        ref: STDOUT
          

使用 YAML 配置文件需要额外的 运行时依赖项

使用属性进行配置

从 2.4 版开始,Log4j 现在支持通过属性文件进行配置。请注意,属性语法与 Log4j 1 中使用的语法不同。与 XML 和 JSON 配置一样,属性配置根据插件及其属性定义配置。

在 2.6 版之前,属性配置要求您在具有这些名称的属性中以逗号分隔的列表形式列出附加程序、过滤器和记录器的标识符。然后,将预期每个组件都定义在以 component.<.identifier>. 开头的属性集中。标识符不必与正在定义的组件的名称匹配,但必须唯一地标识属于组件的所有属性和子组件。如果标识符列表不存在,则标识符中不能包含“.”。每个单独的组件都必须指定一个“type”属性,该属性标识组件的插件类型。

从 2.6 版开始,此标识符列表不再需要,因为名称在首次使用时会推断出来,但是如果您想使用更复杂的标识符,您仍然必须使用该列表。如果存在该列表,它将被使用。

与基本组件不同,在创建子组件时,您不能指定包含标识符列表的元素。相反,您必须使用其类型定义包装元素,如以下滚动文件附加程序中的策略定义所示。然后,您在该包装元素下方定义每个子组件,如以下 TimeBasedTriggeringPolicy 和 SizeBasedTriggeringPolicy 所定义。

从 2.17.2 版开始,可以指定 rootLoggerlogger.key 属性来设置该记录器的级别和零个或多个附加程序引用以创建该记录器。级别和附加程序引用由逗号 , 字符分隔,逗号周围可能有可选的空格。以下示例演示了在读取属性配置时如何扩展简写。

appender.stdout.type = Console
# ... other appender properties
appender.file.type = File
# ... other appender properties
logger.app = INFO, stdout, file
logger.app.name = com.example.app

# is equivalent to:
# appender.stdout.type = Console
# appender.stdout.name = stdout
# ...
appender.file.type = File
appender.file.name = file
# ...
logger.app.name = com.example.app
logger.app.level = INFO
logger.app.appenderRef.$1.ref = stdout
logger.app.appenderRef.$2.ref = file
            

属性配置文件支持 advertiser、monitorInterval、name、packages、shutdownHook、shutdownTimeout、status、verbose 和 dest 属性。有关这些属性的定义,请参阅 配置语法

status = error
dest = err
name = PropertiesConfig

property.filename = target/rolling/rollingtest.log

filter.threshold.type = ThresholdFilter
filter.threshold.level = debug

appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = error

appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5

logger.rolling = debug, RollingFile
logger.rolling.name = com.example.my.app
logger.rolling.additivity = false

rootLogger = info, STDOUT

# or using a grouping element:
# rootLogger.level = info
# rootLogger.appenderRef.stdout.ref = STDOUT
          

配置记录器

在尝试配置记录器之前,了解记录器在 Log4j 中的工作原理至关重要。如果需要更多信息,请参考 Log4j 体系结构。尝试在不了解这些概念的情况下配置 Log4j 会导致沮丧。

LoggerConfig 使用 logger 元素进行配置。logger 元素必须指定一个 name 属性,通常会指定一个 level 属性,也可能指定一个 additivity 属性。级别可以使用 TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF 之一进行配置。如果未指定级别,则默认为 ERROR。additivity 属性可以分配 true 或 false 值。如果省略该属性,则将使用默认值 true。

捕获位置信息(调用者的类名、文件名、方法名和行号)可能很慢。Log4j 尝试通过减少必须遍历以查找日志方法调用者的堆栈大小来优化此操作。它通过确定任何可能被访问的组件是否需要位置信息来做到这一点。如果记录器在 trace 或 debug 等级别进行配置,并且预期大多数日志将在附加程序引用或附加程序上进行过滤,这可能会导致性能问题,因为 Log4j 将计算位置信息,即使日志事件将被丢弃。要禁用此行为,可以在 LoggerConfig 上将 includeLocation 属性设置为 false。这将导致 Log4j 延迟计算位置信息,直到绝对必要时才计算。

LoggerConfig(包括根 LoggerConfig)可以使用将添加到从 ThreadContextMap 复制的属性的属性进行配置。这些属性可以从附加程序、过滤器、布局等中引用,就像它们是 ThreadContext Map 的一部分一样。属性可以包含将在解析配置时或在记录每个事件时动态解析的变量。有关使用变量的更多信息,请参阅 属性替换

LoggerConfig 还可以配置一个或多个 AppenderRef 元素。引用的每个附加程序将与指定的 LoggerConfig 相关联。如果在 LoggerConfig 上配置了多个附加程序,则在处理日志事件时将调用它们中的每一个。

每个配置都必须有一个根记录器。如果未配置,则将使用默认的根 LoggerConfig,其级别为 ERROR,并且附加了 Console 附加程序。根记录器与其他记录器之间的主要区别在于

  1. 根记录器没有 name 属性。
  2. 根记录器不支持 additivity 属性,因为它没有父级。

配置附加程序

附加程序可以使用特定附加程序插件的名称进行配置,也可以使用 appender 元素和包含附加程序插件名称的 type 属性进行配置。此外,每个附加程序都必须指定一个 name 属性,其值在附加程序集中是唯一的。该名称将被记录器用于引用附加程序,如上一节所述。

大多数附加程序还支持配置布局(同样可以使用特定布局插件的名称作为元素进行指定,或者使用“layout”作为元素名称,以及包含布局插件名称的 type 属性。各种附加程序将包含其他属性或元素,这些属性或元素是它们正常运行所必需的。

配置过滤器

Log4j 允许在以下 4 个位置指定过滤器

  1. 与 appenders、loggers 和 properties 元素处于同一级别。这些过滤器可以在事件传递到 LoggerConfig 之前接受或拒绝事件。
  2. 在日志记录器元素中。这些过滤器可以接受或拒绝特定日志记录器的事件。
  3. 在追加器元素中。这些过滤器可以阻止或导致事件被追加器处理。
  4. 在追加器引用元素中。这些过滤器用于确定日志记录器是否应将事件路由到追加器。

虽然只能配置单个filter元素,但该元素可能是代表CompositeFilter的filters元素。filters元素允许在其中配置任意数量的filter元素。以下示例显示了如何在ConsoleAppender上配置多个过滤器。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="XMLConfigTest">
  <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>

属性替换

Log4j 2支持在配置中指定标记作为对其他地方定义的属性的引用。其中一些属性将在解释配置文件时解析,而另一些属性可能会传递给组件,这些组件将在运行时对其进行评估。为了实现这一点,Log4j 使用了Apache Commons LangStrSubstitutorStrLookup类的变体。以类似于 Ant 或 Maven 的方式,这允许声明为${name}的变量使用在配置本身中声明的属性进行解析。例如,以下示例显示了滚动文件追加器的文件名被声明为属性。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest">
  <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 变量名应在特定上下文中进行评估。有关更多详细信息,请参阅查找手册页。内置于 Log4j 的上下文是

前缀 上下文
bundle 资源包。格式为${bundle:BundleName:BundleKey}。包名遵循包命名约定,例如:${bundle:com.domain.Messages:MyKey}
ctx 从线程上下文映射 (MDC) 中检索先前存储的值。格式为${ctx:some.key}
date 使用来自SimpleDateFormat类的指定格式模式插入当前日期和/或时间。如果未指定模式,则使用默认模式。格式为${date:some.pattern}${date:}
docker 返回应用程序正在运行的 Docker 容器的属性。格式为${docker:some.attribute}。有关要求和可用属性列表,请参阅Docker 文档
env 从系统环境变量中检索值,如果环境变量未设置,则检索默认值。格式为${env:ENV_NAME}${env:ENV_NAME:-default_value}
event 从日志事件中的字段检索值。格式为${event:some.field}。有关可用字段的列表,请参阅查找手册页。
java 检索有关应用程序正在运行的 Java 环境的信息。格式为${java:some.property}。有关可用属性的列表,请参阅查找手册页。
jndi 在默认 JNDI 上下文中设置的值。(需要将系统属性log4j2.enableJndiLookup设置为true。)格式为${jndi:logging/context-name}
jvmrunargs 通过 JMX 访问的 JVM 输入参数,但不是主参数;请参阅RuntimeMXBean.getInputArguments()。格式为${jvmrunargs:argument}。在 Android 或 Google App Engine 上不可用。
k8s 返回应用程序正在运行的 Kubernetes 环境的属性。格式为${k8s:some.attribute}。有关可用属性的列表,请参阅查找手册页。
log4j Log4j 配置属性。表达式${log4j:configLocation}${log4j:configParentLocation}分别提供 log4j 配置文件及其父文件夹的绝对路径。
lower 将传入的参数转换为小写(通常与嵌套查找一起使用)。格式为${lower:argument}
main 使用MapLookup.setMainArguments(String[])设置的值。格式为${main:index}(用于参数列表中的基于 0 的索引)和${main:argument.name}(用于参数列表中的名称)。
map 为配置文件中的属性提供基础,或从 MapMessage 中检索值。格式为${map:type}。有关更多详细信息,请参阅查找手册页。
marker 允许在配置中使用标记。格式为${marker:}${marker:some.name}。有关更多详细信息,请参阅查找手册页。
sd 来自 StructuredDataMessage 的值。键“id”将返回 StructuredDataId 的名称,不包括企业编号。键“type”将返回消息类型。其他键将从 Map 中检索各个元素。
spring 从 Spring 配置中返回 Spring 属性的值。格式为${spring:some.property}。有关要求和详细信息,请参阅查找手册页。
sys 从系统属性中检索值。格式为${sys:some.property}${sys:some.property:-default_value}
upper 将传入的参数转换为大写(通常与嵌套查找一起使用)。格式为${upper:argument}
web 返回与 Servlet 上下文关联的变量的值。格式为${spring:some.key}。有关可用键的列表,请参阅查找手册页。

默认属性

可以通过在 Configuration 元素之后,在声明任何 Loggers、Filters、Appenders 等之前直接放置 Properties 元素来在配置文件中声明默认属性映射。如果在指定的查找中找不到该值,则将使用默认属性映射中的值。默认映射预先填充了“hostName”的值,该值是当前系统的主机名或 IP 地址,以及“contextName”,其值是当前日志记录上下文的 value。在本节中,请参阅 Properties 元素在许多地方的使用示例。

默认属性也可以通过使用语法${lookupName:key:-defaultValue}在 Lookup 中指定。在某些情况下,键可能包含前导“-”。在这种情况下,必须包含转义字符,例如${main:\--file:-app.properties}。这将使用名为--file的键的MainMapLookup。如果找不到键,则将使用app.properties作为默认值。

启用消息模式查找

消息(默认情况下)在不使用查找的情况下进行处理,例如,如果您定义了 <Property name="foo.bar">FOO_BAR </Property>,则logger.info("${foo.bar}")将输出${foo.bar}而不是FOO_BAR。您可以通过使用 %m{lookups} 定义消息模式来启用消息模式查找。

具有多个前导“$”字符的查找变量

StrLookup 处理的一个有趣功能是,当变量引用声明为具有多个前导“$”字符时,每次解析变量时,前导“$”都会被简单地删除。在前面的示例中,“Routes”元素能够在运行时解析变量。为了允许这样做,前缀值被指定为具有两个前导“$”字符的变量。当配置文件首次处理时,第一个“$”字符将被简单地删除。因此,当 Routes 元素在运行时进行评估时,它是变量声明“${sd:type}”,它会导致检查事件以查找 StructuredDataMessage,如果存在,则使用其 type 属性的值作为路由键。并非所有元素都支持在运行时解析变量。支持此功能的组件将在其文档中明确说明这一点。

如果在与前缀关联的 Lookup 中找不到键的值,则将使用配置文件中属性声明中与键关联的值。如果找不到值,则将返回变量声明作为值。默认值可以在配置中通过以下方式声明

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Properties>
    <Property name="type">Audit</property>
  </Properties>
  ...
</Configuration>

作为脚注,值得指出的是,RollingFile 追加器声明中的变量在处理配置时也不会被评估。这仅仅是因为整个 RollingFile 元素的解析被推迟到匹配发生时。有关更多信息,请参阅RoutingAppender

脚本

Log4j 提供了对JSR 223脚本语言的支持,这些语言可以在其某些组件中使用。任何提供对 JSR 223 脚本引擎支持的语言都可以使用。可以在脚本引擎网站上找到语言及其绑定的列表。但是,其中列出的一些语言,如 JavaScript、Groovy 和 Beanshell,直接支持 JSR 223 脚本框架,并且只需要安装该语言的 jar 包。

从 Log4j 2.17.2 开始,要支持的语言必须在log4j2.Script.enableLanguages系统属性中指定为逗号分隔的列表。

支持使用脚本的组件通过允许在它们上配置<script><scriptFile><scriptRef>元素来实现这一点。script 元素包含脚本的名称、脚本的语言和脚本文本。scriptFile 元素包含脚本的名称、其位置、其语言、其字符集以及是否应监视文件以进行更改。scriptRef 元素包含在<scripts>配置元素中定义的脚本的名称。脚本的名称用于存储脚本及其 ScriptEngine,以便每次需要运行脚本时都可以快速找到它。虽然名称不是必需的,但提供它将有助于在脚本运行时调试问题。语言必须在 script 元素上提供,并且必须指定下一节中描述的 Configuration 状态日志中出现的语言名称之一。如果在 scriptFile 元素上未指定语言,则语言将由脚本路径的文件扩展名确定。如果请求文件监视,则只有在配置元素上指定了非零 monitorInterval 时才会启用它。该间隔将用于检查文件中的更改。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest">
  <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>

  <Appenders>
    <Console name="STDOUT">
      <ScriptPatternSelector defaultPattern="%d %p %m%n">
        <ScriptRef ref="selector"/>
          <PatternMatch key="NoLocation" pattern="[%-5level] %c{1.} %msg%n"/>
          <PatternMatch key="Flow" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/>
      </ScriptPatternSelector>
      <PatternLayout pattern="%m%n"/>
    </Console>
  </Appenders>

  <Loggers>
    <Logger name="EventLogger" level="info" additivity="false">
        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
          <Script name="GroovyFilter" language="groovy"><![CDATA[
            if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
                return true;
            } else if (logEvent.getContextMap().containsKey("UserId")) {
                return true;
            }
            return false;
            ]]>
          </Script>
        </ScriptFilter>
      <AppenderRef ref="STDOUT"/>
    </Logger>

    <Root level="error">
      <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
        <ScriptRef ref="groovy.filter"/>
      </ScriptFilter>
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>

</Configuration>
          

如果 Configuration 元素上的 status 属性设置为 DEBUG,则将列出当前安装的脚本引擎列表及其属性。虽然某些引擎可能表示它们不是线程安全的,但 Log4j 会采取措施确保如果引擎声明它不是线程安全的,则脚本将以线程安全的方式运行。

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}
          

执行脚本时,将为它们提供一组变量,这些变量应该允许它们完成预期执行的任何任务。有关脚本可用的变量列表,请参阅各个组件的文档。

支持脚本的组件期望将返回值传递回调用 Java 代码。这对几种脚本语言来说不是问题,但 Javascript 不允许返回语句,除非它在函数中。但是,Javascript 将返回在脚本中执行的最后一个语句的值。因此,如下所示的代码将导致期望的行为。

            var result;
            if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
                result = "NoLocation";
            } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
                result = "Flow";
            }
            result;
          

关于 Beanshell 的特别说明

JSR 223 脚本引擎应该识别它们是否支持编译脚本,如果支持则应该识别它们支持 Compilable 接口。Beanshell 做到了这一点。但是,每当调用 compile 方法时,它都会抛出一个错误(而不是异常)。Log4j 会捕获此错误,但会为每个尝试编译的 Beanshell 脚本记录以下警告。然后,所有 Beanshell 脚本将在每次执行时被解释。

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 配置文件可以使用 XInclude 包含其他文件。以下是一个包含另外两个文件的 log4j2.xml 文件示例

<?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>

log4j-xinclude-appenders.xml

<?xml version="1.0" encoding="UTF-8"?>
<appenders>
  <Console name="STDOUT">
    <PatternLayout pattern="%m%n" />
  </Console>
  <File name="File" fileName="${filename}" bufferedIO="true" immediateFlush="true">
    <PatternLayout>
      <pattern>%d %p %C{1.} [%t] %m%n</pattern>
    </PatternLayout>
  </File>
</appenders>

log4j-xinclude-loggers.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <AppenderRef ref="File" />
  </logger>

  <root level="error">
    <AppenderRef ref="STDOUT" />
  </root>
</loggers>

组合配置

Log4j 允许通过在 log4j.configurationFile 上指定它们作为逗号分隔的文件路径列表来使用多个配置文件,或者在使用 URL 时,通过将辅助配置位置添加为名为“override”的查询参数来使用多个配置文件。合并逻辑可以通过在 log4j.mergeStrategy 属性上指定实现 MergeStrategy 接口的类来控制。默认合并策略将使用以下规则合并文件

  1. 全局配置属性将与后续配置中的属性聚合,后续配置中的属性将替换先前配置中的属性,但以下情况除外
    • 将使用最高状态级别
    • 将使用大于 0 的最低 monitorInterval
    • 包将用逗号连接
  2. 来自所有配置的属性将被聚合。重复属性将替换先前配置中的属性。
  3. 如果定义了多个过滤器,则过滤器将在 CompositeFilter 下聚合。由于过滤器没有命名,因此可能存在重复项。
  4. 脚本和 ScriptFile 引用将被聚合。重复定义将替换先前配置中的定义。
  5. 附加器将被聚合。具有相同名称的附加器将被后续配置中的附加器替换,包括所有附加器的子组件。
  6. 所有记录器都将被聚合。记录器属性将被单独合并,重复项将被后续配置中的属性替换。记录器上的附加器引用将被聚合,重复项将被后续配置中的属性替换。记录器上的过滤器将在 CompositeFilter 下聚合,如果定义了多个过滤器。由于过滤器没有命名,因此可能存在重复项。附加器引用下的过滤器将根据其父附加器引用是否保留或丢弃而被包含或丢弃。

状态消息

针对性强的故障排除技巧

从 log4j-2.9 开始,如果系统属性 log4j2.debug 被定义为空或其值等于 true(不区分大小写),则 log4j2 将将所有内部日志记录打印到控制台。

在 log4j-2.9 之前,有两个地方可以控制内部日志记录

  • 在找到配置之前,可以使用系统属性 org.apache.logging.log4j.simplelog.StatusLogger.level 控制状态记录器级别。
  • 在找到配置之后,可以使用配置文件中的“status”属性控制状态记录器级别,例如:<Configuration status="trace">

正如希望能够诊断应用程序中的问题一样,也经常需要能够诊断日志记录配置或配置的组件中的问题。由于日志记录尚未配置,因此在初始化期间无法使用“正常”日志记录。此外,附加器中的正常日志记录可能会创建无限递归,Log4j 将检测到这一点并导致递归事件被忽略。为了满足这种需求,Log4j 2 API 包含一个 StatusLogger。组件声明 StatusLogger 的实例,类似于

protected final static Logger logger = StatusLogger.getLogger();

由于 StatusLogger 实现了 Log4j 2 API 的 Logger 接口,因此可以使用所有正常的 Logger 方法。

在配置 Log4j 时,有时需要查看生成的事件状态。这可以通过将 status 属性添加到配置元素来实现,或者可以通过设置“Log4jDefaultStatusLevel”系统属性来提供默认值。status 属性的有效值为“trace”、“debug”、“info”、“warn”、“error”和“fatal”。以下配置将 status 属性设置为 debug。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest">
  <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>

在启动期间,此配置会生成

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,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,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')})
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')}), 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, 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

如果 status 属性设置为 error,则只会将错误消息写入控制台。这使得故障排除配置错误成为可能。例如,如果将上面的配置更改为将 status 设置为 error,并将记录器声明更改为

<logger name="EventLogger" level="info" additivity="false">
  <AppenderRef ref="Routng"/>
</logger>

则会生成以下错误消息。

2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger

应用程序可能希望将状态输出定向到其他目的地。这可以通过将 dest 属性设置为“err”来实现,以将输出发送到 stderr,或者发送到文件位置或 URL。这也可以通过确保配置的状态设置为 OFF,然后以编程方式配置应用程序来实现,例如

StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
StatusLogger.getLogger().registerListener(listener);

在 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 test-jar 依赖项添加到您的测试范围依赖项中。例如

public class AwesomeTest {
    @Rule
    public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml");

    @Test
    public void testSomeAwesomeFeature() {
        final LoggerContext ctx = init.getLoggerContext();
        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.
    }
}

系统属性

Log4j 文档引用了一些系统属性,这些属性可用于控制 Log4j 2 行为的各个方面。下表列出了这些属性及其默认值以及它们控制的内容的描述。属性名称中出现的任何空格都是为了视觉效果,应该删除。

请注意,从 Log4j 2.10 开始,所有系统属性名称都已标准化为遵循一致的命名方案。虽然仍然支持旧的属性名称以确保向后兼容性,但建议更新配置以使用新的样式。此系统是可扩展的,并通过 PropertySource 接口启用。可以通过 Java SE 中的标准 ServiceLoader 机制添加其他属性源类。

属性可以被具有较低数字优先级的源覆盖(例如,-100 在 100 之前)。以下源默认情况下都可用

PropertySource 优先级和描述
优先级 描述
Spring Boot 属性 -100 此属性源仅在 Java 应用程序使用 Spring Boot 且存在 log4j-spring 模块时启用。它使用 Spring Environment 解析属性。
系统属性 0 所有属性都可以使用正常的系统属性模式设置。这些属性在常用的属性源中具有最低的数字优先级,可以覆盖属性文件或环境变量。如果 log4j2.system.properties 文件在类路径上可用,则其内容将在 Log4j 启动时被源到 Java 系统属性中。
环境变量 100 环境变量都以 LOG4J_ 为前缀,全部大写,单词之间用下划线分隔。只有这种命名方案支持环境变量,因为没有旧的命名方案来维护与之的兼容性。
log4j2.component.properties 文件 200 将此文件包含在类路径中可以用作提供属性作为系统属性的替代方法。这是具有最高数字优先级的属性源,可用于提供默认值,这些默认值可以被系统管理员覆盖。

以下是可用的全局配置属性列表。请注意,这些属性在每个 JVM 进程中只能设置一次,与配置文件中可用的配置设置不同。属性名称 列包含属性文件和系统属性中使用的名称;环境变量 用于等效的环境变量;旧属性名称 用于 2.10 之前的名称。

t
Log4j 2 全局配置属性
属性名称
(旧属性名称)
环境变量 默认值 描述
log4j2.configurationFile
(log4j.configurationFile)
LOG4J_CONFIGURATION_FILE   Log4j 2 配置文件的路径。也可以包含逗号分隔的配置文件名称列表。可以包含 URL。当指定为 URL 时,可以使用“override”查询参数指定其他配置文件位置。
log4j2.debug
(log4j2.debug)
LOG4J_DEBUG   如果系统属性 log4j2.debug 被定义为空或其值等于 true(不区分大小写),则 log4j2 将将所有内部日志记录打印到控制台。
log4j2.mergeStrategy
(log4j.mergeStrategy)
LOG4J_MERGE_STRATEGY   实现 MergeStrategy 接口的类的名称。如果未指定,则在创建 CompositeConfiguration 时将使用 DefaultMergeStrategy
log4j2.contextSelector
(Log4jContextSelector)
LOG4J_CONTEXT_SELECTOR ClassLoaderContextSelector 创建 LoggerContext。应用程序可以根据情况拥有一个或多个活动的 LoggerContext。有关更多详细信息,请参阅 日志分离。可用的上下文选择器实现类
org.apache.logging.log4j.core.async .AsyncLoggerContextSelector - 使 所有记录器异步
org.apache.logging.log4j.core.async .BasicAsyncLoggerContextSelector - 使用单个共享 AsyncLoggerContext 使 所有记录器异步
org.apache.logging.log4j.core.selector .BasicContextSelector - 创建单个共享 LoggerContext。
org.apache.logging.log4j.core.selector .ClassLoaderContextSelector - 为每个 Web 应用程序创建单独的 LoggerContext。
org.apache.logging.log4j.core.selector .JndiContextSelector - 使用 JNDI 定位每个 Web 应用程序的 LoggerContext。
org.apache.logging.log4j.core.osgi .BundleContextSelector - 为每个 OSGi 捆绑包创建单独的 LoggerContext。
log4j2.logEventFactory
(Log4jLogEventFactory)
LOG4J_LOG_EVENT_FACTORY org.apache.logging.log4j.core.impl .DefaultLogEventFactory LoggerConfig 用于创建 LogEvent 实例的工厂类。(在使用 AsyncLoggerContextSelector 时被忽略。)
log4j2.loggerContextFactory
(log4j2.loggerContextFactory)
LOG4J_LOGGER_CONTEXT_FACTORY org.apache.logging.log4j.simple .SimpleLoggerContextFactory LogManager 用于引导日志记录实现的工厂类。核心 jar 提供 org.apache.logging.log4j.core .impl.Log4jContextFactory
log4j2.configurationFactory
(log4j.configurationFactory)
LOG4J_CONFIGURATION_FACTORY   扩展 org.apache.logging.log4j.core .config.ConfigurationFactory 的类的完全限定类名。如果指定,则将此类的实例添加到配置工厂列表中。
log4j2.Configuration.allowedProtocols
(log4j.configurationAllowedProtocols)
LOG4J_CONFIGURATION_ALLOWED_PROTOCOLS   逗号分隔的协议列表,这些协议可用于加载配置文件。默认值为“https, file, jar”。要完全阻止通过 URL 访问配置,请指定“_none”的值。
log4j2.configurationAuthorizationEncoding LOG4J_CONFIGURATION_AUTHORIZATION_ENCODING UTF-8 用于基本身份验证的编码(参见 RFC 7617)。
log4j2.Configuration.authorizationProvider
(log4j.configurationAuthorizationProvider
LOG4J_CONFIGURATION_AUTHORIZATION_PROVIDER org.apache.logging.log4j.core.util.BasicAuthorizationProvider 授权提供者的完全限定类名。
log4j2.Configuration.password
(log4j.configurationPassword
LOG4J_CONFIGURATION_PASSWORD   访问远程日志配置文件所需的密码。
log4j2.Configuration.passwordDecryptor
(log4j.configurationPasswordDecryptor
LOG4J_CONFIGURATION_PASSWORD_DECRYPTOR   如果密码已加密,则此类将用于解密它。
log4j2.Configuration.username
(log4j.configurationUsername
LOG4J_CONFIGURATION_USERNAME   访问远程日志配置文件所需的用户名。
log4j2.shutdownHookEnabled
(log4j.shutdownHookEnabled)
LOG4J_SHUTDOWN_HOOK_ENABLED true 覆盖全局标志,指示是否应使用关闭挂钩来停止LoggerContext。默认情况下,这是启用的,可以在每个配置的基础上禁用。在使用log4j-web模块运行时,这将自动禁用。
log4j2.shutdownCallbackRegistry
(log4j.shutdownCallbackRegistry)
LOG4J_SHUTDOWN_CALLBACK_REGISTRY org.apache.logging.log4j.core.util .DefaultShutdownCallbackRegistry 实现ShutdownCallbackRegistry的类的完全限定类名。如果指定,则使用此类的实例而不是DefaultShutdownCallbackRegistry。指定的类必须具有默认构造函数。
log4j2.clock
(log4j.Clock)
LOG4J_CLOCK SystemClock 用于对日志事件进行时间戳的org.apache.logging.log4j .core.util.Clock接口的实现。
默认情况下,System.currentTimeMillis在每个日志事件上被调用。
您还可以指定实现Clock接口的自定义类的完全限定类名。
log4j2.level
(org.apache.logging.log4j.level)
LOG4J_LEVEL ERROR 默认配置的日志级别。如果ConfigurationFactory无法成功创建配置(例如,未找到log4j2.xml文件),则使用默认配置。
log4j2.disableThreadContext
(disableThreadContext)
LOG4J_DISABLE_THREAD_CONTEXT false 如果为true,则禁用ThreadContext堆栈和映射。(如果指定了自定义ThreadContext映射,则可能会被忽略。)
log4j2.disableThreadContextStack
(disableThreadContextStack)
LOG4J_DISABLE_THREAD_CONTEXT_STACK false 如果为true,则禁用ThreadContext堆栈。
log4j2.disableThreadContextMap
(disableThreadContextMap)
LOG4J_DISABLE_THREAD_CONTEXT_MAP false 如果为true,则禁用ThreadContext映射。(如果指定了自定义ThreadContext映射,则可能会被忽略。)
log4j2.threadContextMap
(log4j2.threadContextMap)
LOG4J_THREAD_CONTEXT_MAP   自定义ThreadContextMap实现类的完全限定类名。
log4j2.isThreadContextMapInheritable
(isThreadContextMapInheritable)
LOG4J_IS_THREAD_CONTEXT_MAP_INHERITABLE false 如果为true,则使用InheritableThreadLocal来实现ThreadContext映射。否则,使用普通的ThreadLocal。(如果指定了自定义ThreadContext映射,则可能会被忽略。)
log4j2.contextDataInjector
(log4j2.ContextDataInjector)
LOG4J_CONTEXT_DATA_INJECTOR   自定义ContextDataInjector实现类的完全限定类名。
log4j2.garbagefreeThreadContextMap
(log4j2.garbagefree.threadContextMap)
LOG4J_GARBAGEFREE_THREAD_CONTEXT_MAP false 指定“true”以使ThreadContext映射无垃圾。
log4j2.disableJmx
(log4j2.disable.jmx)
LOG4J_DISABLE_JMX false 如果为true,则不会使用MBean对Log4j配置对象(如LoggerContexts、Appenders、Loggers等)进行检测,并且无法对其进行远程监控和管理。
log4j2.jmxNotifyAsync
(log4j2.jmx.notify.async)
LOG4J_JMX_NOTIFY_ASYNC 对于Web应用程序为false,否则为true 如果为true,则log4j的JMX通知将从单独的后台线程发送,否则它们将从调用线程发送。如果系统属性log4j2.is.webapptruejavax.servlet.Servlet类在类路径上,则默认行为是使用调用线程来发送JMX通知。
log4j2.skipJansi
(log4j.skipJansi)
LOG4J_SKIP_JANSI true 如果为true,则ConsoleAppender不会尝试在Windows上使用Jansi输出流。
log4j2.ignoreTCL
(log4j.ignoreTCL)
LOG4J_IGNORE_TCL false 如果为true,则类仅使用默认类加载器加载。否则,在回退到默认类加载器之前,将尝试使用当前线程的上下文类加载器加载类。
log4j2.enableJndiContextSelector LOG4J_ENABLE_JNDI_CONTEXT_SELECTOR false 当为true时,使用JNDI java协议的Log4j上下文选择器将被启用。当为false时,默认情况下,它们将被禁用。
log4j2.enableJndiJdbc LOG4J_ENABLE_JNDI_JDBC false 当为true时,使用JNDI java协议的DataSource配置的Log4j JDBC Appender将被启用。当为false时,默认情况下,它们将被禁用。
log4j2.enableJndiJms LOG4J_ENABLE_JNDI_JMS false 当为true时,使用JNDI java协议的Log4j JMS Appender将被启用。当为false时,默认情况下,它们将被禁用。
log4j2.enableJndiLookup LOG4J_ENABLE_JNDI_LOOKUP false 当为true时,使用JNDI java协议的Log4j查找将被启用。当为false时,默认情况下,它们将被禁用。
log4j2.uuidSequence
(org.apache.logging.log4j.uuidSequence)
LOG4J_UUID_SEQUENCE 0 可用于使用整数值对UUID生成进行播种的系统属性。
log4j2.simplelogShowContextMap
(org.apache.logging.log4j .simplelog.showContextMap)
LOG4J_SIMPLELOG_SHOW_CONTEXT_MAP false 如果为true,则每个SimpleLogger日志消息中都包含完整的ThreadContext映射。
log4j2.simplelogShowlogname
(org.apache.logging.log4j .simplelog.showlogname)
LOG4J_SIMPLELOG_SHOWLOGNAME false 如果为true,则每个SimpleLogger日志消息中都包含日志记录器名称。
log4j2.simplelogShowShortLogname
(org.apache.logging.log4j .simplelog.showShortLogname)
LOG4J_SIMPLELOG_SHOW_SHORT_LOGNAME true 如果为true,则仅在SimpleLogger日志消息中包含日志记录器名称的最后一个组件。(例如,如果日志记录器名称为“mycompany.myproject.mycomponent”,则仅记录“mycomponent”。
log4j2.simplelogShowdatetime
(org.apache.logging.log4j .simplelog.showdatetime)
LOG4J_SIMPLELOG_SHOWDATETIME false 如果为true,则SimpleLogger日志消息包含时间戳信息。
log4j2.simplelogDateTimeFormat
(org.apache.logging.log4j .simplelog.dateTimeFormat)
LOG4J_SIMPLELOG_DATE_TIME_FORMAT "yyyy/MM/dd HH:mm:ss:SSS zzz" 要使用的日期时间格式。如果org.apache.logging.log4j .simplelog.showdatetimefalse,则忽略。
log4j2.simplelogLogFile
(org.apache.logging.log4j .simplelog.logFile)
LOG4J_SIMPLELOG_LOG_FILE system.err "system.err"(不区分大小写)记录到System.err,"system.out"(不区分大小写)记录到System.out,任何其他值都被解释为要保存SimpleLogger消息的文件名。
log4j2.simplelogLevel
(org.apache.logging.log4j .simplelog.level)
LOG4J_SIMPLELOG_LEVEL ERROR 新SimpleLogger实例的默认级别。
log4j2.simplelog.<loggerName>.level
(org.apache.logging.log4j .simplelog.<loggerName>.level)
LOG4J_SIMPLELOG_<LOGGER_NAME>_LEVEL SimpleLogger默认日志级别 具有指定名称的SimpleLogger实例的日志级别。
log4j2.simplelogStatusLoggerLevel
(org.apache.logging.log4j.simplelog .StatusLogger.level)
LOG4J_SIMPLELOG_STATUS_LOGGER_LEVEL ERROR 此属性用于控制初始StatusLogger级别,并且可以通过调用StatusLogger.getLogger() .setLevel(someLevel)在代码中覆盖它。请注意,StatusLogger级别仅用于确定状态日志输出级别,直到注册侦听器为止。在实践中,在找到配置时会注册侦听器,从那时起,状态消息仅发送到侦听器(取决于其statusLevel)。
log4j2.defaultStatusLevel
(Log4jDefaultStatusLevel)
LOG4J_DEFAULT_STATUS_LEVEL ERROR

StatusLogger将日志记录系统中发生的事件记录到控制台。在配置期间,AbstractConfiguration向StatusLogger注册一个StatusConsoleListener,该侦听器可能会将状态日志事件从默认控制台输出重定向到文件。侦听器还支持细粒度过滤。此系统属性指定侦听器在配置未指定状态级别时要使用的默认状态日志级别。

注意:此属性仅在找到配置文件后由log4j-core实现使用。

log4j2.statusLoggerLevel
(log4j2.StatusLogger.level)
LOG4J_STATUS_LOGGER_LEVEL WARN

StatusLogger的初始“listenersLevel”。如果添加了StatusLogger侦听器,则“listenerLevel”将更改为最详细的侦听器的“listenerLevel”。如果注册了任何侦听器,则listenerLevel用于快速确定是否存在感兴趣的侦听器。

默认情况下,在找到配置时以及由JMX StatusLoggerAdmin MBean添加StatusLogger侦听器。例如,如果配置包含<Configuration status="trace">,则会注册一个具有statusLevel TRACE的侦听器,并且StatusLogger listenerLevel将设置为TRACE,从而导致在控制台上显示详细的状态消息。

如果未注册任何侦听器,则不会使用listenersLevel,并且StatusLogger输出级别由StatusLogger.getLogger().getLevel()确定(请参阅属性org.apache.logging.log4j .simplelog.StatusLogger.level)。

log4j2.statusEntries
(log4j2.status.entries)
LOG4J_STATUS_ENTRIES 200 StatusLogger 事件在缓冲区中保留的数量,可以通过 StatusLogger.getStatusData() 获取。
log4j2.statusLoggerDateformat
(log4j2.StatusLogger.DateFormat)
LOG4J_STATUS_LOGGER_DATEFORMAT   用于状态记录器输出中时间戳格式的日期时间格式字符串。有关支持的格式,请参见 java.text.SimpleDateFormat
log4j2.asyncLoggerExceptionHandler
(AsyncLogger.ExceptionHandler)
LOG4J_ASYNC_LOGGER_EXCEPTION_HANDLER 默认处理程序 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerRingBufferSize
(AsyncLogger.RingBufferSize)
LOG4J_ASYNC_LOGGER_RING_BUFFER_SIZE 在无垃圾模式下为 256 * 1024 或 4 * 1024 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerWaitStrategy
(AsyncLogger.WaitStrategy)
LOG4J_ASYNC_LOGGER_WAIT_STRATEGY 超时 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerTimeout
(AsyncLogger.Timeout)
LOG4J_ASYNC_LOGGER_TIMEOUT 10 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerSleepTimeNs
(AsyncLogger.SleepTimeNs)
LOG4J_ASYNC_LOGGER_SLEEP_TIME_NS 100 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerRetries
(AsyncLogger.Retries)
LOG4J_ASYNC_LOGGER_SLEEP_TIME_NS 200 有关详细信息,请参见 异步记录器系统属性
AsyncLogger.SynchronizeEnqueueWhenQueueFull ASYNC_LOGGER_SYNCHRONIZE_ENQUEUE_WHEN_QUEUE_FULL true 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerThreadNameStrategy
(AsyncLogger.ThreadNameStrategy)
LOG4J_ASYNC_LOGGER_THREAD_NAME_STRATEGY 缓存 有关详细信息,请参见 异步记录器系统属性
log4j2.asyncLoggerConfigExceptionHandler
(AsyncLoggerConfig.ExceptionHandler)
LOG4J_ASYNC_LOGGER_CONFIG_EXCEPTION_HANDLER 默认处理程序 有关详细信息,请参见 混合异步/同步记录器系统属性
log4j2.asyncLoggerConfigRingBufferSize
(AsyncLoggerConfig.RingBufferSize)
LOG4J_ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE 在无垃圾模式下为 256 * 1024 或 4 * 1024 有关详细信息,请参见 混合异步/同步记录器系统属性
log4j2.asyncLoggerConfigWaitStrategy
(AsyncLoggerConfig.WaitStrategy)
LOG4J_ASYNC_LOGGER_CONFIG_WAIT_STRATEGY 超时 有关详细信息,请参见 混合异步/同步记录器系统属性
AsyncLoggerConfig.SynchronizeEnqueueWhenQueueFull ASYNC_LOGGER_CONFIG_SYNCHRONIZE_ENQUEUE_WHEN_QUEUE_FULL true 有关详细信息,请参见 混合异步/同步记录器系统属性
log4j2.julLoggerAdapter
(log4j.jul.LoggerAdapter)
LOG4J_JUL_LOGGER_ADAPTER org.apache.logging.log4j .jul.ApiLoggerAdapter JUL 适配器中使用的默认 LoggerAdapter。默认情况下,如果 log4j-core 可用,则将使用类 org.apache.logging.log4j.jul .CoreLoggerAdapter。否则,将使用 ApiLoggerAdapter。自定义实现必须提供一个公共默认构造函数。
log4j2.formatMsgAsync
(log4j.format.msg.async)
LOG4J_FORMAT_MSG_ASYNC false 如果为 false(默认值),Log4j 将确保在调用方线程中格式化消息,以确保调用记录器时的值是记录的值。
log4j2.asyncQueueFullPolicy
(log4j2.AsyncQueueFullPolicy)
LOG4J_ASYNC_QUEUE_FULL_POLICY  

异步记录器和 AsyncAppender 使用它来维护应用程序吞吐量,即使底层追加器无法跟上记录速率并且队列正在填满。

如果没有指定值(默认值),则永远不会丢弃事件。如果队列已满,则记录器调用将阻塞,直到可以将事件添加到队列中。

指定 Discard 以丢弃队列已满时级别等于或小于阈值级别(默认情况下为 INFO)的事件。

log4j2.discardThreshold
(log4j2.DiscardThreshold)
LOG4J_DISCARD_THRESHOLD 信息 DiscardingAsyncQueueFullPolicy 使用它来确定队列已满时要丢弃哪些事件。默认情况下,当队列已满时,将丢弃 INFODEBUGTRACE 级别事件。此属性仅在将 Discard 指定为 log4j2.AsyncQueueFullPolicy 时有效。
log4j2.messageFactory
(log4j2.messageFactory)
LOG4J_MESSAGE_FACTORY 在无垃圾模式下为 org.apache.logging.log4j.message. ParameterizedMessageFactory 或 org.apache.logging.log4j.message. ReusableMessageFactory 如果未指定工厂,则记录器使用的默认消息工厂。
log4j2.flowMessageFactory
(log4j2.flowMessageFactory)
LOG4J_FLOW_MESSAGE_FACTORY org.apache.logging.log4j.message. DefaultFlowMessageFactory 记录器使用的默认流消息工厂。
log4j2.isWebapp
(log4j2.is.webapp)
LOG4J_IS_WEBAPP 如果类路径上存在 Servlet 类,则为 true 此系统属性可用于强制 Log4j 2 就像它是 Web 应用程序的一部分(当为 true 时)或就像它不是 Web 应用程序的一部分(当为 false 时)一样运行。
log4j2.enableThreadlocals
(log4j2.enable.threadlocals)
LOG4J_ENABLE_THREADLOCALS true 此系统属性可用于关闭 threadlocals 的使用,这将部分禁用 Log4j 的无垃圾行为:要完全无垃圾,Log4j 将对象存储在 ThreadLocal 字段中以重用它们,否则将为每个日志事件创建新对象。请注意,当 Log4j 检测到它在 Web 应用程序中运行时,此属性无效。
log4j2.enableDirectEncoders
(log4j2.enable.direct.encoders)
LOG4J_ENABLE_DIRECT_ENCODERS true 此属性可用于强制垃圾感知布局和追加器恢复到 2.6 之前的行为,其中将日志事件转换为文本会生成临时对象,如字符串和 char[] 数组,并将此文本转换为字节会生成临时 byte[] 数组。默认情况下,此属性为 true,并且将日志事件转换为文本的垃圾感知布局和追加器将在此文本转换为字节时不会创建临时对象。
log4j2.initialReusableMsgSize
(log4j.initialReusableMsgSize)
LOG4J_INITIAL_REUSABLE_MSG_SIZE 128 在无 GC 模式下,此属性确定可重用 StringBuilder 的初始大小,其中格式化消息文本并可能传递给后台线程。
log4j2.maxReusableMsgSize
(log4j.maxReusableMsgSize)
LOG4J_MAX_REUSABLE_MSG_SIZE 518 在无 GC 模式下,此属性确定可重用 StringBuilder 的最大大小,其中格式化消息文本并可能传递给后台线程。
log4j2.layoutStringBuilderMaxSize
(log4j.layoutStringBuilder.maxSize)
LOG4J_LAYOUT_STRING_BUILDER_MAX_SIZE 2048 此属性确定线程本地可重用 StringBuilder 的最大大小,用于通过扩展 AbstractStringLayout 的布局将日志事件格式化为文本。
log4j2.unboxRingbufferSize
(log4j.unbox.ringbuffer.size)
LOG4J_UNBOX_RINGBUFFER_SIZE 32 org.apache.logging.log4j.util.Unbox 实用程序管理一个小的线程本地 StringBuilder 环形缓冲区。每次调用 box() 方法时,都会使用环形缓冲区中的下一个插槽,直到环形缓冲区已满并重新使用第一个插槽。默认情况下,Unbox 环形缓冲区有 32 个插槽,因此用户代码可以在单个记录器调用中最多有 32 个装箱的基元。

如果需要更多插槽,请将系统属性 log4j.unbox.ringbuffer.size 设置为所需的环形缓冲区大小。请注意,指定的值将向上舍入到最接近的 2 的幂。

log4j2.loggerContextStacktraceOnStart
(log4j.LoggerContext.stacktrace.on.start)
LOG4J_LOGGER_CONTEXT_STACKTRACE_ON_START false 在 DEBUG 级别将堆栈跟踪打印到 状态记录器,当 LoggerContext 启动时。用于调试目的。
log4j2.trustStoreLocation LOG4J_TRUST_STORE_LOCATION 信任存储的位置。如果未提供,将使用默认信任存储。
log4j2.trustStorePassword LOG4J_TRUST_STORE_PASSWORD 访问信任存储所需的密码。
log4j2.trustStorePasswordFile LOG4J_TRUST_STORE_PASSWORD_FILE 包含信任存储密码的文件的位置。
log4j2.trustStorePasswordEnvironmentVariable LOG4J_TRUST_STORE_PASSWORD_ENVIRONMENT_VARIABLE 包含信任存储密码的环境变量的名称。
log4j2.trustStoreType LOG4J_TRUST_STORE_TYPE 用于信任存储的密钥存储类型。
log4j2.trustStoreKeyManagerFactoryAlgorithm LOG4J_TRUST_STORE_KEY_MANAGER_FACTORY_ALGORITHM Java 密码算法。
log4j2.keyStoreLocation LOG4J_KEY_STORE_LOCATION 密钥存储的位置。如果未提供,将使用默认密钥存储。
log4j2.keyStorePassword LOG4J_KEY_STORE_PASSWORD 访问密钥存储所需的密码。
log4j2.keyStorePasswordFile LOG4J_KEY_STORE_PASSWORD_FILE 包含密钥存储密码的文件的位置。
log4j2.keyStorePasswordEnvironmentVariable LOG4J_KEY_STORE_PASSWORD_ENVIRONMENT_VARIABLE 包含密钥存储密码的环境变量的名称。
log4j2.keyStoreType LOG4J_KEY_STORE_TYPE 密钥存储的类型。
log4j2.keyStoreKeyManagerFactoryAlgorithm LOG4J_KEY_STORE_KEY_MANAGER_FACTORY_ALGORITHM Java 密码算法。
log4j2.sslVerifyHostName false 如果应验证主机名,则为 true 或 false
log4j2.Script.enableLanguages 允许执行的脚本语言列表。指定的名称必须安装有 ScriptEngine,并且该 ScriptEngine 在广告中使用相同的语言,才能启用脚本。如果没有指定语言,这是默认设置,则不会安装 ScriptManager。
log4j2.disableCloudConfigLoggingSystem 禁用 Spring Boot Log4j2CloudConfigLoggingSystem 的使用。默认为 false