本篇内容主要讲解“怎么在zuul上做日志处理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在zuul上做日志处理”吧!
由于zuul作为api网关,所有的请求都经过这里,所以在网关上,可以做请求相关的日志处理。
我的需求是这样的,需要记录请求的 url,ip地址,参数,请求发生的时间,整个请求的耗时,请求的响应状态,
甚至请求响应的结果等。
很显然,需要实现这样的一个功能,需要写一个ZuulFliter,它应该是在请求发送给客户端之前做处理,并且在
route过滤器路由之后,在默认的情况下,这个过滤器的order应该为500-1000之间。那么如何获取这些我需要的
日志信息呢?找RequestContext,在请求的生命周期里这个对象里,存储了整个请求的所有信息。
现在编码,在代码的注释中,做了详细的说明,代码如下:
@Componentpublic class LoggerFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); String method = request.getMethod();//氢气的类型,post get .. Map<String, String> params = HttpUtils.getParams(request); String paramsStr = params.toString();//请求的参数 long statrtTime = (long) context.get("startTime");//请求的开始时间 Throwable throwable = context.getThrowable();//请求的异常,如果有的话 request.getRequestURI();//请求的uri HttpUtils.getIpAddress(request);//请求的iP地址 context.getResponseStatusCode();//请求的状态 long duration=System.currentTimeMillis() - statrtTime);//请求耗时 return null; }}
现在读者也许有疑问,如何得到的statrtTime,即请求开始的时间,其实这需要另外一个过滤器,在网络请求route之前(大部分耗时都在route这一步),在过滤器中,在RequestContext存储一个时间即可,另写一个过滤器,代码如下:
@Componentpublic class AccessFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.set("startTime",System.currentTimeMillis()); return null; }}
可能还有这样的需求,我需要将响应结果,也要存储在log中,在之前已经分析了,在route结束后,将从具体服务获取的
响应流存储在RequestContext中,在SendResponseFilter过滤器写入在HttpServletResponse中,最终返回给客户端。那么我只需要在SendResponseFilter写入响应流之前把响应流写入到 log日志中即可,那么会引发另外一个问题,因为响应流写入到 log后,RequestContext就没有响应流了,在SendResponseFilter就没有流输入到HttpServletResponse中,导致客户端没有任何的返回数据,那么解决的办法是这样的:
InputStream inputStream =RequestContext.getCurrentContext().getResponseDataStream();InputStream newInputStream= copy(inputStream);transerferTolog(inputStream);RequestContext.getCurrentContext().setResponseDataStream(newInputStream);
从RequestContext获取到流之后,首先将流 copy一份,将流转化下字符串,存在日志中,再set到RequestContext中,
这样SendResponseFilter就可以将响应返回给客户端。这样的做法有点影响性能,如果不是字符流,可能需要做更多的处理工作。
到此,相信大家对“怎么在zuul上做日志处理”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!