Reputation: 1981
I am using Zipkin with Spring Sleuth to display traces. When I use it locally, http://localhost:9411/zipkin/dependency/ displays a nicely created graph of dependencies within the eco-system. Sometimes, backends from outside that eco-system get called and those are not displayed in that graph. Is it possible to annotate a call (let's assume RestTemplate and Feign clients) to such an external system so Zipkin would actually draw that dependency? If it's possible, what do I have to do?
This would be my baseline of code:
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping("/")
public String callExternalBackend() {
return restTemplate.getForObject("https://httpbin.org/get", String.class);
}
Somewhere I would like to type httpbin
so this call gets drawn in the dependency-graph of Zipkin.
Thank you!
// Edit based on current solution I'm using Spring Cloud Finchley and added the following line before restTemplate's call:
@RequestMapping("/")
public String callBackend() {
spanCustomizer.tag("peer.service", "httpbin");
return restTemplate.getForObject("https://httpbin.org/get", String.class);
}
I simply inject SpanCustomizer
in this class. The Span is sent to Zipkin and I see the tag is set:
Unfortunately, it is not drawn in the dependencies-view. Is there anything else I need to configure, maybe in Zipkin rather than in Sleuth?
Upvotes: 0
Views: 557
Reputation: 11179
EDGWARE
Have you read the documentation? If you use Spring Cloud Sleuth in Edgware version if you read the Sleuth section you would find this piece of the documentation https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#_custom_sa_tag_in_zipkin
Let me copy that for you
54.5 Custom SA tag in Zipkin Sometimes you want to create a manual Span that will wrap a call to an external service which is not instrumented. What you can do is to create a span with the peer.service tag that will contain a value of the service that you want to call. Below you can see an example of a call to Redis that is wrapped in such a span.
org.springframework.cloud.sleuth.Span newSpan = tracer.createSpan("redis");
try {
newSpan.tag("redis.op", "get");
newSpan.tag("lc", "redis");
newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_SEND);
// call redis service e.g
// return (SomeObj) redisTemplate.opsForHash().get("MYHASH", someObjKey);
} finally {
newSpan.tag("peer.service", "redisService");
newSpan.tag("peer.ipv4", "1.2.3.4");
newSpan.tag("peer.port", "1234");
newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_RECV);
tracer.close(newSpan);
}
[Important] Important Remember not to add both peer.service tag and the SA tag! You have to add only peer.service.
FINCHLEY
The SA
tag will not work for Finchley. You have to do it in the following manner using the remoteEndpoint
on the span.
Span span = tracer.newTrace().name("redis");
span.remoteEndpoint(Endpoint.newBuilder().serviceName("redis").build());
span.kind(CLIENT);
try(SpanInScope ws = tracer.withSpanInScope(span.start())) {
// add any tags / annotations on the span
// return (SomeObj) redisTemplate.opsForHash().get("MYHASH", someObjKey);
} finally {
span.finish();
}
Upvotes: 1