如何优雅的在log日志中打印操作人

如何优雅的在log日志中打印操作人

本文中的log日志基于slf4j,使用的注解为lombok.extern.slf4j
本文的日志打印使用logback.xml配置
仅提供了如何打印日志,不包含如何优雅的写日志
更新:今日发现一个如何优雅的写日志的文章,在这里引用一下以做记录打印优质日志的 10 条军规


一、将操作人添加到日志中

 
这里利用到slf4j的MDC,调用put(key,val)会将值塞入mdcAdapter(LogbackMDCAdapter)中
MDC
在logback.xml中可以使用%X{key}获取val

例如key为user,值为张三

MDC.put("user","张三");

在logback.xml中即可用%X{user}获取到张三

<!-- 这是一个完整的日志pattern,你可以将%X{user}放到任何一个位置 -->
<property name="PATTERN"
              value="%date{yyyy-MM-dd HH:mm:ss.SSS} ${profile} [%level]  --- [%thread] [${application}] %logger{26} - %X{user} - %msg%n"/>

 
添加认证拦截器,在用户携带登录信息访问时,使用MDC将需要写入日志的操作人放入自定义的key中,然后在logback.xml的pattern中添加%X{key},即可在打印日志时打印出操作人的信息。
java案例代码如下

@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
              // 获取当前登录的用户
              UserInfoDTO user = getUserInfo();

			  if (Objects.isNull(user)) {
			  		/**
                     * 无需登录用户即可访问的,则不在MDC中存值
                     * 如果有某些业务需要记录访问人,可以在业务逻辑执行前,将参数中标记用户的参数放入user中,
                     * 		如MDC.put("user", param.getCellphone());
                     */
			  		return true;
			  }
			  MDC.put("user", user.getUsername() + ":" +user.getRealName());
        }

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        MDC.clear();
    }
}

xml案例代码如下

<property name="LOG_FILE" value="xxx"/>
<property name="PATTERN"
              value="%date{yyyy-MM-dd HH:mm:ss.SSS} ${profile} [%level]  --- [%thread] [${application}] %logger{26} - %X{user} - %msg%n"/>
              
<!-- 中间略过啦 -->

<root level="INFO">
	 <!-- 控制台输出,具体不作展示 -->
     <appender-ref ref="STDOUT"/>
     <!-- 输出到文件,具体不作展示 -->
     <appender-ref ref="LOG_OUT"/>
</root>

xml案例代码如下
访问接口,从接口中打印的log日志就可以看到 admin:张三 这个操作人信息
在这里插入图片描述


二、自定义日志打印操作人

虽然日志成功打印了,但是一些查询语句之类的也加上了操作人,有些小伙伴只想在自定义日志上加操作人,就需要进一步的进行改造啦。
 
Slf4j注解中有个topic值,用来指定采用的logger。如果不传参,或者参数与logback中的logger不对应,就会默认走name为root的logger。

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface Slf4j {
    String topic() default "";
}
&nbsp;

先在logback中注册一个logger,name自定义

	<!-- name如果设置包名,则指定包下的所有日志都走这个配置;如果设置自定义名称,则topic一致的走这个配置  -->
	<!-- additivity为false,则只走自定义的appender-ref,为true,则日志还会走root的appender-ref -->
    <logger name="CUSTOM_LOGGER" level="INFO" additivity="false">
    	<!-- 这里STDOUT_USER与上边的STDOUT,上边的STDOUT的pattern改为无%X{user}的  -->
        <appender-ref ref="STDOUT_USER"/>
    </logger>

将@Slf4j注解改为@Slf4j(topic = “CUSTOM_LOGGER”)
这样就可以将自定义日志和系统日志分开,输入日志如下:
在这里插入图片描述
细心的小伙伴会发现,这里的logger中,只使用了控制台输出,而没有采用log文件输出。原因是如果多个采用的logger,文件输出指向同一个文件,则启动项目时会报错,因此我们还需要继续改造。


三、自定义日志存到其他文件

logback.xml新做一个appender-ref,指向另一个log文件配置LOG_FILE_USER,文件输出为yyy,将自定义日志的文件与系统日志的区分开。

<property name="LOG_FILE" value="xxx"/>
<property name="LOG_FILE_USER" value="yyy"/>
<property name="PATTERN"
              value="%date{yyyy-MM-dd HH:mm:ss.SSS} ${profile} [%level]  --- [%thread] [${application}] %logger{26} - %X{user} - %msg%n"/>
              
<!-- 中间略过啦 -->

<!-- 这里的additivity为什么改为true,下边会做讲解 -->
<logger name="CUSTOM_LOGGER" level="INFO" additivity="true">
        <appender-ref ref="STDOUT_USER"/>
        <appender-ref ref="LOG_OUT_USER"/>
</logger>
<root level="INFO">
	 <!-- 控制台输出,具体不作展示 -->
     <appender-ref ref="STDOUT"/>
     <!-- 输出到文件,具体不作展示 -->
     <appender-ref ref="LOG_OUT"/>
</root>

如果additivity为false,操作日志在yyy文件中,而系统日志在xxx文件,有些业务需要通过操作日志+sql来排查问题,就会变得非常麻烦。因此可以将additivity改为true,将操作日志在操作日志文件中打印一份,系统日志文件中打印一份。
控制台的日志输出如下:
在这里插入图片描述
至此,我们已将操作人优雅的打印到了log日志中~


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值