Добавление 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") вернет строку со значением и может делать с ней все, что вы хотите.

Что касается размещения этой информации в заголовке, приведенные выше ответы ясно показали, как это сделать.

Вы можете получить его, выполнив следующие действия.

  1. Autowire SpanAccessor.
 @Autowired
private SpanAccessor spanAccessor;
  1. И добавьте эту строку там, где это необходимо.
spanAccessor.getCurrentSpan().traceIdString() method to get the value.

Надеюсь, это поможет.

При использовании пружины 5 и датчика 2 используйте приведенный ниже образец.

https://github.com/robert07ravikumar/sleuth-sample

Шаги: -

  1. Создайте веб-фильтр с приведенным ниже кодом и добавьте идентификатор трассировщика из объекта трассировщика.

    @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);
        }
    
  2. Добавьте аннотацию @ServletComponentScan к основному классу весенней загрузки.

Другие вопросы по тегам