diff --git a/src/main/java/com/profiler/context/AsyncTrace.java b/src/main/java/com/profiler/context/AsyncTrace.java index 93e1d07b8..4ee383222 100644 --- a/src/main/java/com/profiler/context/AsyncTrace.java +++ b/src/main/java/com/profiler/context/AsyncTrace.java @@ -82,7 +82,7 @@ public class AsyncTrace { } private void clearReference() { - // 관련 reference를 null로 하는게 좋지 않을까 함? + this.storage = null; } public void markAfterTime() { diff --git a/src/main/java/com/profiler/context/BypassStorageFactory.java b/src/main/java/com/profiler/context/BypassStorageFactory.java index bdb6412d7..db88a143e 100644 --- a/src/main/java/com/profiler/context/BypassStorageFactory.java +++ b/src/main/java/com/profiler/context/BypassStorageFactory.java @@ -6,9 +6,12 @@ import com.profiler.sender.DataSender; * */ public class BypassStorageFactory implements StorageFactory { + // 현재 해당 storage는 상태가 없어서 재사용해도 된다. 만약 상태가 존재하게 변경된다면 수정해야 된다. private BypassStorage storage = new BypassStorage(); + private DataSender dataSender; public BypassStorageFactory(DataSender dataSender) { + this.dataSender = dataSender; storage.setDataSender(dataSender); } @@ -16,4 +19,9 @@ public class BypassStorageFactory implements StorageFactory { public Storage createStorage() { return storage; } + + @Override + public DataSender getDataSender() { + return dataSender; + } } diff --git a/src/main/java/com/profiler/context/StorageFactory.java b/src/main/java/com/profiler/context/StorageFactory.java index 9ada12fad..24ed2c82c 100644 --- a/src/main/java/com/profiler/context/StorageFactory.java +++ b/src/main/java/com/profiler/context/StorageFactory.java @@ -1,8 +1,12 @@ package com.profiler.context; +import com.profiler.sender.DataSender; + /** * */ public interface StorageFactory { Storage createStorage(); + + DataSender getDataSender(); } diff --git a/src/main/java/com/profiler/context/TimeBaseStorageFactory.java b/src/main/java/com/profiler/context/TimeBaseStorageFactory.java index fb9b8a934..6e2f3c5a1 100644 --- a/src/main/java/com/profiler/context/TimeBaseStorageFactory.java +++ b/src/main/java/com/profiler/context/TimeBaseStorageFactory.java @@ -26,4 +26,9 @@ public class TimeBaseStorageFactory implements StorageFactory { timeBaseStorage.setDiscard(config.isSamplingElapsedTimeBaseDiscard()); return timeBaseStorage; } + + @Override + public DataSender getDataSender() { + return this.dataSender; + } } diff --git a/src/main/java/com/profiler/context/Trace.java b/src/main/java/com/profiler/context/Trace.java index 74aefe30c..048fe4f9a 100644 --- a/src/main/java/com/profiler/context/Trace.java +++ b/src/main/java/com/profiler/context/Trace.java @@ -34,9 +34,8 @@ public final class Trace { private Storage storage; - // TODO 아래 관련 핸들링 로직은 traceContext로 빼야지 이쁠뜻하다. - private LRUCache sqlCache; - private SqlParser sqlParser; + private TraceContext traceContext; + // use for calculating depth of each Span. private Integer latestStackIndex = null; @@ -72,10 +71,6 @@ public final class Trace { this.storage = storage; } - public DataSender getDataSender() { - return storage.getDataSender(); - } - public short getSequence() { return sequence++; } @@ -256,14 +251,16 @@ public final class Trace { if (methodDescriptor == null) { return; } - String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber(); - recordAttribute(AnnotationNames.API, method); + if(methodDescriptor.getApiId() == -1) { + recordAttribute(AnnotationNames.API, methodDescriptor.getFullName()); + } else { + recordAttribute(AnnotationNames.API_DID, methodDescriptor.getApiId()); + } } public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { // API 저장 방법의 개선 필요. - String method = methodDescriptor.getClassName() + "." + methodDescriptor.getMethodName() + methodDescriptor.getParameterDescriptor() + ":" + methodDescriptor.getLineNumber(); - recordAttribute(AnnotationNames.API, method); + recordApi(methodDescriptor); recocordArgs(args); } @@ -292,7 +289,7 @@ public final class Trace { if (sql == null) { return null; } - ParsingResult parsingResult = parseSql(sql); + ParsingResult parsingResult = traceContext.parseSql(sql); recordSqlParsingResult(parsingResult); return parsingResult; } @@ -305,35 +302,6 @@ public final class Trace { } } - public ParsingResult parseSql(String sql) { - - // 해당 api의 구현을 그냥 tarceContext api에 만들어야 될듯 하다. - ParsingResult parsingResult = this.sqlParser.normalizedSql(sql); - String normalizedSql = parsingResult.getSql(); - // 파싱시 변경되지 않았다면 동일 객체를 리턴하므로 그냥 ==비교를 하면 됨 - boolean newValue = this.sqlCache.put(normalizedSql); - if (newValue) { - if (logger.isLoggable(Level.FINE)) { - // TODO hit% 로그를 남겨야 문제 발생시 도움이 될듯 하다. - logger.fine("NewSQLParsingResult:" + parsingResult); - } - // newValue란 의미는 cache에 인입됬다는 의미이고 이는 신규 sql문일 가능성이 있다는 의미임. - // 그러므로 메타데이터를 서버로 전송해야 한다. - - // 프로파일 데이터를 보내는데 사용되는 queue가 아니고, - // 좀더 급한 메시지만 별도 처리할수 있는 상대적으로 더 한가한 queue와 datasender를 별도로 가지고 있는게 좋을듯 하다. - SqlMetaData sqlMetaData = new SqlMetaData(); - sqlMetaData.setAgentId(Agent.getInstance().getAgentId()); - sqlMetaData.setStartTime(Agent.getInstance().getStartTime()); - sqlMetaData.setHashCode(normalizedSql.hashCode()); - sqlMetaData.setSql(normalizedSql); - // 다른 우선순위가 더 높은 sender가 존재하면 좋을듯 하다. - this.getStorage().getDataSender().send(sqlMetaData); - } - // hashId그냥 return String에서 까보면 됨. - return parsingResult; - } - public void recordAttribute(final String key, final Object value) { if (!tracingEnabled) return; @@ -436,13 +404,8 @@ public final class Trace { } } - public void setSqlCache(LRUCache sqlCache) { - this.sqlCache = sqlCache; + public void setTraceContext(TraceContext traceContext) { + this.traceContext = traceContext; } - public void setSqlParser(SqlParser sqlParser) { - this.sqlParser = sqlParser; - } - - } \ No newline at end of file diff --git a/src/main/java/com/profiler/context/TraceContext.java b/src/main/java/com/profiler/context/TraceContext.java index fa02c78b7..b5bdc02dd 100644 --- a/src/main/java/com/profiler/context/TraceContext.java +++ b/src/main/java/com/profiler/context/TraceContext.java @@ -1,15 +1,27 @@ package com.profiler.context; +import com.profiler.Agent; +import com.profiler.common.dto.thrift.ApiMetaData; +import com.profiler.common.dto.thrift.SqlMetaData; +import com.profiler.common.util.ParsingResult; import com.profiler.common.util.SqlParser; +import com.profiler.interceptor.MethodDescriptor; import com.profiler.metadata.LRUCache; +import com.profiler.metadata.Result; +import com.profiler.metadata.StringCache; +import com.profiler.sender.DataSender; import com.profiler.util.Assert; import com.profiler.util.NamedThreadLocal; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; public class TraceContext { + private final Logger logger = Logger.getLogger(TraceContext.class.getName()); + private static TraceContext CONTEXT = new TraceContext(); // initailze관련 생명주기가 뭔가 애매함. 추후 방안을 더 고려해보자. @@ -37,9 +49,11 @@ public class TraceContext { private StorageFactory storageFactory; - private LRUCache LRU = new LRUCache(1000); + private LRUCache sqlCache = new LRUCache(1000); private SqlParser sqlParser = new SqlParser(); + private StringCache apiCache = new StringCache(); + public TraceContext() { } @@ -57,15 +71,15 @@ public class TraceContext { // trace.setDataSender(this.dataSender); Storage storage = storageFactory.createStorage(); trace.setStorage(storage); - trace.setSqlCache(this.LRU); - trace.setSqlParser(this.sqlParser); + trace.setTraceContext(this); + // // trace.setTransactionId(transactionId.getAndIncrement()); threadLocal.set(trace); } public void detachTraceObject() { - this.threadLocal.set(null); + this.threadLocal.remove(); } public GlobalCallTrace getGlobalCallTrace() { @@ -96,4 +110,52 @@ public class TraceContext { Assert.notNull(storageFactory, "storageFactory myst not be null"); this.storageFactory = storageFactory; } + + + public int cacheApi(MethodDescriptor methodDescriptor) { + String fullName = methodDescriptor.getFullName(); + Result result = this.apiCache.put(fullName); + if (result.isNewValue()) { + ApiMetaData apiMetadata = new ApiMetaData(); + apiMetadata.setAgentId(Agent.getInstance().getAgentId()); + apiMetadata.setStartTime(Agent.getInstance().getStartTime()); + apiMetadata.setApiId(result.getId()); + apiMetadata.setApiInfo(methodDescriptor.getApiDescriptor()); + apiMetadata.setLine(methodDescriptor.getLineNumber()); + DataSender dataSender = storageFactory.getDataSender(); + dataSender.send(apiMetadata); + methodDescriptor.setApiId(result.getId()); + } + return result.getId(); + } + + + + public ParsingResult parseSql(String sql) { + + ParsingResult parsingResult = this.sqlParser.normalizedSql(sql); + String normalizedSql = parsingResult.getSql(); + // 파싱시 변경되지 않았다면 동일 객체를 리턴하므로 그냥 ==비교를 하면 됨 + boolean newValue = this.sqlCache.put(normalizedSql); + if (newValue) { + if (logger.isLoggable(Level.FINE)) { + // TODO hit% 로그를 남겨야 문제 발생시 도움이 될듯 하다. + logger.fine("NewSQLParsingResult:" + parsingResult); + } + // newValue란 의미는 cache에 인입됬다는 의미이고 이는 신규 sql문일 가능성이 있다는 의미임. + // 그러므로 메타데이터를 서버로 전송해야 한다. + + // 프로파일 데이터를 보내는데 사용되는 queue가 아니고, + // 좀더 급한 메시지만 별도 처리할수 있는 상대적으로 더 한가한 queue와 datasender를 별도로 가지고 있는게 좋을듯 하다. + SqlMetaData sqlMetaData = new SqlMetaData(); + sqlMetaData.setAgentId(Agent.getInstance().getAgentId()); + sqlMetaData.setStartTime(Agent.getInstance().getStartTime()); + sqlMetaData.setHashCode(normalizedSql.hashCode()); + sqlMetaData.setSql(normalizedSql); + // 다른 우선순위가 더 높은 sender가 존재하면 좋을듯 하다. + this.storageFactory.getDataSender().send(sqlMetaData); + } + // hashId그냥 return String에서 까보면 됨. + return parsingResult; + } } diff --git a/src/main/java/com/profiler/interceptor/DefaultMethodDescriptor.java b/src/main/java/com/profiler/interceptor/DefaultMethodDescriptor.java index b61cc4d19..5747904bc 100644 --- a/src/main/java/com/profiler/interceptor/DefaultMethodDescriptor.java +++ b/src/main/java/com/profiler/interceptor/DefaultMethodDescriptor.java @@ -1,5 +1,7 @@ package com.profiler.interceptor; +import com.profiler.common.mapping.ApiUtils; + /** * */ @@ -15,9 +17,13 @@ public class DefaultMethodDescriptor implements MethodDescriptor { private String parameterDescriptor; + private String apiDescriptor; private int lineNumber; + private int apiId = -1; + + private String fullName; public DefaultMethodDescriptor() { } @@ -27,6 +33,8 @@ public class DefaultMethodDescriptor implements MethodDescriptor { this.methodName = methodName; this.parameterTypes = parameterTypes; this.parameterVariableName = parameterVariableName; + this.parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); + this.apiDescriptor = ApiUtils.mergeApiDescriptor(className, methodName, parameterDescriptor); } public String getParameterDescriptor() { @@ -83,4 +91,41 @@ public class DefaultMethodDescriptor implements MethodDescriptor { public int getLineNumber() { return lineNumber; } + + @Override + public String getFullName() { + if (fullName != null) { + return fullName; + } + StringBuilder buffer = new StringBuilder(256); + buffer.append(className); + buffer.append("."); + buffer.append(methodName); + buffer.append(parameterDescriptor); + if (lineNumber != -1) { + buffer.append(":"); + buffer.append(lineNumber); + } + fullName = buffer.toString(); + return fullName; + } + + public void setApiDescriptor(String apiDescriptor) { + this.apiDescriptor = apiDescriptor; + } + + @Override + public String getApiDescriptor() { + return apiDescriptor; + } + + @Override + public void setApiId(int apiId) { + this.apiId = apiId; + } + + @Override + public int getApiId() { + return apiId; + } } diff --git a/src/main/java/com/profiler/interceptor/InterceptorRegistry.java b/src/main/java/com/profiler/interceptor/InterceptorRegistry.java index 8f945e84a..d8925729a 100644 --- a/src/main/java/com/profiler/interceptor/InterceptorRegistry.java +++ b/src/main/java/com/profiler/interceptor/InterceptorRegistry.java @@ -33,7 +33,7 @@ public class InterceptorRegistry { } int newId = id.getAndIncrement(); if (newId > max) { - throw new IllegalArgumentException("id" + id); + throw new IndexOutOfBoundsException("size=" + index.length + " id=" + id); } this.index[newId] = interceptor; diff --git a/src/main/java/com/profiler/interceptor/MethodDescriptor.java b/src/main/java/com/profiler/interceptor/MethodDescriptor.java index 9e1e9936d..ccd78fc64 100644 --- a/src/main/java/com/profiler/interceptor/MethodDescriptor.java +++ b/src/main/java/com/profiler/interceptor/MethodDescriptor.java @@ -20,4 +20,12 @@ public interface MethodDescriptor { int getLineNumber(); + + String getFullName(); + + void setApiId(int apiId); + + int getApiId(); + + String getApiDescriptor(); } diff --git a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java index 7c70f1feb..c4ba4d5c5 100644 --- a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java +++ b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java @@ -217,9 +217,9 @@ public class JavaAssistClass implements InstrumentClass { methodDescriptor.setClassName(ctClass.getName()); - CtClass[] parameterTypes = behavior.getParameterTypes(); - String[] parameterType = JavaAssistUtils.getParameterType(parameterTypes); - methodDescriptor.setParameterTypes(parameterType); + CtClass[] ctParameterTypes = behavior.getParameterTypes(); + String[] parameterTypes = JavaAssistUtils.getParameterType(ctParameterTypes); + methodDescriptor.setParameterTypes(parameterTypes); String[] parameterVariableName = JavaAssistUtils.getParameterVariableName(behavior); methodDescriptor.setParameterVariableName(parameterVariableName); @@ -227,9 +227,11 @@ public class JavaAssistClass implements InstrumentClass { int lineNumber = JavaAssistUtils.getLineNumber(behavior); methodDescriptor.setLineNumber(lineNumber); - String parameterDescription = ApiUtils.mergeParameterVariableNameDescription(parameterType, parameterVariableName); - methodDescriptor.setParameterDescriptor(parameterDescription); + String parameterDescriptor = ApiUtils.mergeParameterVariableNameDescription(parameterTypes, parameterVariableName); + methodDescriptor.setParameterDescriptor(parameterDescriptor); + String apiDescriptor = ApiUtils.mergeApiDescriptor(ctClass.getName(), methodName, parameterDescriptor); + methodDescriptor.setApiDescriptor(apiDescriptor); interceptor.setMethodDescriptor(methodDescriptor); } diff --git a/src/main/java/com/profiler/metadata/Result.java b/src/main/java/com/profiler/metadata/Result.java new file mode 100644 index 000000000..5752282bc --- /dev/null +++ b/src/main/java/com/profiler/metadata/Result.java @@ -0,0 +1,24 @@ +package com.profiler.metadata; + +/** + * + */ +public class Result { + + private boolean newValue; + private int id; + + public Result(boolean newValue, int id) { + this.newValue = newValue; + this.id = id; + } + + public boolean isNewValue() { + return newValue; + } + + public int getId() { + return id; + } + +} diff --git a/src/main/java/com/profiler/metadata/SqlObject.java b/src/main/java/com/profiler/metadata/SqlObject.java index 17a806ea6..4900bd6c3 100644 --- a/src/main/java/com/profiler/metadata/SqlObject.java +++ b/src/main/java/com/profiler/metadata/SqlObject.java @@ -5,6 +5,7 @@ import com.profiler.util.Assert; /** * 없애도 될듯하다. */ +@Deprecated public class SqlObject { private String parsedSql; diff --git a/src/main/java/com/profiler/metadata/StringCache.java b/src/main/java/com/profiler/metadata/StringCache.java new file mode 100644 index 000000000..dfae3f715 --- /dev/null +++ b/src/main/java/com/profiler/metadata/StringCache.java @@ -0,0 +1,29 @@ +package com.profiler.metadata; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * + */ +public class StringCache { + + private final AtomicInteger idGen = new AtomicInteger(); + private final ConcurrentMap cache = new ConcurrentHashMap(); + + public Result put(String string) { + Integer find = this.cache.get(string); + if(find != null) { + return new Result(false, find); + } + + int newId = idGen.getAndIncrement(); + Integer before = this.cache.putIfAbsent(string, newId); + if (before != null) { + return new Result(false, before); + } + return new Result(true, newId); + } + +} diff --git a/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java b/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java index 4929f8dcc..ae76a2896 100644 --- a/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/bloc/handler/interceptors/ExecuteMethodInterceptor.java @@ -23,11 +23,11 @@ import com.profiler.util.StringUtils; /** * @author netspider */ -public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(ExecuteMethodInterceptor.class.getName()); private MethodDescriptor descriptor; - private int apiId; +// private int apiId; @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -99,8 +99,8 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo // 문제 있는 callstack을 dump하면 도움이 될듯. } -// trace.recordApi(descriptor); - trace.recordApi(this.apiId); + trace.recordApi(descriptor); +// trace.recordApi(this.apiId); trace.recordException(result); trace.markAfterTime(); @@ -156,10 +156,9 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } + } \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/connector/interceptors/Execute2MethodInterceptor.java b/src/main/java/com/profiler/modifier/connector/interceptors/Execute2MethodInterceptor.java index 59a0fdda0..58e3a407c 100644 --- a/src/main/java/com/profiler/modifier/connector/interceptors/Execute2MethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/connector/interceptors/Execute2MethodInterceptor.java @@ -89,7 +89,9 @@ public class Execute2MethodInterceptor implements StaticAroundInterceptor, ByteC @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; - } + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); + } private HttpHost extractHost(final URI uri) { if (uri == null) { diff --git a/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java b/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java index 9178cc4da..f8558fdce 100644 --- a/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/connector/interceptors/ExecuteMethodInterceptor.java @@ -32,11 +32,11 @@ import com.profiler.util.StringUtils; * throws IOException, ClientProtocolException { * */ -public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(ExecuteMethodInterceptor.class.getName()); private MethodDescriptor descriptor; - private int apiId; +// private int apiId; @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -81,8 +81,8 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo if (trace == null) { return; } - // trace.recordApi(descriptor); - trace.recordApi(this.apiId); + trace.recordApi(descriptor); +// trace.recordApi(this.apiId); trace.recordException(result); trace.markAfterTime(); @@ -92,10 +92,8 @@ public class ExecuteMethodInterceptor implements StaticAroundInterceptor, ByteCo @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } } \ No newline at end of file diff --git a/src/main/java/com/profiler/modifier/db/interceptor/DriverConnectInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/DriverConnectInterceptor.java index 9084c1f3e..1de9b4edb 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/DriverConnectInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/DriverConnectInterceptor.java @@ -1,9 +1,7 @@ package com.profiler.modifier.db.interceptor; -import com.profiler.context.Annotation; import com.profiler.context.Trace; import com.profiler.context.TraceContext; -import com.profiler.interceptor.ApiIdSupport; import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; import com.profiler.interceptor.MethodDescriptor; import com.profiler.interceptor.StaticAroundInterceptor; @@ -20,7 +18,7 @@ import java.util.logging.Logger; /** * */ -public class DriverConnectInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class DriverConnectInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(DriverConnectInterceptor.class.getName()); private final MetaObject setUrl = new MetaObject("__setUrl", Object.class); @@ -77,8 +75,7 @@ public class DriverConnectInterceptor implements StaticAroundInterceptor, ByteCo trace.recordRpcName(databaseInfo.getType(), databaseInfo.getDatabaseId(), databaseInfo.getUrl()); trace.recordEndPoint(databaseInfo.getUrl()); -// trace.recordApi(descriptor, new Object[]{args[0]}); - trace.recordApi(apiId, new Object[]{args[0]}); + trace.recordApi(descriptor, new Object[]{args[0]}); trace.recordException(result); trace.markAfterTime(); @@ -97,10 +94,9 @@ public class DriverConnectInterceptor implements StaticAroundInterceptor, ByteCo @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } + } diff --git a/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java index c2cacb11c..8e7c2be78 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java @@ -14,7 +14,7 @@ import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; -public class PreparedStatementCreateInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class PreparedStatementCreateInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(PreparedStatementCreateInterceptor.class.getName()); private MethodDescriptor descriptor; @@ -80,8 +80,8 @@ public class PreparedStatementCreateInterceptor implements StaticAroundIntercept trace.recordException(result); } -// trace.recordApi(descriptor, args); - trace.recordApi(apiId); + trace.recordApi(descriptor); +// trace.recordApi(apiId); trace.markAfterTime(); trace.traceBlockEnd(); @@ -91,10 +91,8 @@ public class PreparedStatementCreateInterceptor implements StaticAroundIntercept @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } } diff --git a/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java index 3f8488630..9944ecb3f 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementExecuteQueryInterceptor.java @@ -19,7 +19,7 @@ import com.profiler.modifier.db.util.DatabaseInfo; import com.profiler.util.MetaObject; import com.profiler.util.StringUtils; -public class PreparedStatementExecuteQueryInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class PreparedStatementExecuteQueryInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(PreparedStatementExecuteQueryInterceptor.class.getName()); @@ -60,8 +60,8 @@ public class PreparedStatementExecuteQueryInterceptor implements StaticAroundInt String bindString = toBindVariable(bindValue); trace.recordAttribute(AnnotationNames.SQL_BINDVALUE, bindString); -// trace.recordApi(descriptor, args); - trace.recordApi(apiId); + trace.recordApi(descriptor); +// trace.recordApi(apiId); // clean 타이밍을 변경해야 될듯 하다. clean(target); @@ -121,10 +121,9 @@ public class PreparedStatementExecuteQueryInterceptor implements StaticAroundInt @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } + } diff --git a/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteQueryInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteQueryInterceptor.java index 3b111625b..5e808ed13 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteQueryInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteQueryInterceptor.java @@ -88,5 +88,7 @@ public class StatementExecuteQueryInterceptor implements StaticAroundInterceptor @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } } diff --git a/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteUpdateInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteUpdateInterceptor.java index 879f043c3..1bec90101 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteUpdateInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/StatementExecuteUpdateInterceptor.java @@ -4,6 +4,8 @@ import com.profiler.common.AnnotationNames; import com.profiler.context.Trace; import com.profiler.context.TraceContext; import com.profiler.interceptor.ApiIdSupport; +import com.profiler.interceptor.ByteCodeMethodDescriptorSupport; +import com.profiler.interceptor.MethodDescriptor; import com.profiler.interceptor.StaticAroundInterceptor; import com.profiler.modifier.db.util.DatabaseInfo; import com.profiler.util.MetaObject; @@ -18,12 +20,13 @@ import java.util.logging.Logger; * * @author netspider */ -public class StatementExecuteUpdateInterceptor implements StaticAroundInterceptor, ApiIdSupport { +public class StatementExecuteUpdateInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(StatementExecuteUpdateInterceptor.class.getName()); private final MetaObject getUrl = new MetaObject("__getUrl"); - private int apiId; +// private int apiId; + private MethodDescriptor descriptor; @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -47,7 +50,7 @@ public class StatementExecuteUpdateInterceptor implements StaticAroundIntercepto DatabaseInfo databaseInfo = (DatabaseInfo) this.getUrl.invoke(target); trace.recordRpcName(databaseInfo.getType(), databaseInfo.getDatabaseId(), databaseInfo.getUrl()); trace.recordEndPoint(databaseInfo.getUrl()); - trace.recordApi(apiId); + trace.recordApi(descriptor); if (args.length > 0) { Object arg = args[0]; if (arg instanceof String) { @@ -84,7 +87,9 @@ public class StatementExecuteUpdateInterceptor implements StaticAroundIntercepto } @Override - public void setApiId(int apiId) { - this.apiId = apiId; + public void setMethodDescriptor(MethodDescriptor descriptor) { + this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } } diff --git a/src/main/java/com/profiler/modifier/db/interceptor/TransactionInterceptor.java b/src/main/java/com/profiler/modifier/db/interceptor/TransactionInterceptor.java index a7ca2b409..9cad5aef7 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/TransactionInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/TransactionInterceptor.java @@ -15,13 +15,12 @@ import com.profiler.modifier.db.util.DatabaseInfo; import com.profiler.util.MetaObject; import com.profiler.util.StringUtils; -public class TransactionInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport { +public class TransactionInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport { private final Logger logger = Logger.getLogger(TransactionInterceptor.class.getName()); private final MetaObject getUrl = new MetaObject("__getUrl"); private MethodDescriptor descriptor; - private int apiId; @Override public void before(Object target, String className, String methodName, String parameterDescription, Object[] args) { @@ -85,8 +84,8 @@ public class TransactionInterceptor implements StaticAroundInterceptor, ByteCode private void afterStartTransaction(Trace trace, Connection target, Object[] arg, Object result) { try { -// trace.recordApi(descriptor, arg); - trace.recordApi(apiId, arg); + trace.recordApi(descriptor, arg); +// trace.recordApi(apiId, arg); trace.recordException(result); // Boolean autocommit = (Boolean) arg; // boolean success = InterceptorUtils.isSuccess(result); @@ -138,8 +137,8 @@ public class TransactionInterceptor implements StaticAroundInterceptor, ByteCode trace.recordRpcName(databaseInfo.getType(), databaseInfo.getDatabaseId(), databaseInfo.getUrl()); trace.recordEndPoint(databaseInfo.getUrl()); -// trace.recordApi(descriptor); - trace.recordApi(apiId); + trace.recordApi(descriptor); +// trace.recordApi(apiId); trace.recordException(result); // boolean success = InterceptorUtils.isSuccess(result); @@ -178,8 +177,8 @@ public class TransactionInterceptor implements StaticAroundInterceptor, ByteCode trace.recordRpcName(databaseInfo.getType(), databaseInfo.getDatabaseId(), databaseInfo.getUrl()); trace.recordEndPoint(databaseInfo.getUrl()); -// trace.recordApi(descriptor); - trace.recordApi(apiId); + trace.recordApi(descriptor); +// trace.recordApi(apiId); trace.recordException(result); // boolean success = InterceptorUtils.isSuccess(result); // if (success) { @@ -201,10 +200,9 @@ public class TransactionInterceptor implements StaticAroundInterceptor, ByteCode @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } + } diff --git a/src/main/java/com/profiler/modifier/method/MethodModifier.java b/src/main/java/com/profiler/modifier/method/MethodModifier.java index f10e7b197..9f69c9428 100644 --- a/src/main/java/com/profiler/modifier/method/MethodModifier.java +++ b/src/main/java/com/profiler/modifier/method/MethodModifier.java @@ -61,8 +61,9 @@ public class MethodModifier extends AbstractModifier { for (int i = 0; i < paramClass.length; i++) { params[i] = paramClass[i].getName(); } - - System.out.println("### c=" + javassistClassName + ", m=" + m.getName() + ", params=" + Arrays.toString(params)); + if(logger.isLoggable(Level.INFO)) { + logger.info("### c=" + javassistClassName + ", m=" + m.getName() + ", params=" + Arrays.toString(params)); + } clazz.addInterceptor(m.getName(), params, interceptor); } diff --git a/src/main/java/com/profiler/modifier/method/interceptors/MethodInterceptor.java b/src/main/java/com/profiler/modifier/method/interceptors/MethodInterceptor.java index 455126c9c..9a769925d 100644 --- a/src/main/java/com/profiler/modifier/method/interceptors/MethodInterceptor.java +++ b/src/main/java/com/profiler/modifier/method/interceptors/MethodInterceptor.java @@ -19,11 +19,10 @@ import com.profiler.util.StringUtils; * @author netspider * */ -public class MethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport, TraceContextSupport { +public class MethodInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { private final Logger logger = Logger.getLogger(MethodInterceptor.class.getName()); private MethodDescriptor descriptor; - private int apiId; private TraceContext traceContext; @Override @@ -62,15 +61,12 @@ public class MethodInterceptor implements StaticAroundInterceptor, ByteCodeMetho @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; - } - - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); + } @Override public void setTraceContext(TraceContext traceContext) { this.traceContext = traceContext; - } + } } diff --git a/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java b/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java index 165ecef54..1c11b87ad 100644 --- a/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java +++ b/src/main/java/com/profiler/modifier/servlet/interceptors/DoXXXInterceptor.java @@ -23,11 +23,10 @@ import com.profiler.interceptor.TraceContextSupport; import com.profiler.util.NumberUtils; import com.profiler.util.StringUtils; -public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport, TraceContextSupport { +public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { private final Logger logger = Logger.getLogger(DoXXXInterceptor.class.getName()); private MethodDescriptor descriptor; - private int apiId; private TraceContext traceContext; /* @@ -126,8 +125,8 @@ public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethod // 문제 있는 callstack을 dump하면 도움이 될듯. } - // trace.recordApi(descriptor); - trace.recordApi(this.apiId); + trace.recordApi(descriptor); +// trace.recordApi(this.apiId); trace.recordException(result); @@ -187,12 +186,10 @@ public class DoXXXInterceptor implements StaticAroundInterceptor, ByteCodeMethod @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } @Override public void setTraceContext(TraceContext traceContext) { diff --git a/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java b/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java index 7eca85025..3f5429d09 100644 --- a/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java +++ b/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java @@ -23,11 +23,11 @@ import com.profiler.interceptor.TraceContextSupport; import com.profiler.util.NumberUtils; import com.profiler.util.StringUtils; -public class StandardHostValveInvokeInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, ApiIdSupport, TraceContextSupport { +public class StandardHostValveInvokeInterceptor implements StaticAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { private final Logger logger = Logger.getLogger(StandardHostValveInvokeInterceptor.class.getName()); private MethodDescriptor descriptor; - private int apiId; +// private int apiId; private TraceContext traceContext; @Override @@ -102,8 +102,8 @@ public class StandardHostValveInvokeInterceptor implements StaticAroundIntercept // 문제 있는 callstack을 dump하면 도움이 될듯. } - // trace.recordApi(descriptor); - trace.recordApi(this.apiId); + trace.recordApi(descriptor); +// trace.recordApi(this.apiId); trace.recordException(result); @@ -163,12 +163,11 @@ public class StandardHostValveInvokeInterceptor implements StaticAroundIntercept @Override public void setMethodDescriptor(MethodDescriptor descriptor) { this.descriptor = descriptor; + TraceContext traceContext = TraceContext.getTraceContext(); + traceContext.cacheApi(descriptor); + } - @Override - public void setApiId(int apiId) { - this.apiId = apiId; - } @Override public void setTraceContext(TraceContext traceContext) { diff --git a/src/test/java/com/profiler/metadata/StringCacheTest.java b/src/test/java/com/profiler/metadata/StringCacheTest.java new file mode 100644 index 000000000..d0c38a5af --- /dev/null +++ b/src/test/java/com/profiler/metadata/StringCacheTest.java @@ -0,0 +1,24 @@ +package com.profiler.metadata; + +import junit.framework.Assert; +import org.junit.Test; + +/** + * + */ +public class StringCacheTest { + + @Test + public void put() { + StringCache cache = new StringCache(); + Result test = cache.put("test"); + Assert.assertEquals(0, test.getId()); + + Result recheck = cache.put("test"); + Assert.assertEquals(test.getId(), recheck.getId()); + + Result newValue = cache.put("new"); + Assert.assertEquals(1, newValue.getId()); + + } +}