第一课:springboot结合使用logback的
关于springboot 的使用或者入门的案例网上有一大堆;这里就不给具体的入门案例了
这里介绍一下项目中常用的logback的使用.
一:项目的目录内容
二:代码片段
pom文件内容
LogController
@RestController
public class LogController {
private static final Logger log = LoggerFactory.getLogger(LogController.class);
@RequestMapping("/log")
public String log(){
log.debug("debug日志级别的日志");
log.info("info日志级别的日志");
log.error("error日志级别的日志");
return "执行完毕";
}
}
logback.xml 配置内容
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/data/test/" />
<!-- 控制台输出 -->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
</appender>
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/error/log_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log/error/log-error-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录error级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/info/log_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log/info/log-info-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别 过滤掉非INFO级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="DEBUG">
<appender-ref ref="FILEERROR" />
<appender-ref ref="FILEINFO" />
<!-- 生产环境将请stdout,testfile去掉 -->
<appender-ref ref="consoleAppender" />
</root>
</configuration>
三:自定义的日志配置内容
项目中我能可能需要根据模块记录不同的日志信息,我们可以通过在logback.xml里面配置不同的appender
里面设置根据模块区分的日志文件内容; 将里面不同模块的日志文件记录到不同的文件夹中去这里
这里测试模块是logback.xml里面是配置的khy这个appender ,然后再java代码中通过
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger khy = LoggerFactory.getLogger(“KHY”);
去获取log代码 “KHY” 这个是logback.xml里面的 logger标签里面配置的
LogController 中的代码
@RestController
public class LogController {
private static final Logger log = LoggerFactory.getLogger(LogController.class);
private static final Logger khy = LoggerFactory.getLogger("KHY");
@RequestMapping("/log")
public String log(){
log.debug("debug日志级别的日志");
log.info("info日志级别的日志");
log.error("error日志级别的日志");
khy.debug("debug日志级别的日志");
khy.info("info日志级别的日志");
khy.warn("warn日志级别的日志");
khy.error("error日志级别的日志");
return "执行完毕";
}
}
logback.xml
<!-- 自定义的 日志内容 -->
<appender name="khy" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/khy/khy_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/khy/khy-info-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%X{requestId} === %d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别 过滤掉非debug级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="KHY" level="debug" additivity="false">
<appender-ref ref="khy" />
<appender-ref ref="consoleAppender" />
</logger>
项目启动之后会生成对应的khy 的文件夹内容
四:关于appender和logger里面组合
关于日志文件里面的级别设置内容;
案例一:a,b级别都是info
结果描述:
配置项a 中的level 和配置项 b中的 level配置的都是 info
日志打印的结果是 控制台打印的是info级别以上日志信息;
但是日志文件中记录的只是info级别的日志文件 ;
案例二:a级别是info b是debug
结果描述:
配置项a中的配置不变 配置项b中的配置是debug
控制台debug及以上的日志全部打印
日志文件中记录的还是配置a中设置的info级别的日志内容;
案例三:a,b都是debug
结果描述:
配置项a,b的level都是debug 内容; 控制台打印debug及以上的日志;日志文件中记录的是debug级别的日志内容;
案例四:a配置是debug ,b配置是info
结果描述:
因为配置a里面是debug 级别小于配置项b 的配置;所以日志文件中不会记录对应的内容;
但是控制台会打印info及以上级别的日志信息
案例五:b配置level不配置
结果描述:
配置项a level配置的是debug 配置项b不配置 则控制台打印的所有级别 但是日志文件记录的还是debug级别的
案例六:配置项a不设置level
结果描述:
因为配置项a不设置level 任一级别的; 但是配置项b设置的是info;所以只有info级别及以上的日志信息会被控制台打印和记录到日志文件
总结内容
配置项b的level:用来设置打印级别,
配置项a中appender 里面配置的level是用来记录到日志文件的级别
例如开发期间为了方便调试代码可以设置更详细的日志信息;我们添加很多debug级别的日志,但是上线之后这样日志其实不需要就可以设置关闭即可,然后配置的appender也是debug级别的;在logger上设置成debug那么所有debug级别及以上的都会被记录;上线之后可以把logger 的level改成info 这样debug级别的日志不会再被记录
level 大小 :
ERROR > WARN > INFO > DEBUG > TRACE
程序会打印高于或等于所设置级别的日志
因为配置项b中可以设置多个appender-ref 多个级别
然后需要配置项a对具体的 appender-ref的对日志进行细化处理;
五:设置统一的requestId内容
当项目部署之后想在日志里面查询某一次请求的所有的日志文件;可以在请求进来的地方本案例是在LogFilter 通过
主要是通过前端请求添加一个过滤器filter在请求之前先给日志添加上统一的日志的编码requestId
LogFilter 中的代码内容
@Component
public class LogFilter implements Filter {
private static final Logger khy = LoggerFactory.getLogger("KHY");
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
try {
///设置 日志统一的 requestId内容 这个随意
String reqId = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS") + RandomStringUtils.randomNumeric(8);
//在请求进来的地方先设置requestId,然后在后面日志记录的地方都可以通过requestId
MDC.put("requestId", reqId);
khy.debug("请求url={}开始执行",request.getRequestURL());
chain.doFilter(servletRequest, servletResponse);
} catch (Exception e) {
khy.debug("请求url={}执行异常e{}",request.getRequestURL(),e.getMessage());
e.printStackTrace();
}finally {
MDC.remove("requestId");
}
return;
}
@Override
public void destroy() {
}
}
然后需要在logback里面的appender 里面的日志的格式需要修改
<!-- 自定义的 日志内容 -->
<appender name="khy" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/khy/khy_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/khy/khy-info-%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<append>true</append>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%X{requestId} === %d{yyyy-MM-dd HH:mm:ss.SSS} %contextName %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别 过滤掉非debug级别 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
里面主要在 %X{requestId} 里面然后日志的格式内容
以上的配置就是logback基本配置,可以满足大部分的项目需求