[英]Strange behaviors with Spring Boot and Log4J2
我在运行 Spring 引导应用程序时遇到了一些奇怪的问题。 它已被配置为使用 Log4J2 作为其记录器(Logback 记录器已被禁用)。
log4j2.xml:
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="serviceName">$${sys:service.name}</Property>
<Property name="serviceId">$${sys:service.id}</Property>
<Property name="LOG_PATTERN">
[%d{yyyy-MM-dd HH:mm:ss.SSS}] %t %-5p: %c{2}:%L - %m%n
</Property>
<Property name="STATS_PATTERN">
%m%n
</Property>
<Property name="logFile">logs/$${sys:service.name}-$${sys:service.id}</Property>
<Property name="statsFile">metrics/$${sys:service.name}-$${sys:service.id}_stats.json</Property>
<!--
<Property name="logFile">logs/${serviceName}-${serviceId}</Property>
<Property name="statsFile">metrics/${serviceName}-${serviceId}_stats.json</Property>
-->
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
<RollingFile name="RollingFile" fileName="${logFile}.current-session.log"
filePattern="${logFile}.%i.log.gz" ignoreExceptions="false">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
<File name="StatsFile" fileName="${statsFile}" append="false">
<PatternLayout>
<Pattern>${STATS_PATTERN}</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="<package>.StatsWriter" level="info" additivity="false">
<AppenderRef ref="StatsFile" />
</Logger>
<Root level="info">
<AppenderRef ref="ConsoleAppender" />
</Root>
</Loggers>
</Configuration>
主要问题
我在 log4j2.xml 文件中有一些变量替换,以允许变化,特别是日志文件名。 当我运行应用程序时,日志文件会在正确的目录中创建,并且看起来确实有实际的日志内容。 问题是它们的名称不正确。 例如,文件名为${sys:service.name}-${sys:service.id}.current-session.log
而不是Client-1.current-session.log
-session.log 。 显然,变量替换没有按计划进行。
属性service.name
和service.id
是 Spring 当前在关联的 application.yml 文件中定义的引导配置参数。 我原以为文件中的属性是可用的,但显然不是这样。
有没有办法让 application.yml 属性在这里可用? 如果这不可行,有什么建议可以通过其他方式来实现?
次要问题
当我在测试环境中执行应用程序时,我将记录器设置为 output 到控制台:
<Root level="info">
<AppenderRef ref="ConsoleAppender" />
</Root>
当它执行时,output 显示在控制台上,但奇怪的是,日志文件也被创建了。 为什么会这样?
注意:
有一个现有的 SO 项目( 在 log4j2.xml 中使用 Spring 引导应用程序属性)(这是第二个答案)可以解决这个问题,但它似乎(正如作者承认的那样)有点骇人听闻。 我还没有尝试过(还)。
我对 application-"profile".yml 和 log4j2-spring.xml 的引用有点困惑。 我不熟悉这些文件名的这些变体。 这些变体(两种文件类型)的意义是什么?
对于您的主要问题,您的文件名是log4j2.xml
您应该使用log4j2-spring.xml
代替,因为这样您可以让 Z38008DD81C2F4D7985ECF6E0CE8AF1D1 更好地控制 Boot。
好处之一是可以整合您缺少的变量。 This is probably due to using log4j2.xml
files makes log4j2 to initialize before spring boot, while using log4j2-spring.xml
makes Spring Boot to initialize log4j2.
正如SpringBoot 文档所述:
如果可能,我们建议您对日志配置使用 -spring 变体(例如,logback-spring.xml 而不是 logback.xml)。 如果使用标准配置位置,Spring 无法完全控制日志初始化。
您可以查看由要求log4j2.xml
与log4j2-spring.xml
的人打开的此线程
对于您的第二个问题,因为您有 2 个记录器......就是这样:
<Loggers>
<Logger name="<package>.StatsWriter" level="info" additivity="false">
<AppenderRef ref="StatsFile" /> <---- This one creates your file
</Logger>
<Root level="info">
<AppenderRef ref="ConsoleAppender" />
</Root>
</Loggers>
关于你的第三个问题:
我对 application-"profile".yml 和 log4j2-spring.xml 的引用有点困惑。 我不熟悉这些文件名的这些变体。 这些变体(两种文件类型)的意义是什么?
application-"profile".xxx
的变体是一种允许 spring 引导基于这些配置文件采用不同配置的方式。 您可以使用“dev”参数(本地开发数据库)启动您的应用程序,但在生产中您可以使用不同的参数。 您可以通过不同的方式控制如何引导不同的配置文件,一种很常见的方式是执行您的应用程序,例如java -jar -Dspring.profiles.active=prod application.jar
与log4j2-spring.xml
相关,如上所述,以允许 Spring 引导正确初始化 log4j2(或您使用的任何日志记录工具)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.