Logback最佳实践和使用指导

栏目: Java · 发布时间: 5年前

内容简介:一、概述1、采用dev(开发环境)、test(测试环境)、pre release(预发布、准生产环境)、production(生产环境)等不同的日志配置,根据系统变量、环境变量等自动识别。2、特殊的记录,需要大批量写入日志文件,应该采用异步线程写文件。

一、概述

1、采用dev(开发环境)、test(测试环境)、pre release(预发布、准生产环境)、production(生产环境)等不同的日志配置,根据系统变量、环境变量等自动识别。

2、特殊的记录,需要大批量写入日志文件,应该采用异步线程写文件。

二、日志输出(Appender)分类

分为5个 基础类 : 

FILE_EXCEPTION (异常日志,包括ERROR和WARN)

FILE_APP (应用日志,包括当前应用package下面的日志和DEBUG级别以上的其他日志)

FILE_INFO (普通信息日志)

FILE_DEBUG (调试日志)

FILE_TRACE(追踪日志)

SYSOUT(控制台输出,可以包括以上所有日志)

扩展类: 包括异步输出的日志,或者特殊业务日志。

举例说明 (FILE_EXCEPTION、FILE_APP、FILE_INFO 等的区别):

假如 当前应用的 Main Package 为 cn.zollty.demo

ROOT_LEVEL为 trace,应用日志 LEVEL 为 debug

有以下日志打印:

Logger loggerA = LoggerFactory.getLogger(cn.zollty.demo.Tests. class );

loggerA.trace( "--------" );

loggerA.debug( "--------" );

loggerA.info( "--------" );

loggerA.warn( "--------" );

loggerA.error( "--------" );

Logger loggerB = LoggerFactory.getLogger(org.apache.kafka.Consumer. class );

loggerB.trace( "--------" );

loggerB.debug( "--------" );

loggerB.info( "--------" );

loggerB.warn( "--------" );

loggerB.error( "--------" );

那么,异常日志(FILE_EXCEPTION)输出的为:

loggerA.warn("--------");

loggerA.error("--------");

loggerB.warn("--------");

loggerB.error("--------");

控制台(SYSOUT)输出的为;

loggerA.debug("--------");

loggerA.info("--------");

loggerA.warn("--------");

loggerA.error("--------");

loggerB.trace("--------");

loggerB.debug("--------");

loggerB.info("--------");

loggerB.warn("--------");

loggerB.error("--------");

应用日志(FILE_APP)输出的为:

loggerA.debug("--------");

loggerA.info("--------");

loggerA.warn("--------");

loggerA.error("--------");

loggerB.info("--------");

loggerB.warn("--------");

loggerB.error("--------");

三、日志归档和保存期限

1、定期对日志文件进行归档、压缩 。

2、保存期限越久越好,但是本机保存的日志最大总容量(当前日志文件+归档压缩后的日志文件 size总和)规定如下:

  • 异常日志(error和warn)最多保存 10G(生产、准生产环境至少要保存30天)

  • app日志最多保存 10G(生产、准生产环境至少要保存7天)

  • trace日志最多保存 1G(仅供开发、测试用,生产环境一般不用)

  • debug、info日志最多保存 5G(一般不用,用app日志就够了)

  • 其他独立的输出日志视具体需求而定,但原则上最多保存 10G

对于超过本地保存容量的日志,根据业务需求决定是否删除或者迁移到其他地方保存。

四、各环境默认日志定义

开发环境

1)默认日志级别定义为:

app包为TRACE级别。日志的ROOT Level为DEBUG级别。

2)启用 System.out 控制台输出日志;

3)启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

测试环境

1)默认日志级别定义为:

app包为DEBUG级别。日志的ROOT Level为DEBUG级别。

2)禁用 System.out 控制台输出日志;

3)启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

生产环境

1)默认日志级别定义为:

app包为DEBUG级别。日志的ROOT Level为INFO级别。

2)禁用 System.out 控制台输出日志;

3)启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

四、根据环境自动选择日志配置

关键点1:使用logback的环境变量定义和读取功能

例如下面的各种环境变量定义:

<!-- 部署的环境类型:dev、test、product -->

< property name = "DEPLOY_ENV" value = "${deploy.env:-dev}" />

<!-- 日志路径,这里是相对路径,web项目eclipse下会输出到当前目录./logs/下,如果部署到 linux 上的tomcat下,会输出到tomcat/logs/目录 下 -->

< property name = "LOG_HOME" value = "${catalina.base:-.}/logs" />

<!-- 日志文件大小,超过这个大小将被压缩 -->

< property name = "LOG_MAX_SIZE" value = "100MB" />

<!-- 日志输出格式 -->

< property name = "LOG_COMMON_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] [%level] %logger - %msg%n" />

< property name = "LOG_DEV_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{48}:%line - %msg%n" />

<!-- 主日志级别 -->

< property name = "ROOT_LEVEL" value = "${log.root.level:-DEBUG}" />

<!-- APP 日志级别 -->

< property name = "APP_LEVEL" value = "${log.app.level:-TRACE}" />

<!-- APP Package 前缀: cn.zollty.demo -->

< property name = "APP_PACKAGE" value = "cn.zollty.demo" />

其中 ${deploy.env:-dev} 代表的意思是,如果环境变量中没有 deploy.env,则使用默认值dev。

一个小技巧:可以自定义类似下面这个类,在logback初始化之前,先设置变量的值:

< statusListener class = "cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener" />

这个类继承自ch.qos.logback.core.status.OnConsoleStatusListener。

关键点2:使用logback的 if-then 条件语法

< root level = "${ROOT_LEVEL}" >

  <!-- Required: exception log -->

  < appender-ref ref = "FILE_EXCEPTION" />

  <!-- Required: app log  -->

  < appender-ref ref = "FILE_APP" />

  < if condition = 'p("DEPLOY_ENV").contains("dev")' >

   < then >

   < appender-ref ref = "STDOUT" />

   </ then >

  </ if >

</ root >

参考配置:

logback.xml:

<? xml version = "1.0" encoding = "UTF-8" ?>

< configuration scan = "true" scanPeriod = "60 seconds" debug = "false" >

  < statusListener class = "cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener" />

  <!-- 部署的环境类型:dev、test、product -->

  < property name = "DEPLOY_ENV" value = "${deploy.env:-dev}" />

  <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到当前目录./logs/下,如果部署到linux上的tomcat下,会输出到tomcat/logs/目录 下 -->

  < property name = "LOG_HOME" value = "${catalina.base:-.}/logs" />

 

  <!-- 日志文件大小,超过这个大小将被压缩 -->

  < property name = "LOG_MAX_SIZE" value = "100MB" />

  <!-- 日志输出格式 -->

  < property name = "LOG_COMMON_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] [%level] %logger - %msg%n" />

  < property name = "LOG_DEV_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{48}:%line - %msg%n" />

  <!-- 主日志级别 -->

  < property name = "ROOT_LEVEL" value = "${log.root.level:-DEBUG}" />

  <!-- APP 日志级别 -->

  < property name = "APP_LEVEL" value = "${log.app.level:-TRACE}" />

  <!-- APP Package 前缀: cn.zollty.demo -->

  < property name = "APP_PACKAGE" value = "cn.zollty.demo" />

 

  < include resource = "includedConfig.xml" />

 

  < appender name = "STDOUT" class = "ch.qos.logback.core.ConsoleAppender" >

   < encoder >

    < pattern >${LOG_DEV_PATTERN}</ pattern >

   </ encoder >

  </ appender >

 

  < appender name = "FILTER-DATA" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < file >${LOG_HOME}/filter.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    < fileNamePattern >${LOG_HOME}/filter/filter-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >90</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     < MaxFileSize >100MB</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

 

  < appender name = "ASYNC1" class = "ch.qos.logback.classic.AsyncAppender" >

   < appender-ref ref = "FILTER-DATA" />

  </ appender >

 

  < include resource = "special_log_level.xml" />

  < logger name = "${APP_PACKAGE}" level = "${APP_LEVEL}" />

 

  < logger name = "FILTER-LOGGER" level = "${APP_LEVEL}" additivity = "false" >

   < appender-ref ref = "ASYNC1" />

  </ logger >

  < root level = "${ROOT_LEVEL}" >

   <!-- Required: exception log -->

   < appender-ref ref = "FILE_EXCEPTION" />

   <!-- Required: app log  -->

   < appender-ref ref = "FILE_APP" />

  

   <!-- Optional: show all debug or trace info -->

   <!-- <appender-ref ref="FILE_DEBUG"/> -->

   <!-- <appender-ref ref="FILE_TRACE"/> -->

  

   < if condition = 'p("DEPLOY_ENV").contains("dev")' >

    < then >

     < appender-ref ref = "STDOUT" />

    </ then >

   </ if >

  

  </ root >

</ configuration >

includedConfig.xml

<? xml version = "1.0" encoding = "UTF-8" ?>

< included >

  <!-- WARN and ERROR -->

  < appender name = "FILE_EXCEPTION" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < filter class = "ch.qos.logback.classic.filter.ThresholdFilter" >

    < level >WARN</ level >

   </ filter >

   < file >${LOG_HOME}/error.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    <!-- rollover daily -->

    < fileNamePattern >${LOG_HOME}/error/error-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >600</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     <!-- or whenever the file size reaches 100MB -->

     < MaxFileSize >${LOG_MAX_SIZE}</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

  <!-- INFO or Greater -->

  < appender name = "FILE_INFO" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < filter class = "ch.qos.logback.classic.filter.ThresholdFilter" >

    < level >INFO</ level >

   </ filter >

   < file >${LOG_HOME}/info.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    < fileNamePattern >${LOG_HOME}/info/info-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >50</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     < MaxFileSize >${LOG_MAX_SIZE}</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

  <!-- DEBUG or Greater-->

  < appender name = "FILE_DEBUG" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < filter class = "ch.qos.logback.classic.filter.ThresholdFilter" >

    < level >DEBUG</ level >

   </ filter >

   < file >${LOG_HOME}/debug.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    < fileNamePattern >${LOG_HOME}/debug/debug-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >50</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     < MaxFileSize >${LOG_MAX_SIZE}</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

  <!-- TRACE and ALL -->

  < appender name = "FILE_TRACE" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < file >${LOG_HOME}/trace.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    < fileNamePattern >${LOG_HOME}/trace/trace-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >10</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     < MaxFileSize >${LOG_MAX_SIZE}</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

 

  <!-- (INFO or Greater) or logname prefix = ${APP_PACKAGE} -->

  < appender name = "FILE_APP" class = "ch.qos.logback.core.rolling.RollingFileAppender" >

   < filter class = "cn.zollty.demo.common.PackageOrThresholdFilter" >

    < level >INFO</ level >

    < prefix >${APP_PACKAGE}</ prefix >

   </ filter >

   < file >${LOG_HOME}/app.log</ file >

   < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >

    < fileNamePattern >${LOG_HOME}/app/app-%d{yyyy-MM-dd}-%i.log.zip</ fileNamePattern >

    < maxHistory >600</ maxHistory >

    < TimeBasedFileNamingAndTriggeringPolicy class = "ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" >

     < MaxFileSize >${LOG_MAX_SIZE}</ MaxFileSize >

    </ TimeBasedFileNamingAndTriggeringPolicy >

   </ rollingPolicy >

   < encoder >

    < pattern >${LOG_COMMON_PATTERN}</ pattern >

   </ encoder >

  </ appender >

</ included >

special_log_level.xml

<? xml version = "1.0" encoding = "UTF-8" ?>

< included >

  < logger name = "org.apache.zookeeper.ClientCnxn" level = "ERROR" />

  < logger name = "org.apache.kafka.clients.consumer.internals.ConsumerCoordinator" level = "INFO" />

  < logger name = "kafka.producer.BrokerPartitionInfo" level = "INFO" />

  < logger name = "kafka.producer.async.ProducerSendThread" level = "INFO" />

  < logger name = "kafka.producer.async.DefaultEventHandler" level = "INFO" />

  < logger name = "org.apache.kafka.common.metrics.Metrics" level = "INFO" />

  < logger name = "org.apache.kafka.clients.Metadata" level = "INFO" />

 

  < logger name = "org.apache.kafka.clients.consumer.internals.AbstractCoordinator" level = "INFO" />

  < logger name = "org.apache.kafka.clients.consumer.internals.Fetcher" level = "INFO" />

  < logger name = "org.apache.kafka.clients.NetworkClient" level = "INFO" />

 

</ included >

也可以把变量定义到properties文件中,本地就放在

src/resources/conf/logback_val.properties

服务器上放在

${catalina.base}/conf/logback_val.properties

配置如下:

<? xml version = "1.0" encoding = "UTF-8" ?>

< configuration scan = "true" scanPeriod = "60 seconds" debug = "false" >

  < if condition = 'isDefined("catalina.base")' >

   < then >

    < property file = "${catalina.base}/conf/logback_val.properties" />

   </ then >

   < else >

    < property resource = "./conf/logback_val.properties" />

   </ else >

  </ if >

 

  ...

logback_val.properties:

# deploy environment : dev, test, pre, prod

deploy.env=dev

# the root log level

log.root.level=DEBUG

# the app log level

log.app.level=TRACE

# to use Kafka LogStash value= "yes" or "no"

log.use.logstash=yes

# LogStash Kafka URL

log.logstash.kafka=172.16.1.164:9092,172.16.1.165:9092,172.16.1.166:9092

同理,可以根据  dev开发环境、test测试环境、prod生产环境来读取不同的配置。

<? xml version = "1.0" encoding = "UTF-8" ?>

< configuration scan = "true" scanPeriod = "60 seconds" debug = "false" >

  < property resource = "./conf/logback-${deploy.env}.properties" />

  ...

参考资料:

http://logback.qos.ch/manual/configuration.html#conditional


以上所述就是小编给大家介绍的《Logback最佳实践和使用指导》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Mechanics of Web Handling

The Mechanics of Web Handling

David R. Roisum

This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具