【问题标题】:Must multiple Logback PropertyDefiner implementations be created to pull in multiple properties?是否必须创建多个 Logback PropertyDefiner 实现才能引入多个属性?
【发布时间】:2014-12-09 23:19:53
【问题描述】:

我可以使用 Logback PropertyDefiner 从 logback.xml 配置文件中访问单个属性。如果我有 3 个属性要访问,我目前正在使用 PropertyDefiner 的 3 个单独实现(每个属性一个)。

有没有办法从单个 PropertyDefiner 实现中访问多个属性?或者也许还有另一个支持多个属性的接口?

我希望能够根据环境(dev、ist、uat、perf、prod)为各种日志配置(上下文名称、日志级别、appender 文件名、文件大小等)使用属性来插入不同的值.).

找到this question,类似,但没有回答如何访问多个属性的问题。

【问题讨论】:

  • 您能否详细说明这些属性是什么以及您打算如何处理它们?基于此,我们可以考虑是否有其他解决方案。 PropertyDefiner 解决方案似乎只适用于一个属性。
  • 我更详细地更新了问题。

标签: properties logback


【解决方案1】:

创建一个PropertyDefiner 实现类。 PropertyDefinerBase 实现已经提供。

package foo.bar;

import java.util.HashMap;
import java.util.Map;

import ch.qos.logback.core.PropertyDefinerBase;

public class LoggingPropertiesDefiner extends PropertyDefinerBase {

  private static Map<String, String> properties = new HashMap<>();

  static {
    properties.put("encoderPattern", "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %message%n");
    properties.put("maxFileSize", "50MB");
    properties.put("rootLogLevel", "INFO");
  }

  private String propertyLookupKey;

  public void setPropertyLookupKey(String propertyLookupKey) {
    this.propertyLookupKey = propertyLookupKey;
  }

  @Override
  public String getPropertyValue() {
    //TODO In the real world, get properties from a properties loader.
    return properties.get(propertyLookupKey);
  }
}

在 logback.xml 中,为每个属性使用相同的 PropertyDefiner 类。为每个提供不同的查找键:

<define name="encoderPattern" class="foo.bar.LoggingPropertiesDefiner">
    <propertyLookupKey>encoderPattern</propertyLookupKey>
</define>

<define name="maxFileSize" class="foo.bar.LoggingPropertiesDefiner">
    <propertyLookupKey>maxFileSize</propertyLookupKey>
</define>

<define name="rootLogLevel" class="foo.bar.LoggingPropertiesDefiner">
    <propertyLookupKey>rootLogLevel</propertyLookupKey>
</define>

引用 logback.xml 中的属性名称:

<root level="${rootLogLevel}">
    <appender-ref ref="FILE"/>
</root>

【讨论】:

  • 这是一个非常有用的建议,令人惊讶的是,其他任何地方都没有涉及。当您花太多时间查看有关此主题的 logback 文档时,这绝对是违反直觉的……但它确实是一个非常干净的解决方案,尤其是。当您只是从属性文件中提取值时。谢谢乍得!
【解决方案2】:

你可以使用 logback 的属性资源支持

logback.properties

mode=prod    

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
    <property resource="logback.properties" />

    <if condition='property("mode").equals("prod")'>
        <then>
            <include file="logback-prod.xml" />
        </then>
    </if>
    <if condition='property("mode").equals("dev")'>
        <then>
            <include resource="logback-dev.xml" />
        </then>
    </if>
</configuration>

logback-prod.xml

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <!--Daily rolling file appender -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <File>${MYAPP_HOME}/myApp.log</File>
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <FileNamePattern>myApp.%d{yyyy-MM-dd}.log</FileNamePattern>
          <MaxHistory>2</MaxHistory>
          </rollingPolicy>
          <layout class="ch.qos.logback.classic.PatternLayout">
          <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
          </layout>
    </appender> 

    <root level="ERROR">
        <appender-ref ref="file" />
    </root>
</configuration>

logback-dev.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--Daily rolling file appender -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <File>${MYAPP_HOME}/myApp.log</File>
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <FileNamePattern>myApp.%d{yyyy-MM-dd}.log</FileNamePattern>
          <MaxHistory>2</MaxHistory>
          </rollingPolicy>
          <layout class="ch.qos.logback.classic.PatternLayout">
          <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
          </layout>
    </appender> 


    <root level="TRACE">
        <appender-ref ref="file" />
    </root>
</configuration>

更详细的解释here

这有助于解决您的问题吗?

【讨论】:

  • 我查看了属性资源支持,但正在寻找一种方法来提供一个 java 类的钩子,这样我就可以执行属性查找。我找到了一种使用单个 PropertyDefiner 类来公开多个属性的方法。我将添加一个单独的答案来说明这一点。感谢您的帮助!
猜你喜欢
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2023-04-03
  • 2013-10-15
相关资源
最近更新 更多