部署
docker run -d -p 9411:9411 openzipkin/zipkin
依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId><version>1.5.2</version></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId><version>1.5.2</version></dependency><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId><version>3.5.1</version></dependency><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-sender-urlconnection</artifactId><version>3.5.1</version></dependency>
</dependencies>
配置
spring:application:name: demo-servicemanagement:tracing:sampling:probability: 1.0zipkin:tracing:endpoint: http://localhost:9411/api/v2/spanslogging:pattern:correlation: "[${spring.application.name:},%X{traceId:-},%X{spanId:-}]"include-application-name: false
代码
@Configuration
public class SpanAspectConfiguration {@BeanNewSpanParser newSpanParser() {return new DefaultNewSpanParser();}@BeanValueResolver valueResolver() {return new NoOpValueResolver();}@BeanValueExpressionResolver valueExpressionResolver() {return new SpelTagValueExpressionResolver();}@BeanMethodInvocationProcessor methodInvocationProcessor(NewSpanParser newSpanParser, Tracer tracer, BeanFactory beanFactory) {return new ImperativeMethodInvocationProcessor(newSpanParser, tracer, beanFactory::getBean, beanFactory::getBean);}@BeanSpanAspect spanAspect(MethodInvocationProcessor methodInvocationProcessor) {return new SpanAspect(methodInvocationProcessor);}}class SpelTagValueExpressionResolver implements ValueExpressionResolver {private static final Log log = LogFactory.getLog(SpelTagValueExpressionResolver.class);@Overridepublic String resolve(String expression, Object parameter) {try {SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();ExpressionParser expressionParser = new SpelExpressionParser();Expression expressionToEvaluate = expressionParser.parseExpression(expression);return expressionToEvaluate.getValue(context, parameter, String.class);}catch (Exception ex) {log.error("Exception occurred while tying to evaluate the SpEL expression [" + expression + "]", ex);}return parameter.toString();}}
@RestController
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class Application {@NewSpan("add")@GetMapping("/add")public String add(@SpanTag("a") @RequestParam Double a, @SpanTag("b") @RequestParam Double b) {Application proxy = (Application) AopContext.currentProxy();Double result = proxy.add1(a + b);return proxy.str(result);}@ContinueSpan(log = "/add1")public Double add1(Double result) {return result + 1;}@ContinueSpan(log = "/str")public String str(Double result) {return String.valueOf(result);}public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
跟踪
