diff --git a/.workflow/branch-pipeline.yml b/.workflow/branch-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..9d2a2926f31b55f68083a3cb58c4cb6d6f43a07f --- /dev/null +++ b/.workflow/branch-pipeline.yml @@ -0,0 +1,53 @@ +version: '1.0' +name: branch-pipeline +displayName: BranchPipeline +stages: + - stage: + name: compile + displayName: 编译 + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + # 支持6、7、8、9、10、11六个版本 + jdkVersion: 8 + # 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本 + mavenVersion: 3.3.9 + # 构建命令 + commands: + - mvn -B clean package -Dmaven.test.skip=true + # 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除 + artifacts: + # 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址 + - name: BUILD_ARTIFACT + # 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录 + path: + - ./target + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + # 上游构建任务定义的产物名,默认BUILD_ARTIFACT + dependArtifact: BUILD_ARTIFACT + # 上传到制品库时的制品命名,默认output + artifactName: output + dependsOn: build_maven + - stage: + name: release + displayName: 发布 + steps: + - step: publish@release_artifacts + name: publish_release_artifacts + displayName: '发布' + # 上游上传制品任务的产出 + dependArtifact: output + # 发布制品版本号 + version: '1.0.0.0' + # 是否开启版本号自增,默认开启 + autoIncrement: true +triggers: + push: + branches: + exclude: + - master + include: + - .* diff --git a/.workflow/master-pipeline.yml b/.workflow/master-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..b9c01c6f7ea5d787ecfa99f6bbd85d87ea69bbb7 --- /dev/null +++ b/.workflow/master-pipeline.yml @@ -0,0 +1,51 @@ +version: '1.0' +name: master-pipeline +displayName: MasterPipeline +triggers: + trigger: auto + push: + branches: + include: + - master +stages: + - name: compile + displayName: 编译 + strategy: naturally + trigger: auto + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + jdkVersion: 8 + mavenVersion: 3.3.9 + commands: + - mvn -B clean package -Dmaven.test.skip=true + artifacts: + - name: BUILD_ARTIFACT + path: + - ./target + - step: sc@opensca + name: open_sca + displayName: OpenSCA 开源组件检测 + detectPath: ./ + notify: [] + strategy: + retry: '0' + dependsOn: build_maven + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + dependArtifact: BUILD_ARTIFACT + artifactName: output + dependsOn: open_sca + - name: release + displayName: 发布 + strategy: naturally + trigger: auto + steps: + - step: publish@release_artifacts + name: publish_release_artifacts + displayName: 发布 + dependArtifact: output + version: 1.0.0.0 + autoIncrement: true diff --git a/.workflow/pr-pipeline.yml b/.workflow/pr-pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f7579dd405c85f97f77df0357ec4893e616f85f --- /dev/null +++ b/.workflow/pr-pipeline.yml @@ -0,0 +1,40 @@ +version: '1.0' +name: pr-pipeline +displayName: PRPipeline +stages: + - stage: + name: compile + displayName: 编译 + steps: + - step: build@maven + name: build_maven + displayName: Maven 构建 + # 支持6、7、8、9、10、11六个版本 + jdkVersion: 8 + # 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本 + mavenVersion: 3.3.9 + # 构建命令 + commands: + - mvn -B clean package -Dmaven.test.skip=true + # 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除 + artifacts: + # 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址 + - name: BUILD_ARTIFACT + # 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录 + path: + - ./target + - step: publish@general_artifacts + name: publish_general_artifacts + displayName: 上传制品 + # 上游构建任务定义的产物名,默认BUILD_ARTIFACT + dependArtifact: BUILD_ARTIFACT + # 构建产物制品库,默认default,系统默认创建 + artifactRepository: default + # 上传到制品库时的制品命名,默认output + artifactName: output + dependsOn: build_maven +triggers: + pr: + branches: + include: + - master diff --git a/tlog-common/src/main/java/com/yomahub/tlog/constant/TLogConstants.java b/tlog-common/src/main/java/com/yomahub/tlog/constant/TLogConstants.java index a39164848c6be1ead578880051755d3b2bf431b9..2db5966856d2931cb4bc665b34e36d06cefbd92b 100644 --- a/tlog-common/src/main/java/com/yomahub/tlog/constant/TLogConstants.java +++ b/tlog-common/src/main/java/com/yomahub/tlog/constant/TLogConstants.java @@ -26,4 +26,6 @@ public class TLogConstants { public static final String WEBFLUX_EXCHANGE = "exchange"; + public static final String REQUEST_ATTRIBUTE_TLOG_FLAG = "REQUEST_ATTRIBUTE_TLOG_FLAG"; + } diff --git a/tlog-core/src/main/java/com/yomahub/tlog/core/aop/AspectLogAop.java b/tlog-core/src/main/java/com/yomahub/tlog/core/aop/AspectLogAop.java index 98d4942bcebd31b0a0a8352b9ed3375a013d06d3..bb95b419653646e5aafa1ceb22e9b03e05becd2c 100644 --- a/tlog-core/src/main/java/com/yomahub/tlog/core/aop/AspectLogAop.java +++ b/tlog-core/src/main/java/com/yomahub/tlog/core/aop/AspectLogAop.java @@ -11,6 +11,7 @@ import com.yomahub.tlog.constant.TLogConstants; import com.yomahub.tlog.core.annotation.TLogAspect; import com.yomahub.tlog.core.context.AspectLogContext; import com.yomahub.tlog.core.convert.AspectLogConvert; +import com.yomahub.tlog.core.utils.TLogAspectUtils; import com.yomahub.tlog.exception.TLogCustomLabelExpressionException; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; @@ -21,6 +22,7 @@ import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -45,93 +47,110 @@ public class AspectLogAop { @Around("cut()") public Object around(ProceedingJoinPoint jp) throws Throwable { - Object[] args = jp.getArgs(); - MethodSignature signature = (MethodSignature) jp.getSignature(); - Method method = signature.getMethod(); - String[] parameterNames = signature.getParameterNames(); - Map paramNameValueMap = MapUtil.newHashMap(); - for (int i = 0; i < parameterNames.length; i++) { - paramNameValueMap.put(parameterNames[i], args[i]); - } + //拿到之前的标签 + String oldLogValue = AspectLogContext.getLogValue(); + boolean fillSuccessful = false; + try { + Object[] args = jp.getArgs(); + MethodSignature signature = (MethodSignature) jp.getSignature(); + Method method = signature.getMethod(); + String[] parameterNames = signature.getParameterNames(); + Map paramNameValueMap = MapUtil.newHashMap(); + for (int i = 0; i < parameterNames.length; i++) { + paramNameValueMap.put(parameterNames[i], args[i]); + } - TLogAspect tlogAspect = method.getAnnotation(TLogAspect.class); - String[] aspectExpressions = tlogAspect.value(); - String str = tlogAspect.str(); - String pattern = tlogAspect.pattern(); - String joint = tlogAspect.joint(); - Class convertClazz = tlogAspect.convert(); + TLogAspect tlogAspect = method.getAnnotation(TLogAspect.class); + TLogAspectUtils.push(tlogAspect); - StringBuilder sb = new StringBuilder(); + String[] aspectExpressions = tlogAspect.value(); + String str = tlogAspect.str(); + String pattern = tlogAspect.pattern(); + String joint = tlogAspect.joint(); + Class convertClazz = tlogAspect.convert(); - //处理字符串类型标签 - if (StrUtil.isNotBlank(str)){ - sb.append(str); - sb.append(joint); - } + StringBuilder sb = new StringBuilder(); - //处理自定义converter - boolean isAspectLogConvert; - if (convertClazz.equals(AspectLogConvert.class)){ - isAspectLogConvert = false; - }else{ - isAspectLogConvert = AspectLogConvert.class.isAssignableFrom(convertClazz); - } - - if (isAspectLogConvert) { - AspectLogConvert convert = convertClazz.newInstance(); - try { - sb.append(convert.convert(args)); + //处理字符串类型标签 + if (StrUtil.isNotBlank(str)) { + sb.append(str); sb.append(joint); - } catch (Throwable t) { - log.error("[AspectLog]some errors happens in AspectLog's convert", t); } - } - //处理表达式 - for (String aspectExpression : aspectExpressions) { - String aspLogValueItem = getExpressionValue(aspectExpression, paramNameValueMap); - if (StringUtils.isNotBlank(aspLogValueItem)) { - sb.append(StrUtil.format("{}:{}", aspectExpression, aspLogValueItem)); - sb.append(joint); + //处理自定义converter + boolean isAspectLogConvert; + if (convertClazz.equals(AspectLogConvert.class)) { + isAspectLogConvert = false; + } else { + isAspectLogConvert = AspectLogConvert.class.isAssignableFrom(convertClazz); } - } - String aspLogValue = sb.toString(); - if (StringUtils.isNotBlank(aspLogValue)) { - aspLogValue = aspLogValue.substring(0, aspLogValue.length() - joint.length()); - aspLogValue = StrUtil.format(pattern, aspLogValue); + if (isAspectLogConvert) { + AspectLogConvert convert = convertClazz.newInstance(); + try { + sb.append(convert.convert(args)); + sb.append(joint); + } catch (Throwable t) { + log.error("[AspectLog]some errors happens in AspectLog's convert", t); + } + } + + //处理表达式 + for (String aspectExpression : aspectExpressions) { + String aspLogValueItem = getExpressionValue(aspectExpression, paramNameValueMap); + if (StringUtils.isNotBlank(aspLogValueItem)) { + sb.append(StrUtil.format("{}:{}", aspectExpression, aspLogValueItem)); + sb.append(joint); + } + } - //拿到之前的标签 - String currentLabel = AspectLogContext.getLogValue(); + String aspLogValue = sb.toString(); + if (StringUtils.isNotBlank(aspLogValue)) { + fillSuccessful = true; - MDC.put(TLogConstants.MDC_KEY, currentLabel + " " + aspLogValue); - AspectLogContext.putLogValue(currentLabel + " " + aspLogValue); - } + aspLogValue = aspLogValue.substring(0, aspLogValue.length() - joint.length()); + aspLogValue = StrUtil.format(pattern, aspLogValue); - return jp.proceed(); + MDC.put(TLogConstants.MDC_KEY, oldLogValue + " " + aspLogValue); + AspectLogContext.putLogValue(oldLogValue + " " + aspLogValue); + } + + return jp.proceed(); + } finally { + // 弹出当前的注解 + TLogAspectUtils.pop(); + // 如果填充成功 + if (fillSuccessful) { + // 将旧值设置回去,解决嵌套调用的问题 + if (StrUtil.isNotBlank(oldLogValue)) { + MDC.put(TLogConstants.MDC_KEY, oldLogValue); + AspectLogContext.putLogValue(oldLogValue); + } + } + } } - private String getExpressionValue(String expression, Map map){ + private String getExpressionValue(String expression, Map map) { List errorList = new ArrayList<>(); - try{ + try { InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache("map." + expression); DefaultContext context = new DefaultContext<>(); context.put("map", map); Object value = expressRunner.execute(instructionSet, context, errorList, false, false); - if (ObjectUtil.isNull(value)){ + if (ObjectUtil.isNull(value)) { return null; } - if (ObjectUtil.isBasicType(value)){ + if (ObjectUtil.isBasicType(value)) { return value.toString(); - }else{ + } else { return JSON.toJSONString(value); } - }catch (Throwable t){ - for (String scriptErrorMsg : errorList){ + } catch (Throwable t) { + for (String scriptErrorMsg : errorList) { log.error("\n{}", scriptErrorMsg); } - log.error(t.getMessage(),t); + log.error(t.getMessage(), t); throw new TLogCustomLabelExpressionException(t.getMessage()); } } diff --git a/tlog-core/src/main/java/com/yomahub/tlog/core/utils/TLogAspectUtils.java b/tlog-core/src/main/java/com/yomahub/tlog/core/utils/TLogAspectUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c412305d2e8f5f8187ac317cfe741d11207153b1 --- /dev/null +++ b/tlog-core/src/main/java/com/yomahub/tlog/core/utils/TLogAspectUtils.java @@ -0,0 +1,48 @@ +package com.yomahub.tlog.core.utils; + +import com.yomahub.tlog.core.annotation.TLogAspect; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * 注解切面工具类 + * + * @author pengchao + * @since 2024/9/5 + */ +public class TLogAspectUtils { + + private TLogAspectUtils() { + } + + private static final ThreadLocal> TLOG_ASPECT_THREAD_LOCAL = ThreadLocal.withInitial(LinkedList::new); + + /** + * 获取当前TLogAspect + * + * @return 当前TLogAspect + */ + public static TLogAspect peek() { + return TLOG_ASPECT_THREAD_LOCAL.get().peek(); + } + + /** + * 添加TLogAspect + * + * @param tLogAspect TLogAspect + */ + public static void push(TLogAspect tLogAspect) { + TLOG_ASPECT_THREAD_LOCAL.get().push(tLogAspect); + } + + /** + * 弹出TLogAspect + */ + public static void pop() { + TLOG_ASPECT_THREAD_LOCAL.get().pop(); + if (TLOG_ASPECT_THREAD_LOCAL.get().isEmpty()) { + TLOG_ASPECT_THREAD_LOCAL.remove(); + } + } +} diff --git a/tlog-webroot/src/main/java/com/yomahub/tlog/web/common/TLogWebCommon.java b/tlog-webroot/src/main/java/com/yomahub/tlog/web/common/TLogWebCommon.java index a2a57540a3b3e105d77acdd9a8d775c2a04fbae5..5be2a3fc4f3a376967b4f82be24b3206f9285ef2 100644 --- a/tlog-webroot/src/main/java/com/yomahub/tlog/web/common/TLogWebCommon.java +++ b/tlog-webroot/src/main/java/com/yomahub/tlog/web/common/TLogWebCommon.java @@ -43,6 +43,8 @@ public class TLogWebCommon extends TLogRPCHandler { TLogLabelBean labelBean = new TLogLabelBean(preIvkApp, preIvkHost, preIp, traceId, spanId); processProviderSide(labelBean); + + request.setAttribute(TLogConstants.REQUEST_ATTRIBUTE_TLOG_FLAG, true); } public void afterCompletion() { diff --git a/tlog-webroot/src/main/java/com/yomahub/tlog/web/filter/TLogServletFilter.java b/tlog-webroot/src/main/java/com/yomahub/tlog/web/filter/TLogServletFilter.java index 0a39d287dd1ebcbe00ad5d8d73165dc61e864980..2e277e961ee842bd309d653756f3f337b7fd0080 100644 --- a/tlog-webroot/src/main/java/com/yomahub/tlog/web/filter/TLogServletFilter.java +++ b/tlog-webroot/src/main/java/com/yomahub/tlog/web/filter/TLogServletFilter.java @@ -22,7 +22,7 @@ public class TLogServletFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - if (request instanceof HttpServletRequest && response instanceof HttpServletResponse){ + if (request instanceof HttpServletRequest && response instanceof HttpServletResponse && null == request.getAttribute(TLogConstants.REQUEST_ATTRIBUTE_TLOG_FLAG)){ try{ TLogWebCommon.loadInstance().preHandle((HttpServletRequest)request); //把traceId放入response的header,为了方便有些人有这样的需求,从前端拿整条链路的traceId diff --git a/tlog-webroot/src/main/java/com/yomahub/tlog/web/interceptor/TLogWebInterceptor.java b/tlog-webroot/src/main/java/com/yomahub/tlog/web/interceptor/TLogWebInterceptor.java index 47cf5a8b2c3652ab7002c751de088a174612afab..ead57da526b25f64da8b515f217b7c0aaf6915aa 100644 --- a/tlog-webroot/src/main/java/com/yomahub/tlog/web/interceptor/TLogWebInterceptor.java +++ b/tlog-webroot/src/main/java/com/yomahub/tlog/web/interceptor/TLogWebInterceptor.java @@ -18,12 +18,17 @@ import javax.servlet.http.HttpServletResponse; public class TLogWebInterceptor extends AbsTLogWebHandlerMethodInterceptor { private static final Logger log = LoggerFactory.getLogger(TLogWebInterceptor.class); + private static final ThreadLocal SET_FLAG = new ThreadLocal<>(); @Override public boolean preHandleByHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - TLogWebCommon.loadInstance().preHandle(request); - //把traceId放入response的header,为了方便有些人有这样的需求,从前端拿整条链路的traceId - response.addHeader(TLogConstants.TLOG_TRACE_KEY, TLogContext.getTraceId()); + if (null == request.getAttribute(TLogConstants.REQUEST_ATTRIBUTE_TLOG_FLAG)) { + SET_FLAG.set(true); + + TLogWebCommon.loadInstance().preHandle(request); + //把traceId放入response的header,为了方便有些人有这样的需求,从前端拿整条链路的traceId + response.addHeader(TLogConstants.TLOG_TRACE_KEY, TLogContext.getTraceId()); + } return true; } @@ -33,6 +38,9 @@ public class TLogWebInterceptor extends AbsTLogWebHandlerMethodInterceptor { @Override public void afterCompletionByHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - TLogWebCommon.loadInstance().afterCompletion(); + if (null != SET_FLAG.get()) { + TLogWebCommon.loadInstance().afterCompletion(); + } + SET_FLAG.remove(); } }