Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding TraceId to Response - Improvements? #633

Closed
sm-azure opened this issue Jul 10, 2017 · 14 comments
Closed

Adding TraceId to Response - Improvements? #633

sm-azure opened this issue Jul 10, 2017 · 14 comments

Comments

@sm-azure
Copy link

Is this (https://stackoverflow.com/questions/41222405/adding-the-traceid-from-spring-cloud-sleuth-to-response) still the best way to do it in > 1.2.0?

Thanks.

@marcingrzejszczak
Copy link
Contributor

You can extend the TraceFilter and register your own version that will override this method https://github.com/spring-cloud/spring-cloud-sleuth/blob/1.2.x/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java#L403-L416 . In that method you have access to the Response and you can inject the Tracer to get the current span. That way you have both the trace id and you can modify the response headers. Does it make sense?

@marcingrzejszczak
Copy link
Contributor

Note to myself: Add a test and embed that test in the docs

@sm-azure
Copy link
Author

sm-azure commented Jul 11, 2017

👍 Thanks and yes, it does.

Wish :):) spring.sleuth.responseheader = true

@marcingrzejszczak
Copy link
Contributor

Heh - I'll close this issue for now but if anyone is interested in reopening it please upvote. If there are quite a few people interested in it we'll come back to the discussion.

@junneyang
Copy link

is there any example for this, thanks

@marcingrzejszczak
Copy link
Contributor

BTW there is a discussion about this going on here - openzipkin/openzipkin.github.io#48 . So in case of questions "why" we don't allow this by default please let's go to that issue.

I'll prepare sample code of how you can achieve this and update the documentation too.

@marcingrzejszczak
Copy link
Contributor

One note... If you want to do this with versions prior to 1.2.5 you have to create a bean like this, with a @Primary annotation:

@Bean
@Primary
		TraceFilter myTraceFilter(BeanFactory beanFactory, final Tracer tracer) {
			return new TraceFilter(beanFactory) {
				@Override protected void addResponseTags(HttpServletResponse response,
						Throwable e) {
					// execute the default behaviour
					super.addResponseTags(response, e);
					// for readability we're returning trace id in a hex form
					response.addHeader("ZIPKIN-TRACE-ID",
							Span.idToHex(tracer.getCurrentSpan().getTraceId()));
					// we can also add some custom tags
					tracer.addTag("custom", "tag");
				}
			};
		}

@ezraroi
Copy link

ezraroi commented Oct 4, 2017

@marcingrzejszczak We used HandlerInterceptorAdapter to implement this with the following code:

@Slf4j
@RequiredArgsConstructor
public class TraceHeaderInterceptor extends HandlerInterceptorAdapter {

    private static final String TRACE_ID = "TraceId";
    private final BeanFactory beanFactory;
    private Tracer tracer;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
        Object handler) throws Exception {
        if (getTracer().isTracing() && StringUtils.isEmpty(response.getHeader(TRACE_ID))) {
            response
                .setHeader(TRACE_ID, Span.idToHex(getTracer().getCurrentSpan().getTraceId()));
        }
        return true;
    }

    private Tracer getTracer() {
        if (tracer == null) {
            tracer = beanFactory.getBean(Tracer.class);
        }
        return tracer;
    }

}

@fcappi
Copy link

fcappi commented Jun 22, 2018

Seems like TraceFilter was removed on 2.0.0. Is there an alternative to have the trace ID on response headers?

@marcingrzejszczak
Copy link
Contributor

marcingrzejszczak commented Jun 22, 2018

We're doing the following bean registration

@Bean
	public FilterRegistrationBean traceWebFilter(
			TracingFilter tracingFilter) {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(tracingFilter);
		filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST);
		filterRegistrationBean.setOrder(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER);
		return filterRegistrationBean;
	}

@Bean
	public FilterRegistrationBean exceptionThrowingFilter() {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new ExceptionLoggingFilter());
		filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST);
		filterRegistrationBean.setOrder(TraceWebServletAutoConfiguration.TRACING_FILTER_ORDER + 1);
		return filterRegistrationBean;
	}

	@Bean
	@ConditionalOnMissingBean
	public TracingFilter tracingFilter(HttpTracing tracing) {
		return (TracingFilter) TracingFilter.create(tracing);
	}

You can create your own filter that starts after the TracingFilter one and set the trace id in the response.

@vikrantk365
Copy link

Can this be as simple as an annotation @EnableTraceIdsInResponse?

@marcingrzejszczak
Copy link
Contributor

If you create such an annotation then for sure it can :)

@chalme
Copy link

chalme commented Jan 17, 2019

One note... If you want to do this with versions prior to 1.2.5 you have to create a bean like this, with a @Primary annotation:

@Bean
@Primary
		TraceFilter myTraceFilter(BeanFactory beanFactory, final Tracer tracer) {
			return new TraceFilter(beanFactory) {
				@Override protected void addResponseTags(HttpServletResponse response,
						Throwable e) {
					// execute the default behaviour
					super.addResponseTags(response, e);
					// for readability we're returning trace id in a hex form
					response.addHeader("ZIPKIN-TRACE-ID",
							Span.idToHex(tracer.getCurrentSpan().getTraceId()));
					// we can also add some custom tags
					tracer.addTag("custom", "tag");
				}
			};
		}

response.isCommitted() and response can't Modify

@dhruv-bansal
Copy link

dhruv-bansal commented Jun 3, 2020

with spring-cloud Hoxton.RELEASE, I have done following implementation

public class ResponseTrackingFilter extends OncePerRequestFilter {

    private static final String TRACKING_HEADER = "X-TRACKING-ID";
    private Tracer tracer;

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
                                    final FilterChain filterChain) throws ServletException, IOException {

        final Span currentSpan = tracer.currentSpan();
        if (null != currentSpan && StringUtils.isEmpty(response.getHeader(TRACKING_HEADER))) {

            final String traceId = currentSpan.context().traceIdString();
            log.debug("Added tracking id in response - {}", traceId);
            response.setHeader(TRACKING_HEADER, traceId);
        }
        filterChain.doFilter(request, response);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants