项目的日志输出
1.关于日志在项目中的logback.xml配置
配置文件内容
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--日志配置-->
<property name="PROJECT_NAME" value="order-finance-error"/>
<property name="LOG_BASE" value="/home/product/logs"/>
<property name="LOG_BACK_DIR" value="${LOG_BASE}/${PROJECT_NAME}_logs"/>
<!-- 监控日志 START-->
<property name="MONITORLOG_DIR" value="/home/product/logs/fsof_monitor/" />
<appender name="MONITOR_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${MONITORLOG_DIR}/provider_service.log</File>
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${MONITORLOG_DIR}/provider_service.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>%m%n
</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="MONITOR_LOG" level="INFO" additivity="false">
<appender-ref ref="MONITOR_APPENDER" />
</logger>
<!-- 监控日志 END-->
<!-- logback 工程的日志配置-->
<appender name="INFO_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_BACK_DIR}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily -->
<fileNamePattern>${LOG_BACK_DIR}/info_%d{yyyyMMddHH}.log</fileNamePattern>
<maxHistory>48</maxHistory>
<!-- 保存最大文件数 2天的日志-->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{threadId}|%X{traceId}-%X{rpcId}|%level|%C|%M|%L|uid=%X{uid},deviceId=%X{deviceId},sessionId=%X{sessionId},requestId=%X{requestId},tradeId=%X{tradeId},clientIp=%X{clientIp}|%.-512msg|%X{callChain}%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 只打印错误日志 -->
<level>INFO</level>
</filter>
</appender>
<appender name="ERROR_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_BACK_DIR}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily -->
<fileNamePattern>${LOG_BACK_DIR}/error_%d{yyyyMMdd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
<!-- 保存最大文件数-->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{threadId}|%X{traceId}-%X{rpcId}|%level|%C|%M|%L|uid=%X{uid},deviceId=%X{deviceId},sessionId=%X{sessionId},requestId=%X{requestId},tradeId=%X{tradeId},clientIp=%X{clientIp}|%.-512msg|%X{callChain}%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 只打印错误日志 -->
<level>WARN</level>
</filter>
</appender>
<appender name="DEBUG_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_BACK_DIR}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily -->
<fileNamePattern>${LOG_BACK_DIR}/debug_%d{yyyyMMddHH}.log</fileNamePattern>
<maxHistory>48</maxHistory>
<!-- 保存最大文件数-->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{threadId}|%X{traceId}-%X{rpcId}|%level|%C|%M|%L|uid=%X{uid},deviceId=%X{deviceId},sessionId=%X{sessionId},requestId=%X{requestId},tradeId=%X{tradeId},clientIp=%X{clientIp}|%.-512msg|%X{callChain}%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!-- 只打印错误日志 -->
<level>TRACE</level>
</filter>
</appender>
<!-- logback 工程的日志配置 END-->
<!-- logback 工程的日志配置 END-->
<!-- 开发环境使用 打印在控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<param name="Pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS}|%X{threadId}|%X{traceId}-%X{rpcId}|%level|%C|%M|%L|uid=%X{uid},deviceId=%X{deviceId},sessionId=%X{sessionId},requestId=%X{requestId},tradeId=%X{tradeId},clientIp=%X{clientIp}|%.-512msg|%X{callChain}%n"/>
</layout>
</appender>
<logger name="org.springframework" level="WARN" />
<logger name="java.sql.Connection" level="INFO" />
<logger name="java.sql.ResultSet" level="INFO" />
<logger name="org.apache.zookeeper.ClientCnxn" level="WARN"/>
<logger name="org.mybatis.spring.SqlSessionUtils" level="WARN" />
<!--开发环境为DEBUG等级-->
<root level="INFO">
<appender-ref ref="INFO_ROLLING"/>
<appender-ref ref="DEBUG_ROLLING"/>
<appender-ref ref="ERROR_ROLLING"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>
2.日志的名词解释用法
1.主题标签
"<"configuration">"
2.控制台输出的标签:
"<“Console name= “Console” target=“SYSTEM_OUT”>”
这个标签估计都能猜到是用于控制台日志打印的;其中:
name属性随意取,是给标签用的。 target属性是输出,我只知道这个值。
3.文件输出标签
"<"File name=“log” fileName=“log/test.log” append=“false”>
filePattern属性是用来声明每个存档文件的名字。
4. 日志集标签:
> <loggers>
子标签
<root level="trace">
<appender-ref ref="RollingFile"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
<SizeBasedTriggeringPolicy size="2MB"/>
level等级:
Log4J Levels | TRACE Level | DEBUG Level | INFO Level | WARN Level | ERROR Level | FATAL Level |
TRACE Level | Y | Y | Y | Y | Y | Y |
DEBUG Level | N | Y | Y | Y | Y | Y |
INFO Level | N | N | Y | Y | Y | Y |
WARN Level | N | N | N | Y | Y | Y |
ERROR Level | N | N | N | N | Y | Y |
FATAL Level | N | N | N | N | N | Y |
ALL Level | Y | Y | Y | Y | Y | Y |
OFF Level | N | N | N | N | N | N |
5.语义符
1.%c 输出日志信息所属的类的全名
2.%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-M-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
3.%f 输出日志信息所属的类的类名
4.%l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
5.%m 输出代码中指定的信息,如log(message)中的message
6.%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
7.%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推
8.%r 输出自应用启动到输出该日志信息所耗费的毫秒数
9.%t 输出产生该日志事件的线程名
3.如何打印日志输出
1)日志输出级别的判断
对DEBUG、INFO级别的日志,必须使用条件输出或者使用占位符的方式打印
举个反例:
> log.debug("输入参数信息id=" + id + ",obj=" + obj);
正确示例:
//使用条件判断形式
if (log.isDebugEnabled()) {
log.debug(“输入参数信息id={}”, id);
}
//使用占位符形式
log.debug(“输入参数信息id={},obj={}”, id, obj);
2)区别对待错误日志
WARN、ERROR都是与错误有关的日志级别,但不要一发生错误就打印ERROR日志,比如一些业务异常是可以通过引导重试就能恢复的,例如用户输入参数错误,在这种情况下,记录日志是为了在用户咨询时可以还原现场如果输出为ERROR级别就表示一旦出现就需要人为介入,这显然不合理。所以,ERROR级别只记录系统逻辑错误、异常或者违反重要的业务规则,其他错误都可以归为WARN级别。
3)输出完整内容
日志记录内容包括上下文内容和异常堆栈信息,所以需要:
1.日志异常时一定要输出异常堆栈,例如:
log.error(“xxx” + e.getMessage(), e);
2.日志中如果需要输出对象实例,要确保实例类重写了toString方法,否则只会打印对象的hashCode值,没有意义