在外部应用程序属性文件

时间:2016-11-16 03:59:09

标签: java spring spring-boot logback

在我的spring-boot应用程序中,我使用logback进行日志记录。该应用程序使用外部application.properties文件来设置特定于环境的应用程序属性,并以选项-spring.config.location=path/to/file开头。我希望logback配置从那里读取属性,以便在一个地方管理所有环境属性。

我尝试了here描述的方法,但由于属性文件不在类路径上,我收到错误:

java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.action.PropertyAction - Could not find resource [application.properties]

我有什么遗失的吗?

更新:

添加此配置有效:

   <property file="path/to/file" />

但我想避免硬编码文件路径。

4 个答案:

答案 0 :(得分:3)

添加系统环境变量,因此logback回退到配置文件

的此位置
logback.configurationFile=path/to/config.xml

答案 1 :(得分:2)

由于您使用的是Spring,因此可以使用Spring扩展进行Logback:logback-ext-spring

这个库的功能基本上使您可以将实际日志记录委派给spring管理对象,从而可以访问spring上下文。您可以在Spring配置中创建和配置appender,您可以访问Environment变量,也可以访问application.properties

您可以在GitHub页面上找到更多信息,但这里是一个示例配置,基于链接中提供的示例,其中从环境属性"consolePattern"检索控制台appender的模式:

logback.xml

<configuration>

    <appender name="consoleAppender" class="ch.qos.logback.ext.spring.DelegatingLogbackAppender"/>

    <root level="INFO">
        <appender-ref ref="consoleAppender"/>
    </root>

</configuration>

LogbackConfig.java

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.ext.spring.ApplicationContextHolder;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LogbackConfig {

    @Autowired
    private Environment environment;

    @Bean 
    public static ApplicationContextHolder applicationContextHolder() {
        return new ApplicationContextHolder();
    }

    @Bean 
    public static LoggerContext loggerContext() {
        return (LoggerContext) LoggerFactory.getILoggerFactory();
    }

    @Bean (initMethod = "start", destroyMethod = "stop")
    public static PatternLayoutEncoder encoder (LoggerContext ctx) {
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setContext(ctx);
        encoder.setPattern(environment.getProperty("consolePattern");
        return encoder;
    }

    @Bean (initMethod = "start", destroyMethod = "stop")
    public static ConsoleAppender consoleAppender (LoggerContext ctx, PatternLayoutEncoder encoder) {
        ConsoleAppender appender = new ConsoleAppender();
        appender.setContext(ctx);
        appender.setEncoder(encoder);
        return appender;
    }
}
  

重要
  请注意,spring bean名称必须与示例logback.xml"consoleAppender"中的appender名称相匹配。另外,请不要忘记指定initMethoddestroyMethod

希望这有助于您找到不对路径进行硬编码的方法。

答案 2 :(得分:2)

如果你使用弹簧启动来运行你的应用程序,你可以这样做:

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property file="${configuration.file.path}" />
    .......
</configuration>

您可以更改“configuration.file.path”,但必须在运行应用程序后更改该名称。

您可以使用属性文件中定义的属性,如下所示:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <Pattern>
            %d{yyyy-MM-dd HH:mm:ss} - ${property.defined.in.property.file} - %msg%n
        </Pattern>
    </layout>
</appender>

<root level="${level.defined.in.property.file}">
    <appender-ref ref="STDOUT" />
</root>

在执行应用程序时将参数添加到VM

-Dlogging.config=/some/path/logback.xml -Dconfiguration.file.path=/other/path/application.properties

logging.config是一个spring-boot配置,因此您必须保留该名称。您可以在每次执行时更改该文件,而无需更改应用程序中的配置。

如果您通过命令行手动执行您的应用程序,应该像:

java -Dlogging.config=/some/path/logback.xml -Dconfiguration.file.path=/other/path/application.properties -jar app-1.0.0.jar .....

这样做,所有日志记录配置都是动态的,并且您在运行应用程序时提供它。您可以使用不同配置的不同实例

答案 3 :(得分:1)

我们不会使用spring-boot,但这种做法可能会有所帮助:

我们创建了此LogbackConfigurator。通过监听ContextRefreshedEvent:

,在应用程序启动时执行此类
public class LogbackConfigurator implements ApplicationListener<ContextRefreshedEvent>
{
    // configure your configuration file here
    private static final String         LOGBACK_CONFIGURATION   = "some/where/application.properties";


    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        try
        {
            // creating JoranConfigurator
            JoranConfigurator joranConfigurator = new JoranConfigurator();

            // setting logger context for JoranConfiguratior
            joranConfigurator.setContext(loggerContext);

            // resetting context, override default configuration
            loggerContext.reset(); 

            // configuring Logback with resource
            joranConfigurator.doConfigure(new Resource(LOGBACK_CONFIGURATION).getInputStream());
        }
        catch (Exception exception)
        {
            // exception handling
        }
    }
}

为了执行bean,我们在Java配置中添加了这一行:

@Bean
public LogbackTestConfigurator logbackConfigurator()
{
    return new LogbackTestConfigurator();
}