diff --git a/src/main/java/cn/iocoder/dashboard/framework/tracer/core/ITrace.java b/src/main/java/cn/iocoder/dashboard/framework/tracer/core/ITrace.java new file mode 100644 index 000000000..483b408db --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/tracer/core/ITrace.java @@ -0,0 +1,16 @@ +package cn.iocoder.dashboard.framework.tracer.core; + +/** + * 用于扩展获取traceId的场景,需要装载到Spring bean容器中. + * + * @author 麻薯 + */ +public interface ITrace { + + /** + * 用于接入三方traceId + * + * @return traceId + */ + String getTraceId(); +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java b/src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java index 777c273cb..a9f85be41 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java +++ b/src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java @@ -1,6 +1,8 @@ package cn.iocoder.dashboard.framework.tracer.core.util; import cn.hutool.core.util.StrUtil; +import cn.iocoder.dashboard.framework.tracer.core.ITrace; +import cn.iocoder.dashboard.util.bean.SpringUtil; import org.apache.skywalking.apm.toolkit.trace.TraceContext; import java.util.UUID; @@ -12,26 +14,62 @@ import java.util.UUID; */ public class TracerUtils { + /** + * 私有化构造方法 + */ + private TracerUtils() { + } + /** * 获得链路追踪编号 - * + *
* 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 - * + *
* 默认情况下,我们使用 Apache SkyWalking 的 traceId 作为链路追踪编号。当然,可能会存在并未引入 Skywalking 的情况,此时使用 UUID 。
*
* @return 链路追踪编号
*/
public static String getTraceId() {
+ // 通过自定义扩展的tracer产生traceId, 在Spring容器加载完成前会获取不到对应的Bean
+ ITrace tracer = null;
+ try {
+ tracer = getTracer();
+ } catch (Throwable ignore) {
+ }
+ if (null != tracer) {
+ try {
+ return tracer.getTraceId();
+ } catch (Throwable ignored) {
+ }
+ }
// 通过 SkyWalking 获取链路编号
try {
String traceId = TraceContext.traceId();
if (StrUtil.isNotBlank(traceId)) {
return traceId;
}
- } catch (Throwable ignore) {}
+ } catch (Throwable ignore) {
+ }
// TODO 芋艿 多次调用会问题
- // TODO 麻薯 定义一个给外部扩展的接口,默认在未接入Skywalking时,输出UUID
+ return defaultTraceId();
+ }
+
+ /**
+ * 从Spring 容器中获取 ITrace 类,返回可以为null
+ *
+ * @return ITrace
+ */
+ private static ITrace getTracer() {
+ return SpringUtil.getBean(ITrace.class);
+ }
+
+ /**
+ * 默认生成TraceId规则为UUID
+ *
+ * @return UUID
+ */
+ private static String defaultTraceId() {
return "UUID:" + UUID.randomUUID().toString();
}
diff --git a/src/main/java/cn/iocoder/dashboard/util/bean/SpringUtil.java b/src/main/java/cn/iocoder/dashboard/util/bean/SpringUtil.java
new file mode 100644
index 000000000..4cbfb4e36
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/util/bean/SpringUtil.java
@@ -0,0 +1,83 @@
+package cn.iocoder.dashboard.util.bean;
+
+import org.springframework.beans.BeansException;
+
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+
+import org.springframework.context.ApplicationContext;
+
+import org.springframework.context.ApplicationContextAware;
+
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class SpringUtil implements ApplicationContextAware {
+
+ /**
+ * Spring context
+ */
+ private static ApplicationContext applicationContext = null;
+
+ public void setApplicationContext(ApplicationContext context) throws BeansException {
+ if (applicationContext == null) {
+ applicationContext = context;
+ }
+ }
+
+ public static ApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
+
+ public static void setAppCtx(ApplicationContext webAppCtx) {
+ if (webAppCtx != null) {
+ applicationContext = webAppCtx;
+ }
+ }
+
+
+ /**
+ * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
+ */
+ public static