繁体   English   中英

Spring 引导和 Log4J2 的奇怪行为

[英]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.nameservice.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.xmllog4j2-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM