Plugins

Introduction

通过在大多数配置声明中要求类属性,允许扩展 Log4j1.x。对于某些元素,尤其是 PatternLayout,添加新的模式转换器的唯一方法是扩展 PatternLayout 类并通过代码添加它们。 Log4j 2 的一个目标是通过使用插件来使其扩展极其容易。

在 Log4j 2 中,通过在类声明中添加@PluginComments 来声明插件。在初始化期间,Configuration将调用PluginManager来加载内置的 Log4j 插件以及所有自定义插件。 PluginManager 通过在五个位置查找来找到插件:

  • Classpath 上的序列化插件列表文件。这些文件是在构建过程中自动生成的(下面有更多详细信息)。

  • (仅 OSGi)每个活动 OSGiBinding 包中的序列化插件列表文件。在激活后添加了 BundleListener,以在 log4j-core 启动后 continue 检查新的 Binding 软件。

  • 由 log4j.plugin.packages 系统属性指定的软件包的逗号分隔列表。

  • 程序包传递给静态 PluginManager.addPackages 方法(在进行 Log4j 配置之前)。

  • 在 log4j2 配置文件中声明的packages

如果多个插件指定了相同的名称(不区分大小写),则上述加载 Sequences 将确定将使用哪个插件。例如,要覆盖内置 FileAppender 类提供的 File 插件,您需要将插件放在 LOG4j-core.jar 之前的 CLASSPATH 中的 JAR 文件中。不建议这样做;插件名称冲突将导致发出警告。请注意,在 OSGi 环境中,扫描 Binding 软件插件的 Sequences 通常遵循将 Binding 软件安装到框架中的 Sequences。参见getBundles()SynchronousBundleListener。简而言之,在 OSGi 环境中,名称冲突甚至更加不可预测。

序列化的插件列表文件由 log4j-core 工件中包含的 Comments 处理器生成,该 Comments 处理器将自动扫描代码以查找 Log4j 2 插件,并在处理的类中输出元数据文件。无需任何额外操作即可实现此目的。 Java 编译器将自动在 Classpath 上使用 Comments 处理器,除非您明确禁用它。在这种情况下,将另一个编译器遍历添加到仅使用 Log4j 2Comments 处理器类 org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor 进行 Comments 处理的构建过程中就很重要。要使用 Apache Maven 做到这一点,请将以下执行添加到您的 maven-compiler-plugin(版本 2.2 或更高版本)构建插件中:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.1</version>
  <executions>
    <execution>
      <id>log4j-plugin-processor</id>
      <goals>
        <goal>compile</goal>
      </goals>
      <phase>process-classes</phase>
      <configuration>
        <proc>only</proc>
        <annotationProcessors>
          <annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
        </annotationProcessors>
      </configuration>
    </execution>
  </executions>
</plugin>

处理完配置后,将自动配置和初始化相应的插件。 Log4j 2 使用了几种不同类别的插件,以下各节对此进行了介绍。

Core

核心插件是由配置文件中的元素直接表示的插件,例如 Appender,Layout,Logger 或 Filter。符合下一节中列出的规则的自定义插件可以在配置中简单引用,只要将它们适当配置为由 PluginManager 加载即可。

每个 Core 插件必须声明一个带有@PluginFactory 或@PluginBuilderFactoryComments 的静态方法。前者用于提供所有选项作为方法参数的静态工厂方法,后者用于构造新的 Builder<T>类,其字段用于注入属性和子节点。为了使配置将正确的参数传递给方法,必须将方法的每个参数都 Comments 为以下属性类型之一。每个属性或元素 Comments 都必须包含配置中必须存在的名称,以使配置项与其各自的参数匹配。对于插件构建器,如果 Comments 中未指定名称,则默认使用字段名称。 Log4j Core 中有许多插件可以用作更复杂场景的示例,包括分层构建器类(例如,请参阅 FileAppender)。有关更多详细信息,请参见使用插件构建器扩展 Log4j

Attribute Types

  • PluginAttribute

    • 该参数必须可以使用TypeConverter从字符串转换成。大多数内置类型均已受支持,但也可能提供自定义 TypeConverter 插件以提供更多类型支持。请注意,可以在构建器类字段中使用 PluginBuilderAttribute 作为提供缺省值的简便方法。
  • PluginElement

    • 该参数可以表示一个复杂的对象,该对象本身具有可以配置的参数。这也支持注入元素数组。
  • PluginConfiguration

    • 当前的 Configuration 对象将作为参数传递给插件。
  • PluginNode

    • 当前正在解析的 Node 将作为参数传递给插件。
  • PluginValue

    • 当前 Node 的值或其名为 value 的属性。

Constraint Validators

插件工厂字段和参数可以在运行时使用受Bean 验证规范启发的约束验证器自动验证。以下 CommentsBinding 在 Log4j 中,但也可以创建自定义ConstraintValidators

  • Required

    • 此注解验证值是非空的。这涵盖了对 null 以及其他几种情况的检查:空 CharSequence 对象,空数组,空 Collection 实例和空 Map 实例。
  • ValidHost

  • ValidPort

    • 此 Comments 验证值是否与 0 到 65535 之间的有效端口号相对应。

Converters

PatternLayout使用转换器来渲染由转换模式标识的元素。每个转换器必须在@PluginComments 上将其类别指定为“转换器”,具有静态的 newInstance 方法,该方法接受 String 数组作为其唯一参数并返回 Converter 的实例,并且必须存在包含@ConverterKeys 的@ConverterKeysComments。导致选择转换器的转换器模式数组。旨在处理 LogEvent 的转换器必须扩展LogEventPatternConverter类,并且必须实现一个接受 LogEvent 和 StringBuilder 作为参数的格式方法。 Converter 应该将其操作结果附加到 StringBuilder。

转换器的第二种类型是 FileConverter-必须在@Plugin 注解的 category 属性中指定“ FileConverter”。尽管与 LogEventPatternConverter 相似,但这些 Converters 具有两种变体,而不是单一格式方法。一个接受一个 Object,另一个接受一个 Objects 数组而不是 LogEvent。两者都以与 LogEventPatternConverter 相同的方式追加到提供的 StringBuilder 中。 RollingFileAppender 通常使用这些转换器来构造要登录的文件的名称。

如果多个转换器指定相同的 ConverterKey,则上面的加载 Sequences 确定将使用哪个。例如,要覆盖内置 DatePatternConverter 类提供的%date 转换器,您需要将插件放在 CLASSPATH 中的 JAR 文件中,位于 log4j-core.jar 之前。不建议这样做;样式 ConverterKeys 冲突将导致发出警告。尝试为您的自定义模式转换器使用唯一的 ConverterKeys。

KeyProviders

Log4j 中的某些组件可能提供执行数据加密的功能。这些组件需要一个 Secret 密钥来执行加密。应用程序可以通过创建实现SecretKeyProvider接口的类来提供密钥。

Lookups

查找可能是所有工具中最简单的插件。他们必须在插件 Comments 中将其类型声明为“ Lookup”,并且必须实现StrLookup接口。他们将有两种方法:一个接受 String 键并返回 String 值的查找方法,另一个接受 LogEvent 和 String 键并返回 String 的查找方法。可以通过指定${name:key}来引用查找,其中 name 是在 Plugin 注解中指定的名称,key 是要查找的项目的名称。

TypeConverters

TypeConverter是一种元插件,用于在插件工厂方法参数中将字符串转换为其他类型。其他插件已经可以通过@PluginElementComments 注入;现在,类型转换系统支持的任何类型都可以在@PluginAttribute 参数中使用。根据需要支持枚举类型的转换,不需要自定义 TypeConverter 类。已经支持了许多内置的 Java 类。有关更详尽的列表,请参见TypeConverters

与其他插件不同,TypeConverter 的插件名称纯粹是装饰性的。通过 Type 接口而不是仅通过 Class<?>对象查找适当的类型转换器。请注意,TypeConverter 插件必须具有默认构造函数。

Developer Notes

如果插件类实现CollectionMap,则不使用工厂方法。而是使用默认构造函数实例化该类,并将所有子配置节点添加到 Collection 或 Map 中。