如何在logback auto-load logback.xml之前定义logback变量/属性?

JBT*_*JBT 23 java logback

我的公司有一个环境管理工具,使您能够以编程方式在Java中查找环境中的属性.我想利用这个工具来配置logback.例如,假设我有一个logback.xml,如下所示(特别是文件appender部分):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- console appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd/HH:mm:ss.SSS} [%thread] %-5level %logger{20}: %msg%n</pattern>
        </encoder>
    </appender>

    <!-- file appender -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${LOG_FILE:-/default/log/file/path</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd/HH:mm:ss.SSS} [%thread] %-5level %logger{20}: %msg%n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,我想LOG_FILE从环境(或OS,如果你愿意)查找属性,并在logback加载logback.xml之前将其传递给logback,以便它知道值LOG_FILE.那么,我该如何实现呢?顺便说一句,我知道如何以编程方式定义文件追加器,但这不是我想要的.

非常感谢你.

Ale*_*tos 15

定义属性logback.xml,并加载到"上下文":

<property scope="context" name="logfolder" value="${location.of.the.log.folder}" />
Run Code Online (Sandbox Code Playgroud)

然后定义引用属性的appender:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${logfolder}/logfile.log</file>
    <append>true</append>
    <encoder>
        <pattern>[%d{ISO8601}] [%p] [%t] [%c] [%m]%n</pattern>
    </encoder>
</appender>
Run Code Online (Sandbox Code Playgroud)

文档:

具有上下文范围的属性将插入上下文中,并且只要上下文或直到它被清除就会持续.一旦定义,上下文范围中的属性就是上下文的一部分.因此,它可用于所有日志记录事件,包括通过序列化发送到远程主机的事件.

所以默认范围,即"本地"可能就足够了.

  • 您还可以从“*.properties”文件导入所有属性 - 例如。`&lt;属性资源=“application.properties”/&gt;` (3认同)
  • 谢谢,亚历山大.但是,这并没有解决我的问题.我希望在logback加载任何配置之前定义`$ {location.of.the.log.folder}`,就像你的例子一样. (2认同)
  • 我发现这是通过在启动时指定-Dlocation.of.the.log.folder = dir来实现的 (2认同)

JBT*_*JBT 11

经过一番摸索,我正在解决以下问题.

首先,将logback.xml放在classpath之外,以便logback不会自动加载任何内容.

其次,将环境中的设置添加到系统属性中,以便在解析logback.xml时,logback可以查找它们.

第三,以编程方式配置应用程序代码中的logback.(官方的logback文档有一个很好的例子.)

完成.


ant*_*tak 10

我想LOG_FILE从环境(或操作系统,如果你愿意)查找属性

以下是替代方案:

  1. 如果是环境,你的意思是通常所说的环境变量,你可以直接在配置文件中引用它们而不会有太多麻烦.

  2. 如果您不是指环境变量,而是需要自定义代码来访问的内容,则可以实现一个自定义的ch.qos.logback.core.spi.PropertyDefiner来获取并返回该值.

    例如

    public class MyCompanyEnvironmentGrabber extends PropertyDefinerBase {
    
        @Override
        public String getPropertyValue() {
            return ...; // grab the value from company environment
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 明显的报告可以logback.xml通过在任何调用之前将其置于加载之前以编程方式设置变量logger,并注意ClassLoader加载顺序......但是,我认为这非常脆弱,因为不使用static logger非常难以控制何时代码库变得复杂.

总而言之,因为logback.xml几乎在Java实例启动后立即加载,将值动态设置为变量的安全方式似乎仅限于:

  1. 通过使用环境变量或系统属性(-D)将其设置在Java程序之外,例如通过调用shell脚本.
  2. 通过ch.qos.logback.core.spi.PropertyDefiner回调返回它.
  3. 设置它ch.qos.logback.classic.spi.LoggerContextListener在这个答案为已完成.
  4. 人为地延迟了logback.xml OP在他的回答中的表现.