我创建了一个基于Spring的Java Web应用程序,
对于每个请求,将创建一个"控制器类"实例来处理请求.
在业务逻辑中,我希望使用自动分配给每个请求的UNIQUE ID进行一些日志记录,以便我可以跟踪程序的确切操作.
日志可能是这样的(同时有2个请求):
[INFO] request #XXX: begin.
[INFO] request #XXX: did step 1
[INFO] request #YYY: begin.
[INFO] request #XXX: did step 2
[INFO] request #YYY: did step 1
[INFO] request #XXX: end.
[INFO] request #YYY: end.
Run Code Online (Sandbox Code Playgroud)
从日志中,我可以实现:req #XXX:begin-step1-step2-end req #YYY:begin-step1-end
我希望可以在代码中的任何地方轻松调用日志记录,因此我不想在每个java函数中添加"requestId"参数,
如果可以以静态方式调用日志工具,那将是完美的:
LOG.doLog("did step 1");
Run Code Online (Sandbox Code Playgroud)
我怎么能这样做呢?谢谢 :)
Sha*_*adr 31
您也可以尝试使用Log4j的MDC类.MDC基于每个线程进行管理.如果您使用的是ServletRequestListner,则可以在requestInitialized中设置唯一ID.
import org.apache.log4j.MDC;
import java.util.UUID;
public class TestRequestListener implements ServletRequestListener {
protected static final Logger LOGGER = LoggerFactory.getLogger(TestRequestListener.class);
public void requestInitialized(ServletRequestEvent arg0) {
LOGGER.debug("++++++++++++ REQUEST INITIALIZED +++++++++++++++++");
MDC.put("RequestId", UUID.randomUUID());
}
public void requestDestroyed(ServletRequestEvent arg0) {
LOGGER.debug("-------------REQUEST DESTROYED ------------");
MDC.clear();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您执行日志调试,警告或错误,现在代码中的任何位置.无论你输入MDC的是什么,都会打印出来.您需要配置log4j.properties.注意%X {RequestId}.这引用了上面的requestInitialized()中插入的键名.
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %X{RequestId} - %m%n
Run Code Online (Sandbox Code Playgroud)
我也发现这个链接很有用 - > Log4j的NDC和MDC设施有什么区别?
MPa*_*esi 19
您有三个不同的问题需要解决:
我会建议这种方法
使用Servlet过滤器或ServletRequestListener(由M. Deinum建议)或Spring Handler Interceptor 以一般方式拦截请求,在那里你可以创建一个唯一的id,可能有一个UUID
您可以将id保存为请求的属性,在这种情况下,id将仅在控制器层中传播,而不是在服务中传播.所以,你可以解决使用问题的ThreadLocal变量或询问春天做魔术与RequestContextHolder:在RequestContextHolder将允许您访问特定线程的请求,并请求属性以及在服务层.RequestContextHolder使用ThreadLocal变量来存储请求.您可以通过以下方式访问请求:
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
// Extract the request
HttpServletRequest request = attr.getRequest();
Run Code Online (Sandbox Code Playgroud)如果您使用log4j,则有一篇有趣的文章(2018替代),用于定制记录器的模式布局.但是,您只需创建日志系统接口的代理,并将id手动附加到每个记录的字符串.
您还可以在 Log4j 2 中使用“Fish Tagging”。它与https://logging.apache.org/log4j/2.x/manual/thread- 中描述的 MDC 和 NDC(线程基础)的想法相同-上下文.html
在这里您可以使用线程上下文堆栈或线程上下文映射。Map 的示例如下所示:
//put a unique id to the map
ThreadContext.put("id", UUID.randomUUID().toString()
//clear map
ThreadContext.clearMap();
Run Code Online (Sandbox Code Playgroud)
对于 log4j2.xml 中的模式,您还可以使用 %X{KEY} 标记。
要将新的 id 放入映射中(例如,对于每个传入的请求),您可以在 ServletRequestListener 实现中这样做,Sharadr 如何描述它。
| 归档时间: |
|
| 查看次数: |
31924 次 |
| 最近记录: |