美文网首页
log4j2使用手册(中文)第五章 Configuration

log4j2使用手册(中文)第五章 Configuration

作者: 在下喵星人 | 来源:发表于2019-07-18 10:53 被阅读0次

    Configuration

    将日志输出插入到应用程序代码需要相当多的计划和努力。 观察显示,大约4%的代码专用于日志记录。 因此,甚至中等大小的应用程序将在其代码中嵌入数千个日志记录语句。 鉴于它们的数量,必须管理这些日志语句而无需手动修改它们。

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

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

    该章节主要侧重于通过配置文件配置Log4j。 有关以编程方式配置Log4j的信息,请参阅Extending Log4j 2和Programmatic Log4j configuration章节。
    请注意,与Log4j 1.x不同,Log4j 2 API不暴露任何添加,修改或删除appender和filters或以任何方式操作配置文件的方法。

    自动配置

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

    1. Log4j将检查“log4j.configurationFile”系统属性,如果设置,将尝试使用与文件扩展名匹配的ConfigurationFactory加载配置。
    2. 如果未设置系统属性,则properties 的ConfigurationFactory将在类路径中查找log4j2-test.properties。
    3. 如果没有找到这样的文件,YAML的ConfigurationFactory将在类路径中查找log4j2-test.yaml或log4j2-test.yml
    4. 如果没有找到这样的文件,JSON的ConfigurationFactory将在类路径中查找log4j2-test.json或log4j2-test.jsn
    5. 如果没有找到这样的文件,XML ConfigurationFactory将在类路径中查找log4j2-test.xml。
    6. 如果找不到test文件,ConfigurationFactory属性将在类路径上查找log4j2.properties。
    7. 如果找不到properties文件,YAML ConfigurationFactory将查找
      类路径上的log4j2.yaml或log4j2.yml。
    8. 如果找不到YAML文件,JSON ConfigurationFactory将在类路径上查找log4j2.json或log4j2.jsn
    9. 如果找不到JSON文件,XML ConfigurationFactory将尝试在类路径上找到log4j2.xml。
    10. 如果找不到配置文件,则将使用DefaultConfiguration。 这将
      导致日志输出转到控制台。

    使用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的静态Logger变量,该变量恰好是类的完全限定名。

    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将提供默认配置。在默认配置类中提供的默认配置将设置:

    • PatternLayout绑定到ConsoleAppender,并设置模式“%d {HH:mm:ss.SSS} [%t]%-5level%logger {36} - %msg%n”

    请注意,默认情况下,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放入类路径后,您将获得与上面列出的结果相同的结果。 将根级别更改为trace将导致结果类似于:

    17:13:01.540 [main] TRACE MyApp - Entering application.
    17:13:01.540 [main] TRACE com.foo.Bar - entry
    17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
    17:13:01.540 [main] TRACE com.foo.Bar - exit with (false)
    17:13:01.540 [main] ERROR MyApp - Didn't do it.
    17:13:01.540 [main] TRACE MyApp - Exiting application.
    

    可加性

    也许你希望从com.foo.Bar之外的所有内容中删除所有TRACE输出。 简单地更改日志级别将无法完成任务。 相反,解决方案是在配置中添加新的Logger定义:

    <Logger name="com.foo.Bar" level="TRACE"/>
    <Root level="ERROR">
    <AppenderRef ref="STDOUT">
    </Root>
    

    使用此配置,将记录来自com.foo.Bar的所有日志事件,同时仅记录来自所有其他组件的错误事件。

    在前面的示例中,com.foo.Bar中的所有事件仍写入控制台。 这是因为com.foo.Bar的记录器没有配置任何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>
    

    将输出一下日志

    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的Trace消息会出现两次。 这是因为首先使用与logger com.foo.Bar关联的appender,它将第一个实例写入Console。 接下来,引用com.foo.Bar的父级,在本例中是root录器。 然后将事件传递给它的appender,它也会写入Console,从而产生第二个实例。 这被称为可加性。 虽然可加性可以是一个非常方便的功能(如前面的第一个示例,其中不需要配置appender引用),但在许多情况下,此行为被认为是不合需要的,因此可以通过将记录器上的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>
    

    一旦事件到Logger且其可加性设置为false,该事件将不会传递给任何其父记Logger,无论其可加性如何设置。

    自动重新配置

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

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

    配置语法

    从版本2.9开始,出于安全原因,Log4j不处理XML文件中的DTD。 如果要将配置拆分为多个文件,请使用XIncludeComposite Configuration

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

    XML文件中的configuration元素接受以下几个属性:

    属性名 描述
    advertiser (可选)广告商插件名称,用于通告单个FileAppender或SocketAppender配置。 唯一提供的广告商插件是'multicastdns'
    dest “err”,它将输出发送到stderr,或文件路径或URL。
    monitorInterval 检查文件配置更改之前必须经过的最短时间(以秒为单位)。
    name 配置的名称
    packages 以逗号分隔的包名称列表,用于搜索插件。 每个类加载器只加载一次插件,因此更改此值可能对重新配置没有任何影响
    scheme 标识类加载器的位置,以定位用于验证配置的XML架构。 仅在strict设置为true时有效。 如果未设置,则不会进行架构验证
    shutdownHook 指定在JVM关闭时Log4j是否应自动关闭。 默认情况下启用关闭,但可以通过将此属性设置为“disable”来禁用
    shutdownTimeout 指定JVM关闭时,多少毫秒关闭appender和后台任务。 默认值为零,表示每个appender使用其默认超时时间,并且不等待后台任务。 并非所有的appender都会尊重这一点,这是一个提示,并不是绝对保证关闭程序不会花费更长时间。 将此设置得太低会增加丢失尚未写入最终目标的未完成日志事件的风险。 请参阅LoggerContext.stop(long,java.util.concurrent.TimeUnit)。 (如果没有使用shutdownHook设置为“disable”。)
    status 应记录到控制台的内部Log4j事件的级别。 此属性的有效值为“trace”,“debug”,“info”,“warn”,“error”和“fatal”。 Log4j会将有关初始化,rollover和其他内部操作的详细信息记录到状态记录器。 如果您需要对log4j进行故障排除,可以设置status =“trace”或者,设置系统属性log4j2.debug也会将内部Log4j2日志记录打印到控制台,包括在找到配置文件之前发生的内部日志记录。)
    strict 允许使用严格的XML格式。 JSON配置不支持
    verbose 加载插件时启用诊断信息

    可以使用两种XML风格配置Log4j简洁和严谨。 简洁的格式使配置非常简单,因为元素名称与它们所代表的组件相匹配,但它不能用XML验证。 例如,通过在其父appenders元素下声明名为Console的XML元素来配置ConsoleAppender。 但是,元素和属性名称不区分大小写。 此外,可以将属性指定为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>
    

    有关示例appender、filter 和logger声明,请参阅本本节示例。

    严格XML

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

    除了XML之外,还可以使用JSON配置Log4j。 JSON格式与简洁的XML格式非常相似。 每个键代表插件的名称,与之关联的键/值对是其属性。 如果一个键包含的不仅仅是一个简单的值,那么它本身就是一个从属插件。 在下面的示例中,ThresholdFilter,Console和PatternLayout都是插件,而Console插件的名称属性将被赋予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组件。 这对于诸如appender和filters之类的元素不起作用,其中每个元素在简明格式中具有不同的名称。 如果每个appender或filters声明一个名为 appender的“type”的属性,则可以将appenders和filter定义为数组元素。 以下示例说明了这一点以及如何将多个logger声明为数组.

    { "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
          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配置文件需要额外的运行时依赖。

    使用Properties配置

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

    在2.6版本之前,properties配置要求在具有这些名称的属性中以逗号分隔的列表列出appenders、 filters和logger的标识符。然后,些组件中的每一个都以组件开头的属性集定义。标识符不必匹配正在定义的组件的名称,但必须唯一地标识所有属性和子组件, 是组件的一部分。如果标识符列表不存在,则标识符必须不包含'.'。每个组件必须有一个指定的“type”属性来标识组件的插件类型。

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

    与基本组件不同,在创建子组件时,您无法指定包含标识符列表的元素。 相反,您必须使用其类型定义包装器元素,如下面的RollingFileappender中的策略定义中所示。 然后定义该包装元素下面的每个子组件,下面定义了TimeBasedTriggeringPolicy和SizeBasedTriggeringPolicy。

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

    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.name = com.example.my.app
    logger.rolling.level = debug
    logger.rolling.additivity = false
    logger.rolling.appenderRef.rolling.ref = RollingFile
     
    rootLogger.level = info
    rootLogger.appenderRef.stdout.ref = STDOUT
    

    配置Loggers

    在尝试配置Log4j之前,了解Log4j如何在Log4j中工作至关重要。 如果需要更多信息,请参考Log4j架构章节。 试图在不理解这些概念的情况下配置Log4j可能不会成功。使用logger元素配置LoggerConfig。 logger元素必须具有指定的name属性,通常会指定level属性,并且还可以指定additivity属性。 可以使用TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF之一日志级别。 如果未指定日志级别,则默认为ERROR。 可以为additivity属性分配值true或false。 如果省略该属性,则将使用默认值true。
    LoggerConfig(包括root LoggerConfig)可以配置properties,这些properties将添加到从ThreadContextMap复制的属性中。 可以从Appenders,Filters,Layouts等引用这些properties,就像它们是ThreadContext Map的一部分一样。 这些properties可以包含将在解析配置时解析的变量,也可以包含在记录每个事件时动态解析的变量。 有关使用变量的更多信息,请参见属性替换章节
    LoggerConfig还可以配置一个或多个AppenderRef元素。 引用的每个appender将与指定的LoggerConfig关联。 如果在LoggerConfig上配置有多个appender,在处理日志记录事件时,每个都会被调用。
    如果未配置,则将使用默认根LoggerConfig,其级别为ERROR且绑定了一个Console appender。 根记录器和其他记录器之间的主要区别是

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

    配置Appender

    使用特定的appender插件的名称或appender元素以及包含appender插件名称的type属性配置appender。 此外,每个appender必须具有一个name属性,该属性的值在appender集中是唯一的。如上一节中所述,loggers将使用该名称来引用appender。
    大多数appender还支持layout(可以使用特定的Layout插件的名称作为元素或使用“layout”作为元素名称以及包含layout插件名称的type属性来指定布局。各种appender将包含其正常运行所需的其他属性或元素。

    配置过滤器

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

    1. 与appender,loggers和properties元素处于同一级别。 这些过滤器可以在将事件传递给LoggerConfig之前接受或拒绝事件。
    2. 在Logger元素中。 这些过滤器可以接受或拒绝特定Logger的事件。
    3. 在一个appender元素。 这些过滤器可以防止或导致事件由appender处理。
    4. 在appender引用元素中。 这些过滤器用于确定Logger是否应将事件路由到appender。

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

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

    属性替换

    Log4j 2支持在配置中指定标记,引用其他地方定义的属性。 解释配置文件时将解析其中一些属性,而其他属性可能会在运行才解析。为了实现这一功能,Log4j使用了Apache Commons Lang的StrSubstitutor和StrLookup类的变体。这个与Ant或Maven中的方式相似。这允许使用配置本身中声明的属性来解析声明为$ {name}的变量。例如,以下示例RollingFile的fileName在property中被声明。

    <?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该变量应在特定上下文中声明。 更多的详细信息,请参阅“Lookups”手册页。 Logj4内置的上下文是:

    前缀 上下文
    bundle 资源包。格式${bundle:BundleName:BundleKey}.bundle遵循package约定,例如${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”将返回消息类型。 其他键将从Map中检索单个元素。
    sys 系统属性。 格式是$ {sys:some.property}和$ {sys:some.property:default_value}

    默认属性

    可以在任何Loggers,Filters,Appender等之后和之前直接放置Properties元素,并且在Properties中声明默认属性映射。如果无法在指定的lookup 中找到该值,则将使用默认属性映射中的值。 默认映射预先填充了“hostName”的值,该值是当前系统的主机名或IP地址,“contextName”是当前日志记录上下文的值。 有关示例,请参阅本节中使用的Properties元素。

    具有多个前导’$’字符的Lookup变量

    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 appender声明中的变量。 这只是因为整个RollingFile元素的解析被推迟到匹配到值时。 有关更多信息,请参阅RoutingAppender

    脚本

    Log4j支持在某些组件中使用JSR 223脚本语言。 可以使用任何为JSR 223脚本引擎提供支持的语言。 可以在Scripting Engine网站上找到它们的语言和绑定列表。 但是,其中列出的一些语言(如JavaScript,Groovy和Beanshell)直接支持JSR 223脚本框架,并且只需要引入该语言的jar包。

    支持使用脚本的组件,通过在这些组件上配置<script>、<scriptFile>或<scriptRef>元素来实现这一点。 script元素包含脚本的名称,脚本的语言和脚本文本。 scriptFile元素包含脚本的名称,位置,语言,字符集以及是否应该监视文件的更改。 scriptRef元素包含配置元素中定义的脚本的名称。脚本的名称用于存储脚本及其ScriptEngine,因此每次需要运行脚本时都可以快速找到它。虽然名称不是必需的,但提供它将有助于在脚本运行时调试问题。必须在脚本元素上提供使用的语言,并且必须指定配置状态日志中显示的语言名称之一,如下一节中所述。 如果未在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将返回脚本中执行的最后一个语句的值。 因此,如下所示的代码将发回result值。

     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脚本。

    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上逗号分隔文件路径的列表。可以通过在log4j.mergeStrategy属性上指定实现MergeStrategy接口的类来控制合并逻辑。 默认合并策略将使用以下规则合并文件:

    1. 除了使用最高状态级别和最低monitorInterval大于0之外,全局配置属性将与后面配置中的属性进行聚合,前面配置的属性会被后面配置的属性覆盖。
    2. 汇总properties所有配置的属性,,如果有重复属性将替换先前配置中的属性。
    3. 如果定义了多个Filter,则在CompositeFilter下聚合过滤器。 由于过滤器未命名,因此可能存在重复项。
    4. Scripts和ScriptFile引用将被合并。 重复定义将替换先前配置中的定义。
    5. Appenders将被合并。 具有相同名称的Appender将替换为后续配置中的Appender,包括所有Appender的子组件。
    6. Logger将被合并。 Logger属性单独合并,重复项将替换为后续配置中的重复项。 Logger上的Appender引用将与后续配置中的重复项进行合并。 如果定义了多个Filter,则会在CompositeFilter下合并Logger上的过滤器。 由于过滤器未命名,因此可能存在重复项。 包含或丢弃Appender引用下的过滤器,具体取决于是保留还是丢弃其父Appender引用。

    状态消息

    故障排除提示:
    从log4j-2.9开始,如果定义了系统属性log4j2.debug(可以配置任何值或不配置值),log4j2将打印所有内部日志记录到控制台。
    
    在log4j-2.9之前,有两个地方可以控制内部日志记录:
        - 在找到配置之前,可以使用系统属性org.apache.logging.log4j.simplelog.StatusLogger.level控制状态记录器级别。
       - 找到配置后,可以使用“status”属性在配置文件中控制状态记录器级别,例如:<Configuration status =“trace”>
    

    正如希望能够诊断应用程序中的问题一样,通常需要能够诊断日志记录配置或配置的组件中的问题。由于尚未配置日志记录,因此在初始化期间不能使用“正常”日志记录。 此外,appender中的正常日志记录可能会创建无限递归,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,则仅将错误消息写入控制台。 这样可以排除配置错误。 例如,如果将上面的配置更改为将状态设置为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放入放置在src / test / resources中将导致使用它而不是可能存在的log4j2.xml或log4j2.json。因此,在测试期间可以使用与生产中使用的不同的日志配置。

    Log4j 2广泛使用的第二种方法是在junit测试类中使用@BeforeClass注释的方法中设置log4j.configurationFile属性。 这将允许在测试期间使用任意命名的文件。

    Log4j 2广泛使用的第三种方法是使用LoggerContextRule JUnit的@Rule注解,该注解为测试提供了额外的便利方法。 这需要将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机制添加其他属性源类。

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

    Source 优先级 描述
    环境变量 -100 环境变量都以LOG4J_为前缀,全部大写,单词全部用下划线分隔。 只有这个命名方案才支持环境变量,因为没有旧的命名方案来保持与之的兼容性。
    log4j2.component.properties 文件 0 在类路径中包含此文件可用作提供属性作为系统属性的替代方法。 这优先于系统属性,但它们可以被环境变量覆盖,如上所述
    系统属性 100 可以使用常规系统属性模式设置所有属性。 它们具有最低优先级,可以被包含的属性文件或环境变量覆盖。

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

    参数名称(旧参数名称) 环境变量 默认值 描述
    log4j2.configurationFile (log4j.configurationFile) LOG4J_CONFIGURATION_FILE Log4j 2配置文件的路径。 也可以包含逗号分隔的配置文件名列表。
    log4j2.debug (log4j2.debug) LOG4J_DEBUG 如果定义了系统属性log4j2.debug(具有任何值或没有值),Log4j2将打印所有内部日志记录到控制台。
    log4j2.mergeFactory (log4j.mergeFactory) LOG4J_MERGE_FACTORY 实现MergeStrategy接口的类的名称。 如果未指定,则在创建CompositeConfiguration时将使用DefaultMergeStrategy
    log4j2.contextSelector (Log4jContextSelector) LOG4J_CONTEXT_SELECTOR ClassLoaderContextSelector 创建LoggerContexts。 应用程序可以具有一个或多个活动LoggerContexts,具体取决于具体情况。 有关详细信息>,请参阅日志分隔。 可用上下文选择器实现类:org.apache.logging.log4j.core.async .AsyncLoggerContextSelector - 使所有记录器异步。org.apache.logging.log4j.core.selector .BasicContextSelector - 创建单个共享LoggerContext。org.apache.logging.log4j.core.selector .ClassLoaderContextSelector - 为每个Web应用程序分离LoggerContexts。org.apache.logging.log4j.core.selector .JndiContextSelector - 使用JNDI查找每个Web应用程序的LoggerContext。org.apache.logging.log4j.core.osgi .BundleContextSelector - 为每个OSGi包分离LoggerContexts。
    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.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映射garbage-free
    log4j2.disableJmx (log4j2.disable.jmx) LOG4J_DISABLE_JMX false 如果为true,则LoggerContexts,Appenders,Loggers等Log4j配置对象将不会使用MBean进行检测,并且无法进行远程监视和管理。
    log4j2.jmxNotifyAsync (log4j2.jmx.notify.async) LOG4J_JMX_NOTIFY_ASYNC 对于Web应用程序为false,否则为true 如果为true,则log4j的JMX通知从单独的后台线程发送,否则它们将从调用者线程发送。 如果系统属>性log4j2.is.webapp为true或javax.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.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.showdatetime为false,则忽略。
    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 default log level 具有指定名称的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,StatusLogger可以将状态日志事件从默认控制台输出重定向到文件。 监听器还支持细粒度过滤。 如果配置未指定状态级别,则此系统属性指定侦听器要使用的默认状态日志级别。注意:只有在找到配置文件后,log4j-core实现才会使用此属性。
    log4j2.statusLoggerLevel (log4j2.StatusLogger.level) LOG4J_STATUS_LOGGER_LEVEL WARN StatusLogger的初始“listenersLevel”。 如果添加了StatusLogger侦听器,则“listenerLevel”将更改为最详细的侦听器。 如果注册了任何侦听器,则使用listenerLevel快速确定是否存在感兴趣的侦听器。默认情况下,在找到配置时添加StatusLogger侦听器,并通过JMX StatusLoggerAdmin MBean添加。 例如,如果配置包含<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 default handler 有关详细信息,请参阅Async Logger系统属性
    log4j2.asyncLoggerRingBufferSize (AsyncLogger.RingBufferSize) LOG4J_ASYNC_LOGGER_RING_BUFFER_SIZE 256 * 1024 有关详细信息,请参阅Async Logger系统属性
    log4j2.asyncLoggerWaitStrategy (AsyncLogger.WaitStrategy) LOG4J_ASYNC_LOGGER_WAIT_STRATEGY Timeout 有关详细信息,请参阅Async Logger系统属性
    log4j2.asyncLoggerThreadNameStrategy (AsyncLogger.ThreadNameStrategy) LOG4J_ASYNC_LOGGER_THREAD_NAME_STRATEGY CACHED 有关详细信息,请参阅Async Logger系统属性
    log4j2.asyncLoggerConfigExceptionHandler (AsyncLoggerConfig.ExceptionHandler) LOG4J_ASYNC_LOGGER_CONFIG_EXCEPTION_HANDLER default handler 有关详细信息,请参阅混合异步/同步记录器系统属性
    log4j2.asyncLoggerConfigRingBufferSize (AsyncLoggerConfig.RingBufferSize) LOG4J_ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE 256 * 1024 有关详细信息,请参阅混合异步/同步记录器系统属性
    log4j2.asyncLoggerConfigWaitStrategy (AsyncLoggerConfig.WaitStrategy) LOG4J_ASYNC_LOGGER_CONFIG_WAIT_STRATEGY Timeout 有关详细信息,请参阅混合异步/同步记录器系统属性
    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。 否则,将使用ApiLogggerAdapter。 自定义实现必须提供公共默认构造函数。
    log4j2.formatMsgAsync (log4j.format.msg.async) LOG4J_FORMAT_MSG_ASYNC false 如果为false(默认值),Log4j将确保在调用者线程中格式化消息,以确保在调用logger时的值是记录的值
    log4j2.asyncQueueFullPolicy (log4j2.AsyncQueueFullPolicy) LOG4J_ASYNC_QUEUE_FULL_POLICY 由Async Loggers和AsyncAppender用于维护应用程序吞吐量,即使底层appender无法跟上日志记录速率并且队列正在填满。如果>未指定任何值(默认值),则永远不会丢弃事件。 如果队列已满,则记录器调用将阻塞,直到可以将事件添加到队列中。指定Discard在队列已满时删除级别等于或小于阈值级别(默认为INFO)的事件。
    log4j2.discardThreshold (log4j2.DiscardThreshold) LOG4J_DISCARD_THRESHOLD INFO DiscardingAsyncQueueFullPolicy使用它来确定队列变满时要删除的事件。 默认情况下,当队列已满时,将丢弃INFO,DEBUG和TRACE级别>事件。 仅当Discard指定为log4j2.AsyncQueueFullPolicy时,此属性才有效。
    log4j2.messageFactory (log4j2.messageFactory) LOG4J_MESSAGE_FACTORY org.apache.logging.log4j.message. ParameterizedMessageFactory or org.apache.logging.log4j.message. ReusableMessageFactory in garbage-free mode 如果未指定工厂,则Loggers使用默认消息工厂。
    log4j2.flowMessageFactory (log4j2.flowMessageFactory) LOG4J_FLOW_MESSAGE_FACTORY org.apache.logging.log4j.message. DefaultFlowMessageFactory Loggers使用的默认流消息工厂。
    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 此属性可用于强制垃圾感知布局和Appender恢复到2.6之前的行为,其中将日志事件转换为文本生成临时对象(如字符串和char []数组),并将此文本转换为字节会生成临时byte []数组。 默认情况下,此属性为true,将日志事件转换为文本的垃圾感知布局和附加程序将此文本转换为字节而不创建临时对象。
    log4j2.initialReusableMsgSize (log4j.initialReusableMsgSize) LOG4J_INITIAL_REUSABLE_MSG_SIZE 128 在无GC模式下,此属性确定可重用StringBuilders的初始大小,其中消息文本已格式化并可能传递给后台线程。
    log4j2.maxReusableMsgSize (log4j.maxReusableMsgSize) LOG4J_MAX_REUSABLE_MSG_SIZE 518 在无GC模式下,此属性确定消息文本格式化并可能传递给后台线程的可重用StringBuilders的最大大小。
    log4j2.layoutStringBuilderMaxSize (log4j.layoutStringBuilder.maxSize) LOG4J_LAYOUT_STRING_BUILDER_MAX_SIZE 2048 此属性确定用于通过扩展AbstractStringLayout的布局将日志事件格式化为文本的线程局部可重用StringBuilders的最大大小。
    log4j2.unboxRingbufferSize (log4j.unbox.ringbuffer.size) LOG4J_UNBOX_RINGBUFFER_SIZE 32 org.apache.logging.log4j.util.Unbox实用程序管理StringBuilders的小型线程本地环形缓冲区。 每次调用其中一个box()方法时,都会使用环形缓冲区中的下一个插槽,直到环形缓冲区已满并重新使用第一个插槽。 默认情况下,Unbox环形缓冲区有32个插槽,因此用户代码在一次记录器调用中最多可以有32个盒装基元。如果需要更多插槽,请将系统属性log4j.unbox.ringbuffer.size设置为所需的环形缓冲区大小。 请注意,指定的数字将向上舍入到最接近的2的幂。
    log4j2.loggerContextStacktraceOnStart (log4j.LoggerContext.stacktrace.on.start) LOG4J_LOGGER_CONTEXT_STACKTRACE_ON_START false 在启动LoggerContext时,将堆栈跟踪打印到DEBUG级别的状态记录器。 用于调试目>的。
    log4j2.formatMsgNoLookups (log4j2.formatMsgNoLookups) FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS false 设置为true时,全局禁用消息模式查找。 这相当于使用%m {nolookups}定义所有消息模式。

    相关文章

      网友评论

          本文标题:log4j2使用手册(中文)第五章 Configuration

          本文链接:https://www.haomeiwen.com/subject/lamsoqtx.html