CAT源码分析之过滤器
在 CAT 的 web.xml 中配置的2个过滤器
<filter>
<filter-name>cat-filter</filter-name>
<filter-class>com.dianping.cat.servlet.CatFilter</filter-class>
</filter>
<filter>
<filter-name>domain-filter</filter-name>
<filter-class>com.dianping.cat.report.view.DomainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cat-filter</filter-name>
<url-pattern>/r/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>domain-filter</filter-name>
<url-pattern>/r/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>cat-filter</filter-name>
<url-pattern>/s/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>cat-filter</filter-name>
<url-pattern>/jsp/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
其中
domain-filter根据domain设置cookie有效期- 只针对报表请求,
url-pattern是 /r/*
- 只针对报表请求,
cat-filter处理请求信息
值得学习点
枚举实现接口和循环操作
package com.dianping.cat.servlet;
public class CatFilter implements Filter {
private List<Handler> m_handlers = new ArrayList<Handler>();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
Context ctx = new Context((HttpServletRequest) request, (HttpServletResponse) response, chain, m_handlers);
ctx.handle(); // for 循环即 分步处理
}
....
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 处理化 分步步骤
m_handlers.add(CatHandler.ENVIRONMENT);
m_handlers.add(CatHandler.LOG_SPAN);
m_handlers.add(CatHandler.LOG_CLIENT_PAYLOAD);
m_handlers.add(CatHandler.ID_SETUP);
}
// 枚举 实现接口
private static enum CatHandler implements Handler {
ENVIRONMENT {
@Override
public void handle(Context ctx) throws IOException, ServletException {
HttpServletRequest req = ctx.getRequest();
boolean top = !Cat.getManager().hasContext();
ctx.setTop(top);
if (top) {
ctx.setType(CatConstants.TYPE_URL);
setTraceMode(req);
} else {
ctx.setType(CatConstants.TYPE_URL_FORWARD);
}
ctx.handle();
}
....
},
ID_SETUP {
....
@Override
public void handle(Context ctx) throws IOException, ServletException {
boolean isTraceMode = Cat.getManager().isTraceMode();
HttpServletResponse res = ctx.getResponse();
if (isTraceMode) {
String id = Cat.getCurrentMessageId();
res.setHeader("X-CAT-ROOT-ID", id);
res.setHeader("X-CAT-SERVER", getCatServer());
}
ctx.handle();
}
},
LOG_CLIENT_PAYLOAD {
@Override
public void handle(Context ctx) throws IOException, ServletException {
HttpServletRequest req = ctx.getRequest();
String type = ctx.getType();
if (ctx.isTop()) {
logRequestClientInfo(req, type);
logRequestPayload(req, type);
} else {
logRequestPayload(req, type);
}
ctx.handle();
}
....
},
LOG_SPAN {
.....
@Override
public void handle(Context ctx) throws IOException, ServletException {
HttpServletRequest req = ctx.getRequest();
Transaction t = Cat.newTransaction(ctx.getType(), getRequestURI(req));
try {
ctx.handle();
customizeStatus(t, req);
} catch (ServletException e) {
t.setStatus(e);
Cat.logError(e);
throw e;
} catch (IOException e) {
t.setStatus(e);
Cat.logError(e);
throw e;
} catch (Throwable e) {
t.setStatus(e);
Cat.logError(e);
throw new RuntimeException(e);
} finally {
customizeUri(t, req);
t.complete();
}
}
....
};
}
protected static class Context {
private FilterChain m_chain;
private List<Handler> m_handlers;
private int m_index;
private HttpServletRequest m_request;
private HttpServletResponse m_response;
private boolean m_top;
private String m_type;
public Context(HttpServletRequest request, HttpServletResponse response, FilterChain chain, List<Handler> handlers) {
m_request = request;
m_response = response;
m_chain = chain;
m_handlers = handlers;
}
....
// Context 封装 Handler 逻辑
public void handle() throws IOException, ServletException {
if (m_index < m_handlers.size()) {
Handler handler = m_handlers.get(m_index++);
handler.handle(this);
} else {
m_chain.doFilter(m_request, m_response);
}
}
....
}
// Handler 接口定义
protected static interface Handler {
public void handle(Context ctx) throws IOException, ServletException;
}
}

浙公网安备 33010602011771号