【问题标题】:how to define logback variables/properties before logback auto-load logback.xml?如何在 logback 自动加载 logback.xml 之前定义 logback 变量/属性?
【发布时间】:2014-08-05 18:46:57
【问题描述】:

我的公司有一个环境管理工具,使您能够以 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>

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

非常感谢。

【问题讨论】:

  • 使用标准的 Logback Groovy 支持可能是最简单的方法。

标签: java logback


【解决方案1】:

Define a property in logback.xml 并将其加载到“上下文”中:

<property scope="context" name="logfolder" value="${location.of.the.log.folder}" />

然后定义引用属性的附加程序:

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

来自documentation

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

所以默认范围,即“本地”可能就足够了。

【讨论】:

  • 谢谢,亚历山大。但是,这并不能解决我的问题。我希望 ${location.of.the.log.folder} 在 logback 加载任何配置之前定义你的示例。
  • 我发现这可以通过在启动时指定 -Dlocation.of.the.log.folder=dir 来实现
  • 您还可以从*.properties 文件中导入所有属性 - 例如。 &lt;property resource="application.properties" /&gt;
【解决方案2】:

经过一番摸索后,我决定采用以下解决方案。

首先,将 logback.xml 放在类路径之外,这样 logback 就不会自动加载任何内容。

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

第三,在应用程序代码中以编程方式配置 logback。 (官方的 logback 文档有 one nice example 。)

完成。

【讨论】:

  • 嗨,JBT。谢谢你。我做了一些稍微不同的事情。我将 logback xml 文件保存在类路径中,但我将其命名为“out-logback.xml”。一旦它是 logback 不扫描的名称,我就可以将配置文件保存在 jar 中。
【解决方案3】:

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

以下是替代方案:

  1. 如果通过环境,您的意思是通常称为environment variables,您可以轻松refer to them directly in the configuration file

  2. 如果您不是指环境变量,而是需要自定义代码才能访问的东西,您可以implement a custom ch.qos.logback.core.spi.PropertyDefiner 获取并返回值。

    例如

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

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

  1. 通过使用环境变量或系统属性 (-D) 在 Java 程序外部设置它,例如通过调用 shell 脚本。
  2. 通过ch.qos.logback.core.spi.PropertyDefiner 回调返回。
  3. 设置它in a ch.qos.logback.classic.spi.LoggerContextListener as done in this answer
  4. 人为延迟加载logback.xmlas how the OP has done in his answer

【讨论】:

    【解决方案4】:

    试试这个:

    在 logback.xml 中通过 %property{myProperty} 引用您的属性:

        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>
                %property{myProperty} - %m%n%wEx
            </pattern>
        </encoder>
        </appender>
    

    在应用程序运行时设置属性:

    LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
    loggerContext.putProperty("myProperty", "myProperty12345");
    

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      • 2017-12-09
      • 2014-03-16
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多