Добавление traceId из Spring Cloud Sleuth к ответу
В настоящее время я внедряю Spring Cloud Sleuth в наш проект. У меня есть требование добавить traceId в заголовки ответа. Есть ли способ, которым это может быть достигнуто?
Спасибо,
Anoop
7 ответов
Есть 2 варианта. Одним из них является предоставление ваших пользовательских экстракторов - http://cloud.spring.io/spring-cloud-sleuth/1.0.x/ (это будет НАМНОГО проще с версией 1.2.0). Другой вариант (намного быстрее) - создать свой собственный Фильтр, который будет зарегистрирован после выполнения TraceFilter и до его закрытия. Вы можете там бежать tracer.getCurrentSpan()
и добавьте любую необходимую информацию в ответ.
Используя пример user2028534, но используя springframework.cloud.sleuth версии 2.1.1, вы можете использовать следующие шаги:
1. Autowired brave.Tracer.
@Autowired
Tracer tracer
2. CurrentSpan возвращает TraceContext, получает traceIdString
tracer.currentSpan().context().traceIdString()
В Spring Sleuth 3.0.x вот пример из официального документа.
@Component
@Order(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1)
class MyFilter extends GenericFilterBean {
private final Tracer tracer;
MyFilter(Tracer tracer) {
this.tracer = tracer;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Span currentSpan = this.tracer.currentSpan();
if (currentSpan == null) {
chain.doFilter(request, response);
return;
}
// for readability we're returning trace id in a hex form
((HttpServletResponse) response).addHeader("ZIPKIN-TRACE-ID",
currentSpan.context().traceIdString());
// we can also add some custom tags
currentSpan.tag("custom", "tag");
chain.doFilter(request, response);
}
}
Если вы используете джерси Один из подходов - добавить фильтр отклика на джерси и использовать трассировку (с автоматическим подключением) из пружинного сыщикаorg.springframework.cloud.sleuth.Tracer
открытый класс TraceHeaderInterceptor реализует ContainerResponseFilter { @Override открытый фильтр void (ContainerRequestContext requestContext, ContainerResponseContext responseContext) выдает IOException { val responseHeaders = responseContext.getHeaders(); if (!responseHeaders.containsKey(TRACE_ID_HEADER_NAME)) { val traceId = tracer.getCurrentSpan().traceIdString(); responseHeaders.add(TRACE_ID_HEADER_NAME, traceId); } } приватная статическая конечная строка TRACE_ID_HEADER_NAME = "X-B3-Traceid"; закрытый финал Tracer tracer; public TraceHeaderInterceptor(Tracer tracer) { this.tracer = tracer; } }
Мы добавили это в наш API-шлюз, чтобы избежать необходимости менять каждый микросервис
Самый простой способ получить traceId от сыщика - использовать MDC. Используя этот метод: MDC.get("traceId") вернет строку со значением и может делать с ней все, что вы хотите.
Что касается размещения этой информации в заголовке, приведенные выше ответы ясно показали, как это сделать.
Вы можете получить его, выполнив следующие действия.
- Autowire SpanAccessor.
@Autowired
private SpanAccessor spanAccessor;
- И добавьте эту строку там, где это необходимо.
spanAccessor.getCurrentSpan().traceIdString() method to get the value.
Надеюсь, это поможет.
При использовании пружины 5 и датчика 2 используйте приведенный ниже образец.
https://github.com/robert07ravikumar/sleuth-sample
Шаги: -
Создайте веб-фильтр с приведенным ниже кодом и добавьте идентификатор трассировщика из объекта трассировщика.
@Autowired Tracer tracer;
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setHeader("tracer-id", tracer.currentSpan().context().traceIdString()); chain.doFilter(request, response); }
Добавьте аннотацию @ServletComponentScan к основному классу весенней загрузки.