重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇内容主要讲解“怎么在zuul上做日志处理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在zuul上做日志处理”吧!
创新互联公司是专业的丰都网站建设公司,丰都接单;提供成都网站设计、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行丰都网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!由于zuul作为api网关,所有的请求都经过这里,所以在网关上,可以做请求相关的日志处理。
我的需求是这样的,需要记录请求的 url,ip地址,参数,请求发生的时间,整个请求的耗时,请求的响应状态,
甚至请求响应的结果等。
很显然,需要实现这样的一个功能,需要写一个ZuulFliter,它应该是在请求发送给客户端之前做处理,并且在
route过滤器路由之后,在默认的情况下,这个过滤器的order应该为500-1000之间。那么如何获取这些我需要的
日志信息呢?找RequestContext,在请求的生命周期里这个对象里,存储了整个请求的所有信息。
现在编码,在代码的注释中,做了详细的说明,代码如下:
@Component public 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 .. Mapparams = 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存储一个时间即可,另写一个过滤器,代码如下:
@Component public 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上做日志处理”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!