在tomcat web项目中, 一次用户请求在同步情况下都是交给同一个线程去处理,如果能知道这个线程的处理路径,可以方便线上问题的排查、代码的调试。因此可以让同一次请求的线程日志带上同一个唯一的token,在查询日志时,grep token可以把相关的日志都查询出来。这时,如果已经在代码逻辑关键部分已经打印了日志,那么可以准确知道这次请求执行了哪些代码。
日志框架通常提供了一定的灵活性,以log4j和log4j2为例。
继承log4j的PatternParser类,并重写finalizeConverter方法,实现对自定义字符的解析,并ThreadTokenHelper.getThreadToken()返回自定义的token信息。
继承log4j的PatternLayout类,并重写createPatternParser方法。
PatternLayout。[%T]就是我们token信息的位置,通过上面的重写log解析,可以解析’T’这个字符。
生成token算法,head与时间相关,精确到毫秒,body是线程号,foot是随机数。head模一天的毫秒数(),这样生成的token在某一天内,可以保证唯一性。
ThreadLocal中,token能在同一个线程中进行传递。在这里主要需要,当一个请求结束后,把存储在当前ThreadLocal中的token清除,那么当下一个请求处理时,会重新获取新的token存储在ThreadLocal中。遇到异常抛出时,代码不会执行到这里,这时需要在异常处理的地方对线程ThreadLocal中的token进行清除。
intercepter清除token,同时可以打印出请求访问的相关信息,访问用户,
在Spring配置文件中的配置
下图红框内,就是一次请求唯一token信息,可以看到,两个token是相同的。通过grep ‘token’ log就可以把这次请求的所有日志都查询出来,可以追踪程序的运行,方便排查问题。


5.1 异常情况
因为每一个请求都是绑定一个线程,并生成唯一token与此线程绑定,通过spring inteceptor在请求后清除此请求的token信息。如果发生异常时,会导致inteceptor不能在请求后清除token信息,会导致请求的token信息重复。这个时候需要在异常拦截的地方,手动清除下存储在线程token信息。
5.2 多线程处理
有这样的场景,一个API在处理过程中,需要调用异步方法发送消息,在调用异步方法时就会有第二条线程来处理,这个时候,一个请求就会有两个token信息。通过查询一个token,只能得到部分日志。
5.3 单线程处理多任务
在使用消息队列的业务里,消费者可用使用单线程来处理多条消息,每一条消息是一个任务,应该在每一条消息处理后,手动清除下线程中的token信息,这样在处理下一条消息时,日志信息中会是新的token,从而不会与上一条消息的处理日志产生混淆。
6.拓展

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/175262.html