logback外化

时间:2013-01-12 00:02:06

标签: slf4j logback

目前我有logback配置文件,即logback.xml src/main/resources。我想设置日志记录级别,但我希望在战争之外进行控制。

我能想到的一个解决方案是在属性文件中将其外部化,在服务器启动时加载它并替换占位符。有没有更好的方法呢?我们不能将logback.xml保留在战争文件之外吗?

<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${catalina.base}/logs/logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- daily rollover -->
        <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
        <!-- keep 7 days' worth of history -->
        <maxHistory>7</maxHistory>
    </rollingPolicy>
    <encoder>
        <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>

<root level="DEBUG">
    <appender-ref ref="FILE"/>
</root>

5 个答案:

答案 0 :(得分:8)

如果您只想更改日志级别,则无需覆盖整个文件,您可以这样做:

<root level="${log.level:-INFO}">

然后,如果您设置系统属性:

-Dlog.level=DEBUG

它将覆盖默认的“INFO”。

答案 1 :(得分:8)

我建议你使用2个logback配置文件。 类路径中的第一个定义为:

<configuration scan="true">
    <property file="/otherfolder/project.properties" />
    <include file="/otherfolder/logback.xml"/>
</configuration>

然后将所有配置放在另一个配置中。 Logback将扫描两个文件以进行更新。

答案 2 :(得分:5)

外部属性是从外部控制日志记录级别的一种方法。 Logback的file inclusion功能是另一个功能。顺便说一句,auto-reload功能适用于包含的配置文件,但不适用于属性文件。

答案 3 :(得分:4)

我设法将一个外部配置文件与tomcat / Spring logback

放在一起

tomcat的上下文文件:

<?xml version='1.0' encoding='utf-8'?>
<Context path="/appName">
<Environment name="pathCfg" value="${user.home}/applications/appName/cfg" type="java.lang.String" override="false" />
</Context>

web.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:/web-application-context.xml
    </param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Listener for external logback configuration file -->
<listener>
    <listener-class>com.package.client.servlet.LogbackConfiguratorContextListener</listener-class>
</listener>

web的应用程序的context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<!-- Configuration -->
<jee:jndi-lookup id="configurationPath" jndi-name="pathCfg"></jee:jndi-lookup>
<bean id="configurationPathResource" class="org.springframework.core.io.FileSystemResource">
    <constructor-arg ref="configurationPath" />
</bean>
<util:properties id="environnementProperties" location="file:${java:comp/env/pathCfg}/environnement.properties" />
</beans>

logback配置器类:

package com.package.client.servlet;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.web.context.support.WebApplicationContextUtils;

import ch.qos.logback.classic.BasicConfigurator;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;

/**
 * Servlet context listener in order to use an external configuration file for logback.
 * 
 */
public class LogbackConfiguratorContextListener implements ServletContextListener
{

    private static final Logger LOGGER = LoggerFactory.getLogger(LogbackConfiguratorContextListener.class);

    /**
     * Logback configuration file uri.
     */
    @Value("#{environnementProperties['logback.configuration.file.uri']}")
    private String logbackConfigurationUri;

    /**
     * Configuration path resource for configuration files.
     */
    @Value("#{configurationPathResource}")
    private Resource configurationPathResource;

    /**
     * initialize logback with external configuration file.
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent)
    {
        autowireThis(servletContextEvent.getServletContext());
        Resource logbackConfigurationResource = null;
        if (StringUtils.isNotBlank(logbackConfigurationUri))
        {
            if (StringUtils.containsAny(logbackConfigurationUri, new char[] { '/', '\\' }))
            {
                logbackConfigurationResource = new FileSystemResource(logbackConfigurationUri);
            }
            else if (configurationPathResource != null)
            {
                try
                {
                    logbackConfigurationResource = new FileSystemResource(new File(configurationPathResource.getFile(),
                            logbackConfigurationUri));
                }
                catch (IOException exception)
                {
                    LOGGER.error("Can't read resource " + configurationPathResource.getFilename(), exception);
                }
            }
        }
        if (logbackConfigurationResource != null)
        {
            if (logbackConfigurationResource.exists())
            {
                LOGGER.info("Found logback configuration " + logbackConfigurationResource.getDescription()
                        + " - Overriding default configuration");
                JoranConfigurator configurator = new JoranConfigurator();
                LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
                loggerContext.reset();
                configurator.setContext(loggerContext);
                try
                {
                    configurator.doConfigure(logbackConfigurationResource.getFile());
                    LOGGER.info("default configuration overrided by logback configuration "
                            + logbackConfigurationResource.getDescription());
                }
                catch (Exception exception)
                {
                    try
                    {
                        new ContextInitializer(loggerContext).autoConfig();
                    }
                    catch (JoranException e)
                    {
                        BasicConfigurator.configureDefaultContext();
                        LOGGER.error("Can't configure default configuration", exception);
                    }
                    LOGGER.error(
                            "Can't configure logback with specified " + logbackConfigurationResource.getDescription()
                                    + " - Keep default configuration", exception);
                }
            }
            else
            {
                LOGGER.error("Can't read logback configuration specified file at "
                        + logbackConfigurationResource.getDescription() + " - Keep default configuration");
            }
        }
        else
        {
            LOGGER.info("No logback configuration file specified - Keep default configuration");
        }
    }

    /**
     * Autowire this bean by spring
     * @param servletContext le contexte de la servlet
     */
    private void autowireThis(ServletContext servletContext)
    {
        WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).getAutowireCapableBeanFactory()
                .autowireBean(this);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce)
    {
    }
}

最后是environnement.properties

# Configuration file
logback.configuration.file.uri=C:/Users/olejacques/applications/appName/cfg/log.xml

答案 4 :(得分:0)

它对我们有用的一种方法是外部化配置文件,如下所示。如果不适用于您,请忽略弹簧轮廓部件。因此,只要您更新logback-include.xml中的配置,让我们说通过将根级别更改为信息,应用程序会在30秒内(可配置)选择它。

参考:https://logback.qos.ch/manual/configuration.html#fileInclusion

<强>的web.xml
我们使用弹簧轮廓,但即使没有弹簧轮廓也可以使用。

    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>dev</param-value>
    </context-param>
    <listener>
        <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
    </listener>
    <context-param>
        <param-name>logbackConfigLocation</param-name>
        <param-value>classpath:properties/${spring.profiles.active}/logback.xml</param-value> <!-- with profiles, config file in classpath includes ext. file -->
<!--        <param-value>file:logback-ext-config-path/logback.xml</param-value> --> <!-- directly using external config -->
<!--        <param-value>classpath:logback.xml</param-value> --> <!-- without profiles -->
    </context-param>

logback.xml (在类路径中)
请注意debug="true",它会告诉您何时更新配置。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration debug="true" scan="true" scanPeriod="30 seconds">
    <include file="${logback-ext-config-include-file-path}/logback-include.xml"/>
</configuration>

logback-include.xml (外部位置) 请注意使用<included>而不是配置。不要错过这部分!

<included>
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${logfile-path}/log-file.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- daily rollover -->
                <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
                <!-- keep 7 days' worth of history -->
                <maxHistory>7</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
            </encoder>
        </appender>

        <root level="DEBUG">
            <appender-ref ref="FILE"/>
        </root>
</included>