Exemplo n.º 1
0
 private void fillTraceContext(CharsetDetectRequestWrapper reqWrapper) {
   TraceContext traceContext = TraceContext.get();
   Pair<String, String> traceAndStep = FilterHelpers.getTraceIdAndRpcId(reqWrapper);
   traceContext.setTraceId(traceAndStep.first);
   traceContext.setParentRpcId(traceAndStep.second);
   traceContext.setSpider(FilterHelpers.isSpider(reqWrapper));
   traceContext.setColor(FilterHelpers.isColorized(reqWrapper)).setFail(false);
 }
Exemplo n.º 2
0
 private void copyResponse(HttpServletResponse res, BufferedResponseWrapper wrapper)
     throws IOException {
   if (wrapper.isError()) {
     res.setContentType("text/html; charset=UTF-8");
     res.sendError(wrapper.getStatus());
   }
   // 发送响应内容
   wrapper.flushBuffer();
   if (wrapper.getLength() > 0) {
     if (wrapper.isGZipped()) {
       res.setHeader("Content-Encoding", "gzip");
     }
     if (!res.isCommitted()) {
       String traceId = TraceContext.get().getTraceId();
       if (!Strings.isNullOrEmpty(traceId)) {
         res.setHeader("x-trace-id", traceId);
       }
       res.setContentLength(wrapper.getLength());
       wrapper.writeTo(res.getOutputStream());
       res.flushBuffer();
     }
   }
 }
Exemplo n.º 3
0
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    // 设定请求开始时间
    FilterHelpers.getRequestTime(req);

    if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(req)) {
      // Proceed without invoking this filter...
      chain.doFilter(request, response);
    } else {
      // Do invoke this filter...
      request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
      CharsetDetectRequestWrapper reqWrapper = new CharsetDetectRequestWrapper(req);
      boolean gzip = false;
      // 是否启用GZip压缩
      if (enableGZip) {
        String encoding = req.getHeader("Accept-Encoding");
        if (encoding != null && encoding.contains("gzip")) {
          gzip = true;
        }
      }
      BufferedResponseWrapper resWrapper = new BufferedResponseWrapper(res, gzip);
      try {
        // XXX: 生成traceId,需要请求_traceId的参数,所以必须放到CharsetEncodingHandler后面
        fillTraceContext(reqWrapper);
        chain.doFilter(reqWrapper, resWrapper);
        if (TraceContext.get().isColor()) {
          Cookie cookie = new Cookie("_color", "1");
          cookie.setMaxAge(3600);
          cookie.setPath("/");
          resWrapper.addCookie(cookie);
        }
      } catch (Exception e) {
        LOG.error("{}", req.getRequestURL(), e);
        resWrapper.setStatus(500);
        // 这里把异常抛出去,针对服务端异常,接入层nginx可以统计到,否则就统计不到
        throw new ServletException(
            req.getRequestURL() + ", message: " + e.getMessage(), e.getCause());
      } finally {
        request.removeAttribute(alreadyFilteredAttributeName);
        try {
          if (resWrapper.getLocation() != null) {
            res.sendRedirect(resWrapper.getLocation());
          } else {
            setContentType(res);
            try {
              copyResponse(res, resWrapper);
            } catch (Exception e) {
              long cost = FilterHelpers.getCostTime(req);
              LOG.error("{}, cost={}ms", req.getRequestURL(), cost, e);
            }
          }
        } finally {
          TraceContext c = TraceContext.get();
          TraceContext.remove();
          // 染色日志发送到总线上
          if (c.isColor()) {
            sendTrace(req, c, resWrapper);
          }
          // 统计页面状态信息
          PageStatusReporter.getInstance().stat(req, c.getCost(), res.getStatus(), c.isSpider());
        }
      }
    }
  }