Java游戏服务器开发

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

2020-05-11  本文已影响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>

引用文件的方式有三种:

  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可以配置下面这些属性:

/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log

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

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

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

日志文件样式配置 例子说明
/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。

下面是一个配置示例:

<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>

7.3 SizeBasedTriggeringPolicy

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

公众号.png
上一篇下一篇

猜你喜欢

热点阅读