当前位置: 首页 > 知识库问答 >
问题:

Spring Boot和Log4J2的奇怪行为

许承悦
2023-03-14

运行Spring Boot应用程序时,我遇到了一些奇怪的问题。它已配置为使用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文件,以允许变化,特别是日志文件名。当我运行应用程序时,日志文件被创建在正确的目录中,并且看起来确实有实际的日志内容。问题是它们的名字不正确。例如,而不是Client-1。本届会议。日志,文件名为${sys:service.name}-${sys:service.id}。本届会议。日志。显然,变量替换没有按计划进行。

属性service.nameservice.id是当前在关联application.yml文件中定义的Spring Boot配置参数。我原以为文件中的属性是可用的,但事实显然并非如此。

有没有一种方法可以申请。这里有yml酒店吗?如果这是不可行的,有什么其他方法来实现这一点的建议?

第二个问题

当我在测试环境中执行应用程序时,我将记录器设置为输出到控制台:

<Root level="info">
  <AppenderRef ref="ConsoleAppender" />
</Root>

当它执行时,输出会显示在控制台上,但奇怪的是,日志文件也会被创建。为什么会这样?

注:

有一个现有的SO项(使用log4j2.xml中的springboot应用程序属性)(这是第二个答案)可以解决这个问题,但它似乎(正如作者所承认的)有点黑客行为。我还没有试过。

我对应用程序“概要”的引用有点困惑。yml和log4j2Spring。xml。我不熟悉这些文件名的这些变体。这些变化(两种文件类型)的意义是什么?

共有1个答案

柯昱
2023-03-14

对于您的主要问题,您的文件名是log4j2。xml您应该使用log4j2spring。xml相反,因为这样可以让Spring Boot更好地控制Log4j2。

其中一个好处是可以整合您缺少的变量。这可能是由于使用了log4j2。xml文件使log4j2在Spring Boot之前初始化,同时使用log4j2spring。xml使Spring启动以初始化log4j2。

正如SpringBoot留档所述:

如果可能,我们建议您在日志配置中使用-spring变体(例如,logback-spring.xml而不是logback.xml)。如果使用标准配置位置,Spring无法完全控制日志初始化。

你可以看看这个由一个家伙打开的线程,他要求log4j2。xmlvslog4j2spring。xml

对于你的第二个问题,因为你有两个伐木工...简单地说:

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

关于你的第三个问题:

我对应用程序“概要”的引用有点困惑。yml和log4j2Spring。xml。我不熟悉这些文件名的这些变体。这些变化(两种文件类型)的意义是什么?

应用程序的变体-“profile”。xxx这是一种允许spring boot根据这些配置文件进行不同配置的方法。您可以使用“dev”参数(本地dev数据库)启动应用程序,但在生产环境中,您可以使用不同的参数。您可以通过不同的方式控制如何引导不同的配置文件,一个非常常见的方法是执行您的应用程序,如java-jar-Dspring。简介。活动=产品应用程序。jar

log4j2-spring.xml相关,上面已经说明了,允许Spring Boot正确初始化log4j2(或您使用的任何日志记录工具)。

 类似资料:
  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 我有一些问题要执行。 我需要的: 发布来自用户的消息 将其广播给其他用户 将消息发送给将在下次连接时使用该消息的脱机用户 我实际上: 在index.html页上,我连接到套接字服务器 我有一个发送消息的按钮 我在索引页上打开两个不同的浏览器,我的用户都已连接起来 如果我向服务器发送消息,服务器就会将消息发送给其他用户 如果我向服务器发送第二条消息,它就会将该消息发送给发送该消息的用户。 它在切换,

  • 问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么

  • 问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处

  • 问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。

  • 问题内容: 我认为这是一个正常程序,但这是我得到的输出: 有人可以向我解释一下吗? 问题答案: 这是有据可查的PHP行为,请参阅php.net的foreach页面上的警告。 警告 即使在 foreach 循环之后,仍保留 $ value的 引用和最后一个数组元素。建议通过unset()销毁它。 __ 编辑 尝试逐步了解此处实际发生的情况