一、概述
1、采用slf4j作为日志API,采用logback作为日志输出工具,用slf4j桥接方式替换掉log4j和commons-logging。
2、采用trace(追踪)、debug(调试)、info(信息)、warn(警告)、error(错误)、fatal(致命)共6种日志级别。
3、采用dev(开发环境)、test(测试环境)、production(生产环境)等不同的日志配置,根据环境变量自动识别。
4、特殊的记录,需要大批量写入日志文件,应该采用异步线程写文件。
二、日志级别定义
采用trace(追踪)、debug(调试)、info(信息)、warn(警告)、error(错误)、fatal(致命)共6种日志级别。
日志级别使用原则:
1、fatal(致命错误)使用原则
fatal为系统级别的异常,发生fatal错误,代表服务器整个或者核心功能已经无法工作了!!
1)在服务器启动时就应该检查,如果存在致命错误,直接抛异常,让服务器不要启动起来(启动了也无法正常工作,不如不启动)。
2)如果在服务器启动之后,发生了致命的错误,则记录fatal级别的错误日志,最好是同时触发相关的修复和告警工作(比如,给开发和维护人员发送告警邮件)。
2、error(错误)使用原则
error为功能或者逻辑级别的严重异常,发生error级别的异常,代表功能或者重要逻辑遇到问题、无法正常工作。
3、warn(警告)使用原则
warn用在某些逻辑非常规,发生了一些小故障但是没有大的影响,或者重要数据被修改,或者某些操作需要引起重视。
4、info(信息)使用原则
info用于记录一些有用的、关键的信息,一般这些信息出现得不频繁,只是在初始化的地方或者重要操作的地方才记录。
5、debug(调试)使用原则
debug用于记录一些调试信息,为了方便查看程序的执行过程和相关数据、了解程序的动态。
6、trace(跟踪)使用原则
trace用于记录一些更详细的调试信息,这些信息无需每次调试时都打印出来,只在需要更详细的调试信息时才开启。
7、项目稳定运行时的日志量
1)正常情况下,trace日志至少是debug日志的100倍,
trace级别的日志量 : debug级别的日志量 > 100 : 1,
也就是说trace日志非常多,debug日志相对较少。
2)debug级别的日志量 : info级别的日志量 > 1000 : 1,
也就是说正常情况下,info日志很少,只在部分重要位置会输出 info日志。
3)error日志和warn日志,正常情况下,几乎为0,当出现异常时,error日志和warn日志量 也在可控范围,不会超过debug级别的最大日志量。
三、日志输出(Appender)分类
分为5个一般类:
FILE_EXCEPTION (异常日志,包括ERROR和WARN)
FILE_APP (应用日志,包括当前应用package下面的日志和DEBUG级别以上的其他日志)
FILE_INFO (普通信息日志)
FILE_DEBUG (调试日志)
FILE_TRACE(追踪日志)
SYSOUT(控制台输出,可以包括以上所有日志)
扩展类: 包括异步输出的日志,或者特殊业务日志。
举例说明:
假如
当前应用的 Main Package 为 cn.zollty.lightning
ROOT_LEVEL为 trace,应用日志 LEVEL 为 debug
有以下日志打印:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Logger loggerA = LoggerFactory.getLogger(cn.zollty.lightning.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("--------");
2、历史日志文件
异常日志(error和warn)最多保存 9000 M(生产,测试)
app日志最多保存 9000 M (生产,测试)
trace日志最多保存 1000 M (仅供测试用,一般不用)
debug、info日志最多保存 5000 M(一般不用,用app日志就够了)
四、各环境默认日志定义
开发环境
1)默认日志级别定义为:
app包为TRACE级别。日志的ROOT Level为DEBUG级别。
2)
启用 System.out 控制台输出日志;
启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。
测试环境
1)默认日志级别定义为:
app包为DEBUG级别。日志的ROOT Level为DEBUG级别。
2)
禁用 System.out 控制台输出日志;
启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。
生产环境
1)默认日志级别定义为:
app包为DEBUG级别。日志的ROOT Level为INFO级别。
2)
禁用 System.out 控制台输出日志;
启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。
五、根据环境自动选择日志配置(借助Logback)
关键点1:使用logback的环境变量定义和读取功能
例如下面的各种环境变量定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<
property
name
=
"DEPLOY_ENV"
value
=
"${deploy.env:-dev}"
/>
<
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}"
/>
<
property
name
=
"APP_LEVEL"
value
=
"${log.app.level:-TRACE}"
/>
<
property
name
=
"APP_PACKAGE"
value
=
"cn.zollty.lightning"
/>
|
其中 ${deploy.env:-dev} 代表的意思是,如果环境变量中没有 deploy.env,则使用默认值dev。
一个小技巧:可以自定义类似下面这个类,在logback初始化之前,先设置变量的值:
1
|
<
statusListener
class
=
"cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener"
/>
|
这个类继承自ch.qos.logback.core.status.OnConsoleStatusListener。
关键点2:使用logback的 if-then 条件语法
1
2
3
4
5
6
7
8
9
10
11
12
|
<
root
level
=
"${ROOT_LEVEL}"
>
<
appender-ref
ref
=
"FILE_EXCEPTION"
/>
<
appender-ref
ref
=
"FILE_APP"
/>
<
if
condition
=
'p("DEPLOY_ENV").contains("dev")'
>
<
then
>
<
appender-ref
ref
=
"STDOUT"
/>
then
>
if
>
root
>
|
参考配置:
logback.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
configuration
scan
=
"true"
scanPeriod
=
"60 seconds"
debug
=
"false"
>
<
statusListener
class
=
"cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener"
/>
<
property
name
=
"DEPLOY_ENV"
value
=
"${deploy.env:-dev}"
/>
<
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}"
/>
<
property
name
=
"APP_LEVEL"
value
=
"${log.app.level:-TRACE}"
/>
<
property
name
=
"APP_PACKAGE"
value
=
"cn.zollty.lightning"
/>
<
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}"
>
<
appender-ref
ref
=
"FILE_EXCEPTION"
/>
<
appender-ref
ref
=
"FILE_APP"
/>
<
if
condition
=
'p("DEPLOY_ENV").contains("dev")'
>
<
then
>
<
appender-ref
ref
=
"STDOUT"
/>
then
>
if
>
root
>
configuration
>
|
includedConfig.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
included
>
<
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"
>
<
fileNamePattern
>${LOG_HOME}/error/error-%d{yyyy-MM-dd}-%i.log.zip
fileNamePattern
>
<
maxHistory
>90
maxHistory
>
<
TimeBasedFileNamingAndTriggeringPolicy
class
=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<
MaxFileSize
>${LOG_MAX_SIZE}
MaxFileSize
>
TimeBasedFileNamingAndTriggeringPolicy
>
rollingPolicy
>
<
encoder
>
<
pattern
>${LOG_COMMON_PATTERN}
pattern
>
encoder
>
appender
>
<
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
>
<
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
>
<
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
>
<
appender
name
=
"FILE_APP"
class
=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<
filter
class
=
"cn.zollty.lightning.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
>90
maxHistory
>
<
|