简介
本文介绍Java项目如何用代码手动获取SkyWalking的traceId。
引入依赖
<dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <!-- 当前的最新版本,请与安装的服务器版本对应 --> <version>8.7.0</version> </dependency>
代码获取traceId
在想获取traceId的地方加@Trace注解,然后调用TraceContext.traceId。
例:
@PostMapping("create") @Trace public Result create(Order order) { orderService.create(order); String traceId = TraceContext.traceId(); return new Result().message("创建订单成功"); }
Trace所在包:import org.apache.skywalking.apm.toolkit.trace.Trace;
TraceContext所在包:import org.apache.skywalking.apm.toolkit.trace.TraceContext;
TraceContext可以获得spanId等其他信息:
项目应用
实际上,项目中不需要每个方法都加@Trace这个注解来获得traceId,只需要在全局响应的地方来获取即可。
下边展示项目中的实际用法(我是实测过的,可以获取到traceId)。
package com.example.common.advice; import com.example.common.entity.Result; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.apm.toolkit.trace.Trace; import org.apache.skywalking.apm.toolkit.trace.TraceContext; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @Slf4j @ControllerAdvice public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 若接口返回的类型本身就是ResultWrapper,则无需操作,返回false // return !returnType.getParameterType().equals(ResultWrapper.class); return true; } @Override @ResponseBody @Trace public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { String traceId = TraceContext.traceId(); if (body instanceof String) { // 若返回值为String类型,需要包装为String类型返回。否则会报错 try { ObjectMapper objectMapper = new ObjectMapper(); Result<Object> result = new Result<>().data(body).traceId(traceId); return objectMapper.writeValueAsString(result); } catch (JsonProcessingException e) { throw new RuntimeException("序列化String错误"); } } else if (body instanceof Result) { return ((Result)body).traceId(traceId); } return new Result<>().traceId(traceId).data(body); } }
请先
!