- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
我们在做java项目的时候通常需要通过请求日志来排查定位线上问题,在日志比较多而我们又需要查找整个请求的全部日志的时候会比较困难。所以,就需要在日志记录的时候讲同一个请求的关键日志用同一个唯一标识串联起来。这样查找的时候就会比较好查找。下面来用java aop实现请求id的日志记录。(该支持子线程继承主线程请求id) 。
一:首先我们需要一个日志请求链路id切面类 。
注意:如果不考虑多线程则(第二步和第三步可以不要) 。
package com.iMagine.iMagine_pro.aop;
import com.iMagine.iMagine_common.utils.UUIDUtil;
import com.iMagine.iMagine_pro.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
/**
* @author 名一
* @ClassName TraceIdAspect
* @description: 日志请求链路id切面处理
* @datetime 2024年 12月 16日 14:28
* @version: 1.0
*/
@Slf4j
@Aspect
@Component
public class TraceIdAspect {
/** 链路追踪id */
public final static String TRACE_ID = "TRACE_ID";
/** 用户 */
public final static String USER = "USER";
/**
* 链路id切点定义
*/
@Pointcut("execution(* com.iMagine.iMagine_pro.controller.*.*(..))")
public void TraceIdCut() {
}
/**
* 链路id添加
*/
@Before("TraceIdCut()")
public void cutProcessBefore() {
MDC.put(TRACE_ID, UUIDUtil.getUUID());
//以下代码为记录用户信息,方便更直观的识别日志操作人信息。若不需要可以将下面部分删除
String nickname = TokenUtil.getNicknameByToken();
if (null == nickname){
nickname = "游客访问";
}
MDC.put(USER, nickname);
}
/**
* 链路id清除
*/
@After("TraceIdCut()")
public void cutProcessAfter() {
MDC.clear();
}
}
package com.iMagine.iMagine_common.utils; import java.util.UUID; /** * @author 名一 * @ClassName UUIDUtil * @description: UUID工具类 * @datetime 2024年 04月 23日 11:49 * @version: 1.0 */ public class UUIDUtil { /** * 获取UUID * * @return */ public static String getUUID() { //生产uuid并去掉uuid的短横线 return UUID.randomUUID().toString().replace("-", ""); } }
。
二:创建一个处理多线程链路追踪的工具类 。
package com.iMagine.iMagine_common.utils;
import com.iMagine.iMagine_common.constant.SysConstant;
import org.slf4j.MDC;
import java.util.Map;
/**
* @author 名一
* @ClassName ThreadMdcUtil
* @description: 多线程链路追踪工具类
* @datetime 2024年 12月 16日 14:57
* @version: 1.0
*/
public class ThreadMdcUtil {
// 获取唯一性标识
public static String generateTraceId() {
return UUIDUtil.getUUID();
}
public static void setTraceIdIfAbsent() {
if (MDC.get(SysConstant.TRACE_ID) == null) {
MDC.put(SysConstant.TRACE_ID, generateTraceId());
}
}
/**
* 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程
*
* @param runnable 要执行的线程
* @param context 父线程的mdc
* @return 链路id传递后的任务
*/
public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
} else {
MDC.setContextMap(context);
}
setTraceIdIfAbsent();
try {
runnable.run();
} finally {
MDC.clear();
}
};
}
}
。
三:在往线程池放任务的时候做请求链路id传递 。
/**
* 线程池添加 [ai server 相关操作(psot)]任务
*
* @param task 添加的任务
*/
public static void addSendPostThreadToThreadPool(SendPostThread task) {
log.info("addSendPostThreadToThreadPool pool:{}, task:{}", pool, task);
try {
pool.execute(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap()));
} catch (Exception e) {
log.error("addSendPostThreadToThreadPool error pool:{}, task:{}, e:", pool, task, e);
}
}
。
四:在日志配置里将链路追踪id加入日志输出格式的配置里 。
<!-- 日志输出格式 (其中%X{TRACE_ID}是mdc里边链路请求id的key,user-%X{USER}是用户信息的key)-->
<property name="ENCODER_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} user-%X{USER} %-5level %logger{32}-[%line] - %msg%n"/>
。
到此spring 项目实现带请求链路id的日志记录就完成了 。
。
最后此篇关于spring项目实现带请求链路id的日志记录的文章就讲到这里了,如果你想了解更多关于spring项目实现带请求链路id的日志记录的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
出现在 python 2.7.8 中。 3.4.1 不会发生这种情况。 示例: >>> id(id) 140117478913736 >>> id(id) 140117478913736 >>> id
好吧,我对动态创建的控件的 ID 很困惑。 Public Class TestClass Inherits Panel Implements INamingContainer
我收到下面的错误,说有堆栈溢出。发生这种情况是因为带有 IN (id, id, id...id) 的 SQL 语句有大量参数。有没有什么办法解决这一问题?这是在我使用 Eclipse 的本地环境中发生
为什么 CPython(不知道其他 Python 实现)有以下行为? tuple1 = () tuple2 = ()
为什么 CPython(对其他 Python 实现一无所知)有以下行为? tuple1 = () tuple2 = ()
非常简单的问题:当我有一个持久对象时,它通常有一个名为 ID 的属性(对于抽象类)。 那么..命名约定是ID还是Id? 例如。 public int ID { get; set; } 或 public
知道为什么我会收到此错误,我已经尝试了所有命名约定(小写/大写) 我正在使用 Vaadin,这是我的代码片段: public class Usercontainer extends BeanI
为什么 CPython(不知道其他 Python 实现)有以下行为? tuple1 = () tuple2 = ()
我需要改变表的所有主键 UPDATE TODO SET id = id + 1 但我做不到(Demo 来自 Ahmad Al-Mutawa 的回答)描述了原因。主键不能这样改。 我也不能根据这是 sq
我正在尝试列出与用户相关的讨论列表。 想象一下,如果你愿意的话: posts -------------------------------------------------------------
我有一个表,其中包含一些具有自己的 ID 和共享 SKU key 的文章。我尝试使用左连接进行查询,并使用组结果获取从查询返回的所有 id。 我的数据结构是这样的: id - name -
在下表People中: id name 1 James 2 Yun 3 Ethan 如果我想找到最大 ID,我可以运行此查询 select max(id) id from People; 结果是
我正在产品页面上创建评论模块,其中显示垃圾评论选项,并显示 onclick 显示和隐藏弹出窗口。现在它在单个评论中工作正常但是当评论是两个时它同时打开两个因为类是相同的。现在这就是为什么我想要获取父
根据 REST 哲学,PUT操作应该(取自维基百科): PUT http://example.com/resources/142 Update the address member of the co
我想知道如何在使用 PHP 或 JavaScript 进行身份验证后从 Google Analytics 获取 Property Id、View Id 和 Account Id?因为我希望能够将它们存
我想使用所选按钮的 ID 进行删除。但我不知道如何从中获取/获取 id。我尝试了 this.id 但不起作用。 这是我创建按钮的地方: var deleteEmployer= document.cre
我有一个具有以下结构的表“表” ID LinkedWith 12 13 13 12 14 13 15 14 16
请不要在未阅读问题的情况下将问题标记为重复。我确实发布了一个类似的问题,但 STACKOVERFLOW 社区成员要求我单独重新发布修改后的问题,因为考虑到一个小而微妙的修改,解决方案要复杂得多。 假设
在 Android Studio 中,我创建了一个 Person.java 类。我使用Generate 创建了getter 和setter 以及构造函数。 这是我的 Person.java 类: pu
如何在 jQuery 中制作这样的东西: //这是显示的主体 ID //当我悬停 #hover-id 时,我希望 #principal-id 消失并更改 。但是当我将光标放在 #this-id 上时
我是一名优秀的程序员,十分优秀!