[강운덕] [LUCYSUS-1744] sql의 meta data를 따기 위한 일부 util및 agent수정 코드 부분 커밋.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1081 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2013-01-08 01:48:30 +00:00
parent c2bce47ec7
commit 1310e2d41b
6 changed files with 192 additions and 7 deletions
+13 -4
View File
@@ -33,6 +33,7 @@ public class Agent {
private final String agentId;
private final String nodeName;
private final String applicationName;
private final long startTime;
public Agent(ProfilerConfig profilerConfig) {
Assert.notNull(profilerConfig, "profilerConfig must not be null");
@@ -44,10 +45,12 @@ public class Agent {
// 일단 임시로 호환성을 위해 agentid에 머신name을넣도록 하자
String machineName = NetworkUtils.getMachineName();
this.agentId = getId("hippo.agentId", machineName);
// TODO node name의 string limit 제한을 해결해야 된다.
this.nodeName = getId("hippo.nodeName", machineName);
this.applicationName = getId("hippo.applicationName", "UnknownApplicationName");
this.dataSender = createDataSender();
this.startTime = System.currentTimeMillis();
initializeTraceContext();
@@ -93,7 +96,7 @@ public class Agent {
logger.warning(idName + " is too long(1~24). value=" + id);
}
// validate = false;
// TODO 이거 후처리를 어떻게 해야 될지. agent를 시작 시키지 않아야 될거 같은데. lifecycle이 이쪽저쪽에 퍼져 있어서 일관된 stop에 문제가 있음..
// TODO 이제 그냥 exception을 던지면 됨 agent 생성 타이밍이 최초 vm스타트와 동일하다.
} catch (UnsupportedEncodingException e) {
logger.log(Level.WARNING, "invalid agentId. Cause:" + e.getMessage(), e);
}
@@ -125,6 +128,10 @@ public class Agent {
return agentId;
}
public long getStartTime() {
return startTime;
}
public String getApplicationName() {
return applicationName;
}
@@ -153,8 +160,9 @@ public class Agent {
agentInfo.setPorts(ports);
agentInfo.setAgentId(getAgentId());
agentInfo.setApplicationName(getApplicationName());
agentInfo.setIsAlive(true);
agentInfo.setTimestamp(System.currentTimeMillis());
agentInfo.setTimestamp(this.startTime);
this.dataSender.send(agentInfo);
}
@@ -177,11 +185,12 @@ public class Agent {
agentInfo.setHostname(ip);
agentInfo.setPorts(ports);
agentInfo.setIsAlive(false);
agentInfo.setTimestamp(System.currentTimeMillis());
agentInfo.setAgentId(getAgentId());
agentInfo.setApplicationName(getApplicationName());
agentInfo.setIsAlive(false);
agentInfo.setTimestamp(this.startTime);
this.dataSender.send(agentInfo);
// 종료 처리 필요.
this.dataSender.stop();
@@ -114,6 +114,11 @@ public class TomcatProfiler implements ClassFileTransformer {
}
String javassistClassName = className.replace('/', '.');
return findModifier.modify(classLoader, javassistClassName, protectionDomain, classFileBuffer);
try {
return findModifier.modify(classLoader, javassistClassName, protectionDomain, classFileBuffer);
} catch (Exception e) {
logger.log(Level.SEVERE, "Modifier:" + findModifier.getTargetClass() + " modify fail. Cause:" + e.getMessage(), e);
return null;
}
}
}
@@ -0,0 +1,78 @@
package com.profiler.metadata;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* approximate concurrent lru cache
*/
public class SqlCacheTable<T> {
private static final Object V = new Object();
private int concurrentLevel = 16;
private Map[] entry;
private AtomicInteger cacheSize = new AtomicInteger();
private int maxCacheSize = 500;
public SqlCacheTable(int maxCacheSize) {
this.maxCacheSize = maxCacheSize;
initialize();
}
public SqlCacheTable() {
initialize();
}
private void initialize() {
this.entry = new Map[concurrentLevel];
for (int i = 0; i < concurrentLevel; i++) {
this.entry[i] = createLinkedHashMap();
}
}
private Map createLinkedHashMap() {
LinkedHashMap map = new LinkedHashMap(200, .75F, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
// 해당 cache는 구현은 매우 정확하게 max사이를 가지고 있지 않음, 어느정도 오차가 있는 범위에서 동작한다..
boolean remove = cacheSize.get() + 1 > maxCacheSize;
// + 1의 경우 성능을 좀더 높이기 위해서 put이후 정상적으로 들어갔을 경우 count를 increment시키기 때문에 먼저 +1해서 봄
// +-대략 concurrentLevel 정도의 오차가 생길수 있을것으로 추정함.
if (remove) {
cacheSize.getAndDecrement();
}
return remove;
}
};
return Collections.synchronizedMap(map);
}
public boolean put(T value) {
Map cacheMap = getHashEntry(value);
Object oldValue = cacheMap.put(value, V);
if (oldValue == null) {
cacheSize.incrementAndGet();
return true;
}
return false;
}
private Map getHashEntry(T key) {
int entryNumber = Math.abs(key.hashCode()) % concurrentLevel;
return this.entry[entryNumber];
}
public int getSize() {
return cacheSize.get();
}
}
@@ -0,0 +1,40 @@
package com.profiler.metadata;
import com.profiler.util.Assert;
/**
* 없애도 될듯하다.
*/
public class SqlObject {
private String parsedSql;
public SqlObject(String parsedSql) {
Assert.notNull(parsedSql, "parsedSql is not null");
this.parsedSql = parsedSql;
}
public String getParsedSql() {
return parsedSql;
}
public int getParsedSqlHashCode() {
return parsedSql.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SqlObject sqlObject = (SqlObject) o;
if (parsedSql != null ? !parsedSql.equals(sqlObject.parsedSql) : sqlObject.parsedSql != null) return false;
return true;
}
@Override
public int hashCode() {
return parsedSql != null ? parsedSql.hashCode() : 0;
}
}
@@ -41,16 +41,19 @@ public class MySQLStatementModifier extends AbstractModifier {
Interceptor executeUpdate1 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.interceptor.StatementExecuteUpdateInterceptor");
statementClass.addInterceptor("executeUpdate", new String[]{"java.lang.String"}, executeUpdate1);
Interceptor executeUpdate2 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.interceptor.StatementExecuteUpdateInterceptor");
statementClass.addInterceptor("executeUpdate", new String[]{"java.lang.String", "boolean"}, executeUpdate2);
statementClass.addInterceptor("executeUpdate", new String[]{"java.lang.String", "int"}, executeUpdate2);
Interceptor executeUpdate3 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.interceptor.StatementExecuteUpdateInterceptor");
statementClass.addInterceptor("execute", new String[]{"java.lang.String"}, executeUpdate3);
Interceptor executeUpdate4 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.profiler.modifier.db.interceptor.StatementExecuteUpdateInterceptor");
statementClass.addInterceptor("execute", new String[]{"java.lang.String", "boolean"}, executeUpdate4);
statementClass.addInterceptor("execute", new String[]{"java.lang.String", "int"}, executeUpdate4);
statementClass.addTraceVariable("__url", "__setUrl", "__getUrl", "java.lang.Object");
return statementClass.toBytecode();
} catch (InstrumentException e) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(Level.WARNING, this.getClass().getSimpleName() + " modify fail. Cause:" + e.getMessage(), e);
}
return null;
}
}