日志体系-Logback配置

参考

Logback配置

Logback配置加载

  1. 类路径下寻找
  2. 寻找顺序为:logback-test.xml->logback.groovy->logback.xml->Configer的实现类->使用默认的BasicConfigurator
  3. BasicConfigurator的等同xml配置
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

可以明显看出配置了一个appender,并且root的打印级别为debug,root的logger打印输出为为Std的Appender
4. 监控日志上下文

public class MyApp2 {

    public static final Logger LOGGER = LoggerFactory.getLogger(MyApp2.class);

    public static void main(String[] args) {

        LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
        StatusPrinter.print(lc);

        LOGGER.info("Entering application.");

        Foo foo = new Foo();
        foo.doIt();
        LOGGER.info("Exiting application.");
    }
}

Slf4j中提过了获取LoggerFactory的实现,而在logback中的实现为LoggerContext,可以用StatusPrinter来进行打印

<configuration debug="true">
  
</configuration>

打印logback的上下文信息只需要在配置xml文件中将configuration中设置debug,设置debug为true等于设置如下

<configuration>

    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    <!-- 剩下的配置跟之前的相同 -->
</configuration>

配置文件修改自动扫描的配置方法为如下

<configuration scan="true" scanPeriod="30 seconds"
   ...
</configuration

增加一个扫描为true,并且扫描时间可以配置为30S,默认为1分钟扫描一次

可以设置在堆栈中展示jar包相关信息

<configuration packagingData="true">
    ...
</configuration>

配置自己的扫描规则
logback 的默认配置机制为:通过 JoranConfigurator在类路径上寻找默认的配置文件。你可以通过直接调用 JoranConfigurator 的方式来重写 logback 的默认配置机制。

public class MyApp3 {

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

    public static void main(String[] args) {

        LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory();
        JoranConfigurator joranConfigurator = new JoranConfigurator();
        joranConfigurator.setContext(context);
        context.reset();
        try {
            joranConfigurator.doConfigure(args[0]);
        } catch (JoranException e) {
            e.printStackTrace();
        }

        StatusPrinter.printInCaseOfErrorsOrWarnings(context);

        LOGGER.info("Entering application");

        Foo foo = new Foo();
        foo.doIt();
        LOGGER.info("Exiting application");
    }
}

配置文件的语法

  1. logback 最基本的结构为 元素,包含 0 或多个 元素,其后跟 0 或多个 元素,其后再跟最多只能存在一个的 元素。基本结构图如下:
    image
  2. 标签名大小写敏感
  • 对于指定的标签名不区分大小写
  • 对于非定义的使用驼峰式命名
  1. logger配置
  • logger中需要一个确定的名称,一个可选的level属性,一个可选的additivity属性。当level的属性为null或inherited则会强制从父辈继承
  • logger中至少包含0个或多得Appender-ref元素
<logger name="" level="" additivity='true'>
<appender-ref></appender-ref>
</logger>
  1. Appender配置规则
  • Appender需要强制有name和class属性
  • Appender包含0个或一个Layout元素
  • Appender包含0个或多个encoder元素,0个或多个filter元素
  • Layout元素可以包含对应的JavaBean属性,默认为PattenLayout,如果为该Layout可以忽略layout的Class类
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>myApp.log</file>
        <encoder>
            <pattern>
                %date %level [%thread] %logger{10} [%file:%line] %msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>
                %msg%n
            </pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
  • appender 通过 appender-ref 元素附加到 root logger 上。每一个 appender 都有自己 encoder。encoder 通常不会设计成给所有的 appender 共享。对于 layout 也是如此。因此,logback 不会提供任何共享 encoder 和 layout 的语法。
  • 在默认的情况下,appender 是可以重复使用的:logger 可以通过附加到本身的 appender 输出日志,同样的也可以附加到起祖先的身上,并输出日志。因此,如果同一个 appender 附加到多个 logger 身上,那么就导致日志重复打印。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="chapters.configuration">
        <appender-ref ref="STDOUT" />
    </logger>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
  • 可以通过Appender设置特定的打印
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>foo.log</file>
        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <logger name="chapters.configuration.Foo" additivity="false">
        <appender-ref ref="FILE" />
    </logger>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
  • 设置日志的应用名字
<configuration>
    <contextName>myAppName</contextName>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d %contextName [%t] %level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

当多个应用输出到同一个日志的时候可以更好的区分来源于的应用

变量替换

  1. 配置文件可以使用变量来配置,这个变量可以来源于配置文件,外部文件,外部资源文件甚至动态定义
<configuration>
    <property name="USER_NAME" value="/data/logs" />

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${USER_NAME}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>    
</configuration>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${USER_HOME}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>    
</configuration>
java -DUSER_HOME="/data/logs" MyApp3
<configuration>
    <property file="F:\project\logback-examples\src\main\resources\variables1.properties"/>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${USER_HOME}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>
</configuration>
<configuration>
    <property resource="resource1.properties" />

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${USER_HOME}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>
</configuration>

作用域

可以通过 、、 元素的 scope 属性来设置变量的作用范围。scope 属性可能的值为:local,context,system。如果没有指定,则默认为 local。

<configuration>
    <property scope="context" name="nodeId" value="firstNode"/>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>/data/${nodeId}/myApp.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="FILE" />
    </root>
</configuration>

变量相关:

  • 在某些情况下,如果某个变量没有被声明,或者为空,默认值则非常有用。在 bash shell 中,默认值可以通过 “:-” 来指定。例如:假设变量 aName 没有被定义,"${aNme:-golden}" 会被解释成 “golden” 。
  • 一个变量的值可以包含对其它变量的引用。
  • 默认值嵌套:一个变量的默认值可以引用另一个变量。例如:假设变量 “id” 没有被定义,变量 “userid” 的值为 “alice”,那么表达式 “KaTeX parse error: Expected '}', got 'EOF' at end of input: {id:-{userid}}” 的值为 “alice”。
  • 配置文件中的条件处理
    开发,测试和生产。这些配置文件有大量相同的地方,只有少数地方不同。为了避免重复,logback 在配置文件中支持通过 、、 元素作为条件语句来区分不同的环境。条件处理需要 Janino 环境的支持。
    <if condition="条件表达式">
        <then>
            ...
        </then>
    </if>

    <if condition="条件表达式">
        <then>
            ...
        </then>
        <else>
            ...
        </else>
    </if>

条件表达式只能是上下文变量或者系统变量。因为值是通过参数传递的,property() 方法或者其等价的 p() 方法属性的值。例如:如果要获取变量 “k” 的值,可以通过 property(“k”) 或者 p(“k”) 来获取。如果 “k” 没有定义,那么方法将会返回空字符串。所以不需要去判断是否为 null。

isDefined() 方法可以用来判断变量是否已经被定义。例如:可以通过 isDefined(“k”) 来判断 k 是否已经定义。还可以通过 isNull() 方法来判断变量是否为 null。例如:isNull(“k”)。

<configuration debug="true">
    <if condition='property("HOSTNAME").contains("volong")'>
        <then>
            <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                    <pattern>%d %-5level %logger{35} - %msg %n</pattern>
                </encoder>
            </appender>
            <root>
                <appender-ref ref="CON" />
            </root>
        </then>
    </if>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${randomOutputDir}/conditional.log</file>
        <encoder>
            <pattern>${HOSTNAME} %d %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>

    <root level="ERROR">
        <appender-ref ref="FILE" />
    </root>
</configuration>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值