【问题标题】:log4j2.xml lookup system properties set by Springlog4j2.xml 查找 Spring 设置的系统属性
【发布时间】:2020-07-03 01:30:17
【问题描述】:

我正在从 log4j 1.x 迁移到 2.x,我们有一个属性文件“foo.properties”,我们在 spring 的 applicationContext.xml 中读取并转换为系统属性:

    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="foo" value="classpath:META-INF/properties/foo.properties" />
    </bean>

    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject">
            <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                <property name="targetClass" value="java.lang.System" />
                <property name="targetMethod" value="getProperties" />
            </bean>
        </property>
        <property name="targetMethod" value="putAll" />
        <property name="arguments">
            <util:properties>
                <prop key="x.y.z">${x.y.z}</prop>
                <prop key="a.b.c">${a.b.c}</prop>
                ...
        </util:properties>
        </property>
    </bean>

我希望现在能够像 &lt;RollingFile name="rollingFile" fileName="${sys:x.y.z}"&gt; 一样在 log4j2.xml 中引用 x.y.z,但这不适用于 2.x。使用 1.x ${x.y.z} 可以正常工作。

之前,我们在 applicationContext.xml 中有这段代码来初始化 log4j:

    <bean id="log4jInitialization"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
        <property name="targetMethod" value="initLogging" />
        <property name="arguments">
            <list>
                <value>classpath:log4jMain.xml</value>
            </list>
        </property>
    </bean>

但这被删除了,因为它不适用于 2.x,这可能会破坏某些东西。如何让 log4j2 查找 Spring 设置的系统属性?

【问题讨论】:

    标签: java spring log4j2 slf4j applicationcontext


    【解决方案1】:

    如果您使用 Spring Boot,Log4j 将至少初始化 3 次,其中第一次是在 Spring 完成任何操作之前。所以 Spring 不可能为你设置这些属性。但是,随后调用初始化日志记录可能能够提供属性,但这并不是必需的,因为 Log4j 可以为您处理。

    选项 1 - 如果您使用 Spring Boot,则包括 Log4j Spring Cloud Config Client。它包括一个 SpringLookup,可以让您引用 Spring 配置中定义的任何属性。例如,如果您的 application.yaml 包含:

    logging:
      root:
        level:
    

    您可以在 log4j2.xml 文件中引用 ${spring:logging.root.level}。

    选项 2 - 如果您不使用 Spring Boot 或不喜欢系统属性,那么您可以在类路径上创建一个名为 log4j2.system.properties 的文件。在此文件中找到的所有属性都将由 Log4j 在 Log4j 初始化开始时作为系统属性发布。

    【讨论】:

    • 我这样做的原因是因为我们在 CI/CD 管道中还有一些我无法控制的其他事情,最终会创建“foo.properties”。听起来它只适用于 1.x,因为使用 MethodInvokingFactoryBean 重新初始化。有没有类似的方法可以调用来重新初始化 2.x?或者,我可以设置一些属性来更改用于 log4j2.system.properties 的文件名吗?我试图在文档中查找它,但找不到任何东西。感谢您的帮助!
    • 不,您不能更改 log4j2.system.properties 文件的名称。是的,如果您正在重新初始化日志记录,那么这将导致这些属性在重新配置期间可用。是的,您可以使 Log4j 重新配置。请参阅配置器类。但是,我建议您更改 CI/CD 管道,而不是在应用程序启动时搞砸。定制您的应用程序以匹配您的 CI/CD 管道就像摇尾巴一样。
    • 我在 14 个月前发现了添加对 log4j2.system.properties 文件的支持的提交(由你!),但不幸的是,这对我来说太新了,无法使用。我被困在 log4j2 2.7 上,因为我们使用的是 Tomcat 7,它无法处理较新版本的某些类文件功能。出于同样的原因,我也不能使用 Configurator.reconfigure(),因为它仅在 2.12 之后才可用。您是否知道是否有任何其他方法可以完成此操作或一些解决方法来使用带有 Tomcat 7 的较新版本?
    • Tomcat 7 将在 Java 8 上运行(我有很多应用程序可以这样做),但也许您还有其他不兼容的依赖项?
    • 我正在运行 Tomcat 7 / Java SE 8,但在启动时收到有关“org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19”的错误。我只是按照这个答案说降级 log4j2 版本:stackoverflow.com/questions/54578459/… 并且它摆脱了它。我可以忽略该错误并安全地运行最新的 log4j2 版本吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 2019-05-19
    • 2018-01-20
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    相关资源
    最近更新 更多