美文网首页Java游戏服务器开发
既然使用Logback,应该对它多些了解(二)

既然使用Logback,应该对它多些了解(二)

作者: 王广帅 | 来源:发表于2020-05-11 22:16 被阅读0次

上一篇:https://www.jianshu.com/p/824d5396d9ec

1. 变量作用范围(logback scopes)

在Logback中,变量有三种不同的scope:local scope ,context scope,system scope。
在变量替换的时候,首先从local scope中找,然后是context scope,然后是system properties中找,最后是操作系统环境变量中找。
可以在<property> <define> <insertFromJNDI>元素中使用scope属性,它的属性值可以是:local,context,system。如果不指定,默认是local。

<configuration>

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

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

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

2. 变量之间可以引用

USER_HOME=/home/sebastien
fileName=myApp.log
destination=${USER_HOME}/${fileName}

3. 条件判断启用不同的logback配置

两种不同的格式:

 <!-- if-then form -->
   <if condition="some conditional expression">
    <then>
      ...
    </then>
  </if>
  
  <!-- if-then-else form -->
  <if condition="some conditional expression">
    <then>
      ...
    </then>
    <else>
      ...
    </else>    
  </if>

4. 引用公共配置

有时候,在多个项目开发中,日志的配置有一部分是统一的配置,可以把这些公共的配置提取到一个公共的配置文件中,在主配置文件中引用这个公共配置的文件。
比如一个主配置文件为:

<configuration>
  <include file="src/main/java/chapters/configuration/includedConfig.xml"/>

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

</configuration>

公共配置文件为:

<included>
  <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>"%d - %m%n"</pattern>
    </encoder>
  </appender>
</included>
  • 注意,这里的<included>标记是不能少的。

引用文件的方式有三种:

  1. 从文件路径中引用
 <include file="src/main/java/chapters/configuration/includedConfig.xml"/>
  1. 从classpath中引用
<include resource="includedConfig.xml"/>
  1. 从URL中引用
<include url="http://some.host.com/includedConfig.xml"/>

如果引用的文件是可有可无的,则可以把它定义为可选择的:

<include optional="true" ..../>

5. 缓存日志输出,提高日志吞吐量

如果日志允许丢失,把Appender中的immediateFlush设置为false,可以明显提高日志的吞吐量。

6. 每次启动都创建一个日志文件

在一些不是常驻内存的应用中,每次启动应用都创建一个新的日志文件是非常合适的。可以使用<timestamp>标签实现。

<configuration>

  <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
       the key "bySecond" into the logger context. This value will be
       available to all subsequent configuration elements. -->
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!-- use the previously created timestamp to create a uniquely
         named log file -->
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

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

datePattern配置的值只要可以被SimpleDateFormat转化就可以。

7. RollingFileAppender

RollingFileAppender有两个重要的组件:RollingPolicy 和 TriggeringPolicy。前者决定如何滚动日志文件,需要一种策略,后者决定何时开始滚动日志文件,需要的是一个触发点。

7.1 TimeBasedRollingPolicy

这是一个常见的日志滚动策略,它基于时间滚动,比如每天生成一个日志文件,或每月生成一个日志文件。它同时实现了RollingPolicy 和 TriggeringPolicy接口。在TimeBasedRollingPolicy可以配置下面这些属性:

  • fileNamePattern 日志文件名样式
    这是一个必须配置的属性。它定义每次滚动日志文件时,日志文件名称的生成方式。它一般由占位符%d和日志名组成。%d可以指定日期和时间,由java.text.SimpleDateFormat进行格式化。如果只有%d,它默认使用yyyy-MM-dd的日期格式。在RollingFileAppender中,<file>标签是可以省略的,如果设置了file的值,当前的日志都会输入到这个file配置的文件中。它可以将当前输出的日志文件和滚动归档的日志文件分离。如果不配置file标签,则随着时间的变化,当前输出的日志会创建新的日志文件。
    如果在一个fileNamePattern标签下用到多个%d,刚只能有一个是做为滚动日志文件的日期判断。其它的都只能是辅助的。例如,每天生成一个日志文件,每个月的日志文件放在一起:
/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log

在配置中,也可以指定时区,比如:

Folder/test.%d{yyyy-MM-dd-HH, UTC}.log

如果指定的时区不存在,或没有指定,默认使用GMT时区。

  • maxHistory 保留的历史日志文件最大数量
    比如你配置的是每天生成一个日志文件,maxHistory配置的是6,那么就会只保留6个日志文件,即六天的日志。如果是每月生成一个日志文件,则是保留6个月的日志文件,因为一个日志文件记录一个月的日志。当日志文件超过这个数量时,最早的日志文件会被异步删除。

  • totalSizeCap
    这个属性限制保留的日志总大小,如果日志文件总的大小超过这个限制,就会异步删除最早的日志文件。这个属性需要配合maxHistory一起使用,logback会首先判断maxHistory,然后再计算日志总量是否超过这个限制。

  • cleanHistoryOnStart
    这个属性默认是false,如果设置为true,则应用启动的时候都会删除以前旧的日志。
    在开发环境下可以配置为true。
    下面是一些常见的格式配置:

日志文件样式配置 例子说明
/log/foo.%d 1. 当不设置<file>标签时,如果现在的日期是2020-05-23,当前的日志会输出到/log/foo.2020-05-20的日志文件中,过了24点之后,会输出到/log/foo.2020-05-20的日志文件中。2. 如果设置file标签为:<file>/log/foo.log</file>,当前日志会输出到/log/foo.log文件中,过了24点之后,foo.log会重命名为/log/foo.2020-05-23,然后重新创建一个/log/foo.log文件,当前日志会输出到新的文件中。
/log/%d{yyyy/MM}/foo.txt 每月生成一个新的日志文件,设置与不设置file和上面的一样。
/log/foo.%d{yyyy-ww}.log 每周生成一个日志文件。
/log/foo%d{yyyy-MM-dd_HH}.log 每小时生成一个日志文件
/log/foo%d{yyyy-MM-dd_HH-mm}.log 每分钟生成一个日志文件
/log/%d{yyyy-MM,aux}/%d.log 每天生成一个日志文件,旧的文件归档到年月的文件夹里面,比如2020-05。
  • 如果配置的文件路径不存在,logback会自动创建。

  • TimeBasedRollingPolicy 支持自动压缩,如果配置的fileNamePattern以.gz或.zip结尾,就会自动压缩。
    例如 :/log/foo.%d.zip

下面是一个配置示例:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- keep 30 days' worth of history capped at 3GB total size -->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>

    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

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

如果想支持多个JVM进程向同一个日志文件中写日志,设置prudent参数为true:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- Support multiple-JVM writing to the same log file -->
    <prudent>true</prudent>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>30</maxHistory> 
      <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

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

7.2 Size and time based rolling policy

有时候希望日志既按天分割,又按大小分割,比如当日志文件不足1G的时候,每天创建一个新的日志文件,同一天内,如果日志文件大小超过1G的时候,也创建一个新的日志文件。就可以使用这个SizeAndTimeBaseRollingPolicy。

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>


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

</configuration>
  • 注意,这里面的配置中,%d和%i都是必不可少的。

7.3 SizeBasedTriggeringPolicy

这个触发策略只有一个参数,maxFileZie,默认是10MB,当文件达到配置的大小时,就分触发日志分割,创建新的日志文件。它支持的单位有:KB,MB,GB。
在使用这个策略时,fileNamePattern必须有%i。

公众号.png

相关文章

网友评论

    本文标题:既然使用Logback,应该对它多些了解(二)

    本文链接:https://www.haomeiwen.com/subject/ubcpnhtx.html