Переглянути джерело

完善 skywalking 组件的集成

YunaiV 3 роки тому
батько
коміт
e351cdf785

+ 5 - 0
pom.xml

@@ -196,6 +196,11 @@
             <artifactId>apm-toolkit-logback-1.x</artifactId>
             <version>${skywalking.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-toolkit-opentracing</artifactId>
+            <version>${skywalking.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>de.codecentric</groupId>

+ 29 - 7
src/main/java/cn/iocoder/dashboard/framework/tracer/config/TracerAutoConfiguration.java

@@ -1,10 +1,15 @@
 package cn.iocoder.dashboard.framework.tracer.config;
 
-import cn.iocoder.dashboard.framework.tracer.core.annotation.BizTracingAop;
+import cn.iocoder.dashboard.framework.tracer.core.aop.BizTraceAspect;
+import cn.iocoder.dashboard.framework.tracer.core.filter.TraceFilter;
+import cn.iocoder.dashboard.framework.web.core.enums.FilterOrderEnum;
+import io.opentracing.Tracer;
+import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -14,21 +19,38 @@ import org.springframework.context.annotation.Configuration;
  * @author mashu
  */
 @Configuration
-@ConditionalOnClass({BizTracingAop.class})
-@EnableConfigurationProperties(BizTracerProperties.class)
+@ConditionalOnClass({BizTraceAspect.class})
+@EnableConfigurationProperties(TracerProperties.class)
 @ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true)
 public class TracerAutoConfiguration {
 
     @Bean
     @ConditionalOnMissingBean
-    public BizTracerProperties bizTracerProperties() {
-        return new BizTracerProperties();
+    public TracerProperties bizTracerProperties() {
+        return new TracerProperties();
     }
 
     @Bean
     @ConditionalOnMissingBean
-    public BizTracingAop bizTracingAop() {
-        return new BizTracingAop();
+    public BizTraceAspect bizTracingAop() {
+        return new BizTraceAspect();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public Tracer tracer() {
+        return new SkywalkingTracer();
+    }
+
+    /**
+     * 创建 TraceFilter 过滤器,响应 header 设置 traceId
+     */
+    @Bean
+    public FilterRegistrationBean<TraceFilter> traceFilter() {
+        FilterRegistrationBean<TraceFilter> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(new TraceFilter());
+        registrationBean.setOrder(FilterOrderEnum.TRACE_FILTER);
+        return registrationBean;
     }
 
 }

+ 1 - 1
src/main/java/cn/iocoder/dashboard/framework/tracer/config/BizTracerProperties.java → src/main/java/cn/iocoder/dashboard/framework/tracer/config/TracerProperties.java

@@ -10,5 +10,5 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
  */
 @ConfigurationProperties("yudao.tracer")
 @Data
-public class BizTracerProperties {
+public class TracerProperties {
 }

+ 6 - 1
src/main/java/cn/iocoder/dashboard/framework/tracer/core/annotation/BizTracing.java → src/main/java/cn/iocoder/dashboard/framework/tracer/core/annotation/BizTrace.java

@@ -10,7 +10,7 @@ import java.lang.annotation.*;
 @Target({ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 @Inherited
-public @interface BizTracing {
+public @interface BizTrace {
 
     /**
      * 业务编号 tag 名
@@ -21,6 +21,11 @@ public @interface BizTracing {
      */
     String TYPE_TAG = "biz.type";
 
+    /**
+     * @return 操作名
+     */
+    String operationName() default "";
+
     /**
      * @return 业务编号
      */

+ 0 - 32
src/main/java/cn/iocoder/dashboard/framework/tracer/core/annotation/BizTracingAop.java

@@ -1,32 +0,0 @@
-package cn.iocoder.dashboard.framework.tracer.core.annotation;
-
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.dashboard.util.sping.SpElUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-
-/**
- * 业务链路AOP切面
- *
- * @author mashu
- */
-@Aspect
-@Slf4j
-public class BizTracingAop {
-
-    @Around(value = "@annotation(bizTracing)")
-    public void tagBizInfo(ProceedingJoinPoint joinPoint, BizTracing bizTracing) {
-        String bizId = (String) SpElUtil.analysisSpEl(bizTracing.id(), joinPoint);
-        String bizType = (String) SpElUtil.analysisSpEl(bizTracing.type(), joinPoint);
-        if (StrUtil.isBlankIfStr(bizId)) {
-            log.error("empty biz: bizId[{}], bizType[{}].", bizId, bizType);
-            return;
-        }
-        log.info("accept biz: bizId[{}], bizType[{}].", bizId, bizType);
-        ActiveSpan.tag(BizTracing.ID_TAG, bizId);
-        ActiveSpan.tag(BizTracing.TYPE_TAG, bizType);
-    }
-}

+ 65 - 0
src/main/java/cn/iocoder/dashboard/framework/tracer/core/aop/BizTraceAspect.java

@@ -0,0 +1,65 @@
+package cn.iocoder.dashboard.framework.tracer.core.aop;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.dashboard.framework.tracer.core.annotation.BizTrace;
+import cn.iocoder.dashboard.util.sping.SpElUtil;
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+import javax.annotation.Resource;
+
+/**
+ * {@link BizTrace} 切面,记录业务链路
+ *
+ * @author mashu
+ */
+@Aspect
+@Slf4j
+public class BizTraceAspect {
+
+    private static final String BIZ_OPERATION_NAME_PREFIX = "Biz/";
+
+    @Resource
+    private Tracer tracer;
+
+    @Around(value = "@annotation(trace)")
+    public Object around(ProceedingJoinPoint joinPoint, BizTrace trace) throws Throwable {
+        // 创建 span
+        String operationName = getOperationName(joinPoint, trace);
+        Span span = tracer.buildSpan(operationName).startManual();
+        try {
+            // 执行原有方法
+            return joinPoint.proceed();
+        } finally {
+            // 设置 Span 的 biz 属性
+            setBizTag(span, joinPoint, trace);
+            // 完成 Span
+            span.finish();
+        }
+    }
+
+    private String getOperationName(ProceedingJoinPoint joinPoint, BizTrace trace) {
+        // 自定义操作名
+        if (StrUtil.isNotEmpty(trace.operationName())) {
+            return BIZ_OPERATION_NAME_PREFIX + trace.operationName();
+        }
+        // 默认操作名,使用方法名
+        return BIZ_OPERATION_NAME_PREFIX
+                + joinPoint.getSignature().getDeclaringType().getSimpleName()
+                + "/" + joinPoint.getSignature().getName();
+    }
+
+    private void setBizTag(Span span, ProceedingJoinPoint joinPoint, BizTrace trace) {
+        try {
+            span.setTag(BizTrace.TYPE_TAG, StrUtil.toString(SpElUtil.analysisSpEl(trace.type(), joinPoint)));
+            span.setTag(BizTrace.ID_TAG, StrUtil.toString(SpElUtil.analysisSpEl(trace.id(), joinPoint)));
+        } catch (Exception ex) {
+            log.error("[around][解析 bizType 与 bizId 发生异常]", ex);
+        }
+    }
+
+}

+ 33 - 0
src/main/java/cn/iocoder/dashboard/framework/tracer/core/filter/TraceFilter.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.framework.tracer.core.filter;
+
+import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Trace 过滤器,打印 traceId 到 header 中返回
+ *
+ * @author 芋道源码
+ */
+public class TraceFilter extends OncePerRequestFilter {
+
+    /**
+     * Header 名 - 链路追踪编号
+     */
+    private static final String HEADER_NAME_TRACE_ID = "trace-id";
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+        // 设置响应 traceId
+        response.addHeader(HEADER_NAME_TRACE_ID, TracerUtils.getTraceId());
+        // 继续过滤
+        chain.doFilter(request, response);
+    }
+
+}

+ 2 - 6
src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java

@@ -2,8 +2,6 @@ package cn.iocoder.dashboard.framework.tracer.core.util;
 
 import org.apache.skywalking.apm.toolkit.trace.TraceContext;
 
-import java.util.UUID;
-
 /**
  * 链路追踪工具类
  *
@@ -18,10 +16,8 @@ public class TracerUtils {
     }
 
     /**
-     * 获得链路追踪编号
-     * <p>
-     * 直接返回skywalking 的TraceId 如果不存在的话为空字符串""
-     * <p>
+     * 获得链路追踪编号,直接返回 SkyWalking 的 TraceId。
+     * 如果不存在的话为空字符串!!!
      *
      * @return 链路追踪编号
      */

+ 0 - 42
src/main/java/cn/iocoder/dashboard/framework/tracer/skywalking/LocalLogbackPatternConverter.java

@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-package cn.iocoder.dashboard.framework.tracer.skywalking;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
-
-/**
- * Created by mashu on 2021/3/6.
- */
-public class LocalLogbackPatternConverter extends ClassicConverter {
-    /**
-     * 作为默认的方式, 从{@link TracerUtils}中获取traceId,
-     * 需要用这个去替代logback的Layout,
-     * 同时避免了sky-walking agent生效的情况下仍然输出定值的问题.
-     *
-     * @param iLoggingEvent the event
-     * @return the traceId: UUID, or the real traceId.
-     */
-    @Override
-    public String convert(ILoggingEvent iLoggingEvent) {
-        return TracerUtils.getTraceId();
-    }
-}

+ 0 - 37
src/main/java/cn/iocoder/dashboard/framework/tracer/skywalking/TraceIdPatternLogbackLayout.java

@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-package cn.iocoder.dashboard.framework.tracer.skywalking;
-
-import ch.qos.logback.classic.PatternLayout;
-
-/**
- * Based on the logback-component convert register mechanism,
- * register {@link LocalLogbackPatternConverter} as a new convert, match to "tid".
- * You can use "%tid" in logback config file, "Pattern" section.
- * If sky-walking agent is not active mode, it will use UUID as tid.
- * <p>
- * logback 的转换组件,为tid 添加占位符的转换器
- * Created by mashu on 2021/3/6.
- */
-public class TraceIdPatternLogbackLayout extends PatternLayout {
-    static {
-        defaultConverterMap.put("tid", LocalLogbackPatternConverter.class.getName());
-    }
-}

+ 1 - 0
src/main/java/cn/iocoder/dashboard/framework/web/core/enums/FilterOrderEnum.java

@@ -9,6 +9,7 @@ public interface FilterOrderEnum {
 
     int CORS_FILTER = Integer.MIN_VALUE;
 
+    int TRACE_FILTER = CORS_FILTER + 1;
 
     int REQUEST_BODY_CACHE_FILTER = Integer.MIN_VALUE + 500;
 

+ 2 - 0
src/main/java/cn/iocoder/dashboard/modules/system/controller/auth/SysAuthController.java

@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.controller.auth;
 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
 import cn.iocoder.dashboard.common.pojo.CommonResult;
 import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
+import cn.iocoder.dashboard.framework.tracer.core.annotation.BizTrace;
 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO;
 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthLoginRespVO;
 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
@@ -58,6 +59,7 @@ public class SysAuthController {
 
     @GetMapping("/get-permission-info")
     @ApiOperation("获取登陆用户的权限信息")
+    @BizTrace(id = "1", type = "'user'")
     public CommonResult<SysAuthPermissionInfoRespVO> getPermissionInfo() {
         // 获得用户信息
         SysUserDO user = userService.getUser(getLoginUserId());

+ 15 - 4
src/main/resources/logback-spring.xml

@@ -1,11 +1,13 @@
-<configuration>   
+<configuration>  
+     
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
         <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
-            <layout class="cn.iocoder.dashboard.framework.tracer.skywalking.TraceIdPatternLogbackLayout">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                 <pattern>%d{ISO8601} | %tid | %thread | %-5level | %msg%n</pattern>
             </layout>
         </encoder>
     </appender>
+
     <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <FileNamePattern>./logs/ruoyi-vue-pro-%d{yyyy-MM-dd_HH}.log</FileNamePattern>
@@ -20,13 +22,20 @@
             <MaxFileSize>10MB</MaxFileSize>
         </triggeringPolicy>
     </appender>
+
     <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
         <discardingThreshold>0</discardingThreshold>
         <queueSize>10</queueSize>
         <appender-ref ref="FILE"/>
     </appender>
+
     <!-- skywalking grpc 日志收集 8.4.0版本开始支持 -->
     <appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
+                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
+            </layout>
+        </encoder>s
     </appender>
 
     <springProfile name="dev">
@@ -35,12 +44,14 @@
             <appender-ref ref="ASYNC"/>
         </logger>
     </springProfile>
+
     <springProfile name="local">
         <logger name="cn.iocoder.dashboard" level="INFO" additivity="false">
             <appender-ref ref="STDOUT"/>
             <appender-ref ref="GRPC"/>
         </logger>
     </springProfile>
+
     <springProfile name="default">
         <logger name="cn.iocoder.dashboard" level="INFO" additivity="false">
             <appender-ref ref="STDOUT"/>
@@ -48,7 +59,7 @@
         </logger>
     </springProfile>
 
-    <root level="DEBUG">      
+    <root level="INFO">      
         <appender-ref ref="STDOUT"/>   
         <appender-ref ref="ASYNC"/> 
     </root>
@@ -56,4 +67,4 @@
     <logger name="cn.iocoder.dashboard" level="INFO">
         <appender-ref ref="STDOUT"/>
     </logger>
-</configuration>
+</configuration>