代码之家  ›  专栏  ›  技术社区  ›  Shubham Pratap Singh

TraceId/SpanId未在带有Sleuth的webflux应用程序中的flux doOnNext lambda块内打印

  •  0
  • Shubham Pratap Singh  · 技术社区  · 1 年前

    当在通量的doOnNext块中遇到日志语句时,traceid和spanId不会被填充。但在块外,它会在webFilter中打印出来。下面是使用Sleuth的Reactive SpringBoot应用程序中的WebFlitter实现。

    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang.StringUtils;
    import org.reactivestreams.Publisher;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.buffer.DataBuffer;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
    import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebFilter;
    import org.springframework.web.server.WebFilterChain;
    import reactor.core.publisher.Flux;
    import reactor.core.publisher.Mono;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.nio.channels.Channels;
    
    @Slf4j
    @Configuration
    public class APILoggingFilter implements WebFilter {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            ServerHttpRequest httpRequest = exchange.getRequest();
            final String httpUrl = httpRequest.getURI().toString();
    
            ServerHttpRequestDecorator loggingServerHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
                String requestBody = "";
    
                @Override
                public Flux<DataBuffer> getBody() {
                    log.info("Service Request URL before {}", httpUrl);
                    Flux<DataBuffer> response =  super.getBody().doOnNext(dataBuffer -> {
                        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                            Channels.newChannel(byteArrayOutputStream).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
                            requestBody = IOUtils.toString(byteArrayOutputStream.toByteArray(), "UTF-8").replaceAll(System.lineSeparator(),StringUtils.EMPTY);
                            log.info(" Service Request json, {}", httpUrl, requestBody);
                        } catch (IOException e) {
                            log.info("Service Request, URL {}, {}, {}", httpUrl, requestBody, e);
                        }
                    });
                    log.info("Service Request URL after {}", httpUrl);
                    return response;
                }
            };
    
            ServerHttpResponseDecorator loggingServerHttpResponseDecorator = new ServerHttpResponseDecorator(exchange.getResponse()) {
                String responseBody = "";
                @Override
                public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                    Mono<DataBuffer> buffer = Mono.from(body);
                    log.info("Service Response, URL {}", httpUrl);
                    return super.writeWith(buffer.doOnNext(dataBuffer -> {
                        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                            Channels.newChannel(byteArrayOutputStream).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
                            responseBody = IOUtils.toString(byteArrayOutputStream.toByteArray(), "UTF-8").replaceAll(System.lineSeparator(), StringUtils.EMPTY);
                            log.info("Service Response, URL {}, {}", httpUrl, responseBody);
                        } catch (Exception e) {
                            log.info("Service Response, URL {}, {}, {}", httpUrl, responseBody, e);
                        }
                    }));
                }
            };
            return chain.filter(exchange.mutate().request(loggingServerHttpRequestDecorator).response(loggingServerHttpResponseDecorator).build());
        }
    
    }
    

    打印日志:

    2023-06-22 22:43:40.859信息[emp mgmt,4edae7c9825b4698,4edae7c9825b4698,false]6596-[Cor-http-nio-3]c.a.e.p.config.APILoggingFilter:之前的服务请求URLhttp://localhost:8083/api/v1/addEmp 2023-06-22 22:43:40.867信息[emp mgmt,4edae7c9825b4698,4edae7c9825b4698,false]6596-[Cor-http-nio-3]c.a.e.p.config.APILoggingFilter:之后的服务请求URLhttp://localhost:8083/api/v1/addEmp 2023-06-22 22:43:40.935信息 [emp mgmt,,] 6596-[cor-http-nio-3]c.a.e.p.config.APILoggingFilter:Service Request json,http://localhost:8083/api/v1/getEmp{ “uId”:null, “empId”:“932046783773”, “empName”:“Adam”, “idNumber”:“860937” }

    2023-06-22 22:43:49.270信息[emp mgmt,4edae7c9825b4698,4edae7c9825b4678,false]6596-[并行-2]配置.APILoggingFilter:服务响应,URLhttp://localhost:8083/api/v1/addEmp 2023-06-22 22:43:49.283信息[emp mgmt,4edae7c9825b4698,4edae7c9825b4698,false]6596-[并行-2]配置.APILoggingFilter:服务响应,URLhttp://localhost:8083/api/v1/addEmp{ “uId”:76543467, “empId”:“932046783773”, “empName”:“Adam”, “idNumber”:“860937” }

    带有“Service Request json”的日志语句没有traceId和SpanId。

    使用弹簧webFlux:5.1.5.RELEASE和Sleuth 2.1.0.RELEASE。 请帮忙。

    0 回复  |  直到 1 年前