Log4j2 环境变量查找机制不适用于 "type" 属性
Log4j2 environment variable lookup mechanism does not work with "type" attribute
我需要使用应用程序启动时提供的变量配置 Log4j2 Appender 布局。基本上,根据特定的 运行 环境,我需要使用一种布局或另一种布局。
目前我使用 XML 配置和以下设置。
- 我定义了一个名为 LAYOUT 的环境变量,将布局类型作为值(例如:
CustomLayout
);
- 在
log4j2.xml
文件中,我定义了以下附加程序:
<Appender type="Console" name="ConsoleAppender">
<PatternLayout type="${env:LAYOUT}" />
</Appender>
但是,每当我启动我的应用程序时,我都会收到以下消息:
ERROR Console contains an invalid element or attribute "${env:LAYOUT}".
唉,在同一个 XML 的其他部分,${env:}
查找机制正常工作,例如这里:
<Root level="${env:ROOT_LOG_LEVEL:-DEBUG}">
<AppenderRef ref="ConsoleAppender" />
</Root>
在我看来,Log4j 的 属性 查找机制不适用于 type
属性。我究竟做错了什么?这是因为 type
属性的解析时间不同吗?
这里有两个问题。
- 您指定了
${env:LAYOUT}
。当查找解析为 null 时,查找的字符串值就是字符串本身 - 即 ${env:LAYOUT}
。这意味着找不到 LAYOUT 的值作为 OS 环境变量。当您在根 Logger 上配置级别时,您指定了 ${env:ROOT_LOG_LEVEL:-DEBUG}
,这意味着如果找不到 ROOT_LOG_LEVEL 作为环境变量,那么要使用的值应该是 "DEBUG"。如果您希望应用程序在未定义环境变量时 运行,则必须提供默认值。
- 您在 PatternLayout 上指定了一个名为 "type" 的属性。只有在配置元素上指定
strict-true
时才能使用 type 属性。但在这种情况下,您的配置需要如下所示:
<Appender type="Console" name="ConsoleAppender">
<Layout type="${env:LAYOUT}" />
</Appender>
请注意,为了使此配置起作用,您可能使用 type 属性指定的每个布局都必须接受完全相同的配置元素。
因为 Log4j 的 属性 查找机制似乎不适用于 type
属性,我用这个解决方法满足了我的需要:
<Appenders>
<Console name="AdvancedConsoleAppender" target="SYSTEM_OUT">
<AdvancedLayout/>
</Console>
<Console name="CustomConsoleAppender" target="SYSTEM_OUT">
<CustomLayout/>
</Console>
</Appenders>
<Loggers>
<Root level="${env:ROOT_LOG_LEVEL:-DEBUG}">
<AppenderRef ref="${env:LOG_APPENDER:-CustomConsoleAppender}" />
</Root>
</Loggers>
基本上方法如下:
- 我定义了两个 appender,每个都包含不同的布局类型;
- 在我的
<Root>
级别的 <AppenderRef>
中,我使用了一个环境变量来引用我需要在特定运行时环境中使用的附加程序的名称。
由于这个解决方法,我现在可以在不同的环境中使用不同的布局和日志级别。
我需要使用应用程序启动时提供的变量配置 Log4j2 Appender 布局。基本上,根据特定的 运行 环境,我需要使用一种布局或另一种布局。
目前我使用 XML 配置和以下设置。
- 我定义了一个名为 LAYOUT 的环境变量,将布局类型作为值(例如:
CustomLayout
); - 在
log4j2.xml
文件中,我定义了以下附加程序:
<Appender type="Console" name="ConsoleAppender">
<PatternLayout type="${env:LAYOUT}" />
</Appender>
但是,每当我启动我的应用程序时,我都会收到以下消息:
ERROR Console contains an invalid element or attribute "${env:LAYOUT}".
唉,在同一个 XML 的其他部分,${env:}
查找机制正常工作,例如这里:
<Root level="${env:ROOT_LOG_LEVEL:-DEBUG}">
<AppenderRef ref="ConsoleAppender" />
</Root>
在我看来,Log4j 的 属性 查找机制不适用于 type
属性。我究竟做错了什么?这是因为 type
属性的解析时间不同吗?
这里有两个问题。
- 您指定了
${env:LAYOUT}
。当查找解析为 null 时,查找的字符串值就是字符串本身 - 即${env:LAYOUT}
。这意味着找不到 LAYOUT 的值作为 OS 环境变量。当您在根 Logger 上配置级别时,您指定了${env:ROOT_LOG_LEVEL:-DEBUG}
,这意味着如果找不到 ROOT_LOG_LEVEL 作为环境变量,那么要使用的值应该是 "DEBUG"。如果您希望应用程序在未定义环境变量时 运行,则必须提供默认值。 - 您在 PatternLayout 上指定了一个名为 "type" 的属性。只有在配置元素上指定
strict-true
时才能使用 type 属性。但在这种情况下,您的配置需要如下所示:
<Appender type="Console" name="ConsoleAppender">
<Layout type="${env:LAYOUT}" />
</Appender>
请注意,为了使此配置起作用,您可能使用 type 属性指定的每个布局都必须接受完全相同的配置元素。
因为 Log4j 的 属性 查找机制似乎不适用于 type
属性,我用这个解决方法满足了我的需要:
<Appenders>
<Console name="AdvancedConsoleAppender" target="SYSTEM_OUT">
<AdvancedLayout/>
</Console>
<Console name="CustomConsoleAppender" target="SYSTEM_OUT">
<CustomLayout/>
</Console>
</Appenders>
<Loggers>
<Root level="${env:ROOT_LOG_LEVEL:-DEBUG}">
<AppenderRef ref="${env:LOG_APPENDER:-CustomConsoleAppender}" />
</Root>
</Loggers>
基本上方法如下:
- 我定义了两个 appender,每个都包含不同的布局类型;
- 在我的
<Root>
级别的<AppenderRef>
中,我使用了一个环境变量来引用我需要在特定运行时环境中使用的附加程序的名称。
由于这个解决方法,我现在可以在不同的环境中使用不同的布局和日志级别。