gateway打印拦截日志

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Component
@Slf4j
@AllArgsConstructor
public class HttpRequestFilter implements GlobalFilter, Ordered {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    String method = request.getMethodValue();
    String uuid = UUID.randomUUID().toString();
    String url = request.getURI().toString();
    log.info("gateway url is:【{}】, uuid is:【{}】", url, uuid);
    //打印请求头
    printHeaders(uuid, request);
    //response
    ServerHttpResponse originalResponse = exchange.getResponse();
    DataBufferFactory bufferFactory = originalResponse.bufferFactory();
    ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(
        originalResponse) {
      @Override
      public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
        if (body instanceof Flux) {
          Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
          return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
            StringBuffer stringBuffer = new StringBuffer();
            dataBuffers.forEach(dataBuffer -> {
              byte[] content = new byte[dataBuffer.readableByteCount()];
              dataBuffer.read(content);
              DataBufferUtils.release(dataBuffer);
              try {
                stringBuffer.append(new String(content, "utf-8"));
              } catch (Exception e) {
                log.error("--list.add--error", e);
              }
            });
            String result = stringBuffer.toString();
            if (StringUtils.isNotBlank(result)) {
              String[] resultArr = StrUtil.cut(result, 10 * 1024 * 1024);
              for (String str : resultArr) {
                log.info("result is :【{}】, uuid is:【{}】", str, uuid);
              }
            }
            byte[] uppedContent = new String(result.getBytes(),
                Charset.forName("UTF-8")).getBytes();
            originalResponse.getHeaders().setContentLength(uppedContent.length);
            return bufferFactory.wrap(uppedContent);
          }));
        }
        // if body is not a flux. never got there.
        return super.writeWith(body);
      }
    };

    //param
    if ("POST".equals(method)) {
      return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> {
        byte[] bytes = new byte[dataBuffer.readableByteCount()];
        dataBuffer.read(bytes);
        try {
          String bodyString = new String(bytes, Charset.forName("UTF-8"));
          if (StringUtils.isNotBlank(bodyString)) {
            bodyString = bodyString.replaceAll("\n", "");
            bodyString = bodyString.replaceAll("\r", "");
          }
          log.info("request method: 【{}】, request param:【{}】, uuid is: 【{}】", method,
              bodyString, uuid);
          exchange.getAttributes().put("POST_BODY", bodyString);
        } catch (Exception e) {
          e.printStackTrace();
        }
        DataBufferUtils.release(dataBuffer);
        Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
          DataBuffer buffer = exchange.getResponse().bufferFactory()
              .wrap(bytes);
          return Mono.just(buffer);
        });
        ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
            exchange.getRequest()) {
          @Override
          public Flux<DataBuffer> getBody() {
            return cachedFlux;
          }
        };
        return chain.filter(exchange.mutate().request(mutatedRequest).response(decoratedResponse)
            .build());
      });
    } else if ("GET".equals(method)) {
      MultiValueMap<String, String> queryParams = request.getQueryParams();
      log.info("request method: 【{}】, request param:【{}】, uuid is:【{}】", method, queryParams,
          uuid);
      return chain.filter(exchange.mutate().response(decoratedResponse)
          .build());
    }
    return chain.filter(exchange);
  }

  /**
   * 打印header.
   */
  private void printHeaders(String uuid, ServerHttpRequest request) {
    // 日志参数
    List<Object> reqArgs = new ArrayList<>();
    // 打印请求头
    HttpHeaders headers = request.getHeaders();
    headers.forEach((headerName, headerValue) -> {
      //reqLog.append("===Headers===  {}: {}\n");
      reqArgs.add(headerName);
      //如果有token,可以先把token解析后打印出原始报文,JwtUtil替换成自己项目里工具类
      if ("Authorization".toLowerCase().equals(headerName)) {
        String value = headerValue.get(0);
        reqArgs.add((value == null) ? "" : value);
        reqArgs.add(headerName.concat("-original"));
        reqArgs.add(StringUtils.join(headerValue.toArray()));
      } else {
        reqArgs.add(StringUtils.join(headerValue.toArray()));
      }
    });
    log.info("gateway headers is:【{}】, uuid is:【{}】", JSONUtil.toJsonStr(reqArgs), uuid);
  }

  @Override
  public int getOrder() {
    return -200;
  }
}

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

裂魂人1214

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值