关注的几个点:
a tcp连接netty的使用 TODO
b 服务间调用messageId rootId parentId的传递如何实现 第4点有提到
c mybatis如何作为一个transation类似的消息也加入 messageTree的 因为之前记录都是的都是url 使用拦截器 参考第5点
几个片段
1 D:\work\git\taimei\cat\cat-client\src\main\java\com\dianping\cat\Cat.java
初始化cat
// this should be called during application initialization time
public static void initialize(File configFile) {
try {
if (!s_init) {
synchronized (s_instance) {
if (!s_init) {
PlexusContainer container = ContainerLoader.getDefaultContainer();
ModuleContext ctx = new DefaultModuleContext(container);
Module module = ctx.lookup(Module.class, CatClientModule.ID);
if (!module.isInitialized()) {
ModuleInitializer initializer = ctx.lookup(ModuleInitializer.class);
ctx.setAttribute("cat-client-config-file", configFile);
initializer.execute(ctx, module);
}
log("INFO", "Cat is lazy initialized!");
s_init = true;
}
}
}
} catch (Exception e) {
errorHandler(e);
}
}
加载client.xml地方
2 MessageTree 的一个主要实现
public class DefaultMessageTree implements MessageTree {
private ByteBuf m_buf;
private String m_domain;
private String m_hostName;
private String m_ipAddress;
private Message m_message;
private String m_messageId;
private String m_parentMessageId;
private String m_rootMessageId;
private String m_sessionToken;
private String m_threadGroupName;
private String m_threadId;
private String m_threadName;
private MessageId m_formatMessageId;
private boolean m_discard = true;
private boolean m_processLoss = false;
private boolean m_hitSample = false;
private List
private List
private List
private List
3 有很多context类
主要看这个上下文
@Named(type = MessageManager.class)
public class DefaultMessageManager extends ContainerHolder implements MessageManager, Initializable, LogEnabled {
还有这个
4 catFilter写入rootId parentId messageId 信息到header传递给下一个请求.
代码路径
package com.dianping.cat.servlet;
public class CatFilter implements Filter {
ID_SETUP {
private String m_servers;
private String getCatServer() {
if (m_servers == null) {
DefaultMessageManager manager = (DefaultMessageManager) Cat.getManager();
List servers = manager.getConfigManager().getServers();
m_servers = Joiners.by(',').join(servers, new IBuilder() {
@Override
public String asString(Server server) {
String ip = server.getIp();
Integer httpPort = server.getHttpPort();
if ("127.0.0.1".equals(ip)) {
ip = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
}
return ip + ":" + httpPort;
}
});
}
return m_servers;
}
@Override
public void handle(Context ctx) throws IOException, ServletException {
boolean isTraceMode = Cat.getManager().isTraceMode();
HttpServletRequest req = ctx.getRequest();
HttpServletResponse res = ctx.getResponse();
MessageProducer producer = Cat.getProducer();
int mode = ctx.getMode();
switch (mode) {
case 0:
ctx.setId(producer.createMessageId());
break;
case 1:
ctx.setRootId(req.getHeader("X-CAT-ROOT-ID"));
ctx.setParentId(req.getHeader("X-CAT-PARENT-ID"));
ctx.setId(req.getHeader("X-CAT-ID"));
break;
case 2:
ctx.setRootId(producer.createMessageId());
ctx.setParentId(ctx.getRootId());
ctx.setId(producer.createMessageId());
break;
default:
throw new RuntimeException(String.format("Internal Error: unsupported mode(%s)!", mode));
}
if (isTraceMode) {
MessageTree tree = Cat.getManager().getThreadLocalMessageTree();
tree.setMessageId(ctx.getId());
tree.setParentMessageId(ctx.getParentId());
tree.setRootMessageId(ctx.getRootId());
res.setHeader("X-CAT-SERVER", getCatServer());
switch (mode) {
case 0:
res.setHeader("X-CAT-ROOT-ID", ctx.getId());
break;
case 1:
res.setHeader("X-CAT-ROOT-ID", ctx.getRootId());
res.setHeader("X-CAT-PARENT-ID", ctx.getParentId());
res.setHeader("X-CAT-ID", ctx.getId());
break;
case 2:
res.setHeader("X-CAT-ROOT-ID", ctx.getRootId());
res.setHeader("X-CAT-PARENT-ID", ctx.getParentId());
res.setHeader("X-CAT-ID", ctx.getId());
break;
}
}
ctx.handle();
}
},
5 mybatis信息采集的问题
官方整理了一个mybatis的拦截器
https://github.com/dianping/cat/blob/master/integration/mybatis/CatMybatisPlugin.java
主要代码如下
@Override | |
public Object intercept(Invocation invocation) throws Throwable { | |
MappedStatement mappedStatement = this.getStatement(invocation); | |
String methodName = this.getMethodName(mappedStatement); | |
Transaction t = Cat.newTransaction("SQL", methodName); | |
String sql = this.getSql(invocation,mappedStatement); | |
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); | |
Cat.logEvent("SQL.Method", sqlCommandType.name().toLowerCase(), Message.SUCCESS, sql); | |
String url = this.getSQLDatabaseUrlByStatement(mappedStatement); | |
Cat.logEvent("SQL.Database", url); | |
return doFinish(invocation,t); | |
} |
可看到是主动写入一个Transaction (就是一个message) 到当前的messageTree里面 然后就采集到了,可以跟一下里面代码
下面是关闭的过程