请求响应日志是日常开发调试定位问题的重要手段,在微服务中引入SpringCloud Gateway后我们希望在网关层统一进行日志的收集。
本节内容将实现以下两个功能:
- 获取请求的输入输出参数,封装成自定义日志
- 将日志发送到MongoDB进行存储
获取输入输出参数
- 首先我们先定义一个日志体
@Data
public class GatewayLog {
/**访问实例*/
private String targetServer;
/**请求路径*/
private String requestPath;
/**请求方法*/
private String requestMethod;
/**协议 */
private String schema;
/**请求体*/
private String requestBody;
/**响应体*/
private String responseData;
/**请求ip*/
private String ip;
/**请求时间*/
private Date requestTime;
/**响应时间*/
private Date responseTime;
/**执行时间*/
private long executeTime;
}
复制代码
- 【关键】在网关定义日志过滤器,获取输入输出参数
/**
* 日志过滤器,用于记录日志
* @author jianzh5
* @date 2020/3/24 17:17
*/
@Slf4j
@Component
public class AccessLogFilter implements GlobalFilter, Ordered {
@Autowired
private AccessLogService accessLogService;
private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
/**
* 顺序必须是<-1,否则标准的NettyWriteResponseFilter将在您的过滤器得到一个被调用的机会之前发送响应
* 也就是说如果不小于 -1 ,将不会执行获取后端响应的逻辑
* @return
*/
@Override
public int getOrder() {
return -100;
}
@Override
@SuppressWarnings("unchecked")
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 请求路径
String requestPath = request.getPath().pathWithinApplication().value();
Route route = getGatewayRoute(exchange);
String ipAddress = WebUtils.getServerHttpRequestIpAddress(request);
GatewayLog gatewayLog = new GatewayLog();
gatewayLog.setSchema(request.getURI().getScheme());
gatewayLog.setRequestMethod(request.getMethodValue());
gatewayLog.setRequestPath(requestPath);
gatewayLog.setTargetServer(route.getId());
gatewayLog.setRequestTime(new Date());
gatewayLog.setIp(ipAddress);
MediaType mediaType = request.getHeaders().getContentType();
if(MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType) || M