1.思路描述
思路:这个文章通过SpringBoot使用logback插件实现自定义字段分割日志文件的的思路。例子比较简单(各位小伙伴可以在此基础上发散思维),在前端使用axios请求接口时将指定字段添加在header中 后端通过logback配置使日志按照字段分割
扩展使用场景:字段可以是前端登陆的用户名,实现按用户分割的用户操作日志。 如下图:
2.关键实现
前端demo:
使用axios请求接口,非登录接口一律验证登陆用户名,已登录用户请求接口时将用户名添加在请求头中 (ps 添加在其他地方也随意 例如作为post get请求的参数都ok)
/**
* http配置
*/
import iView from 'iview';
import router from '../../src/router.js'
import axios from 'axios'
let l = true;
// 发送请求前
axios.interceptors.request.use(
config => {
// 判断不是登录接口
if(config.url.indexOf('login') == -1){
if(!localStorage.username){
window.App.$router.push('/login')
}else{
// let _token = localStorage.bearer
// // config.headers['ip'] = localStorage.userIp
// _token && (config.headers['Authorization'] = _token);
localStorage.username && (config.headers['username'] = encodeURIComponent(localStorage.username))
}
}else{
localStorage.username && (config.headers['username'] = encodeURIComponent(localStorage.username))
}
config.timeout = 1800000
return config;
},
err => {
return Promise.reject(err);
}
)
export default axios
后端配置:
Springboot自动支持所以直接上配置
要想实现按照指定名称动态分割日志需要如下面格式
<appender name="AopInfo" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>userName</key>
<defaultValue>小明</defaultValue>
</discriminator>
<sift>
<appender name="aop-${userName}"class="ch.qos.logback.core.rolling.RollingFileAppender">
</appender>
</sift>
</appender>
解释:1 class="ch.qos.logback.classic.sift.SiftingAppender
解释:2 本实例表示 (userName默认值小明,当请求接口没有附带username时 使用默认值)
<discriminator>
<key>userName</key>
<defaultValue>小明</defaultValue>
</discriminator>
解释:3 <sift></sift>
用来包裹实际生成日志文件的<appender></appender>配置
解释:4 name="aop-${userName}"
${userName} 会根据程序运行时 userName实际值动态生成
主要部分配置(ps: 这个只是分割功能的配置不是页面完整位置,没用过logback看不懂配置的之后会重新写一篇基础配置解释下xml文件的基本配置)
<appender name="AopInfo" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>userName</key>
<defaultValue>小明</defaultValue>
</discriminator>
<sift>
<appender name="aop-${userName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志文件路径和名称-->
<File>logs/WholeMachineTest/aop/${userName}_aop_info.log</File>
<!--是否追加到文件末尾,默认为true-->
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch><!-- 如果命中就使用这条规则 -->
<onMismatch>DENY</onMismatch><!-- 如果没有命中就禁止这条日志-->
</filter>
<!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
<!-- 文件名:logs/project_info.2017-12-05.0.log -->
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
<fileNamePattern>logs/WholeMachineTest/aop/%d/${userName}_aop_info.%i.log</fileNamePattern>
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
<maxHistory>30</maxHistory>
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
<totalSizeCap>20GB</totalSizeCap>
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!--编码器-->
<encoder>
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
<!-- 记录日志的编码:此处设置字符集 - -->
<charset>UTF-8</charset>
</encoder>
</appender>
</sift>
</appender>
<logger name="com.ceiec.WholeMachineTest" level="DEBUG" >
<appender-ref ref="AopInfo" />
</logger>
后端动态值设置:
看完前面部分,会产省疑问
<discriminator>
<key>userName</key>
<defaultValue>小明</defaultValue>
</discriminator>
上面配置了默认值,那怎么根据前端传来的用户名动态设置呢?
说明:Springboot开发时 我们会写 拦截器 过滤器 或者使用 @Aspect注解切面 我们只需要在原来的代码中加入以下内容 MDC是什么可以查看文档自行学习 : http://www.logback.cn/01%E7%AC%AC%E4%B8%80%E7%AB%A0logback%E4%BB%8B%E7%BB%8D.html
MDC.put("userName",username); 拦截到请求方法时 得到前端请求参数 如此设置
MDC.clear(); 请求方法结束后 使用这个
如此 我们在接口的方法中使用 log.debug("","")时候 配置文件会自动生成 按照配置文件规则的 日志
结果