diff --git a/src/main/java/com/profiler/context/DefaultTrace.java b/src/main/java/com/profiler/context/DefaultTrace.java index eeac6dbf4..f4a1c5023 100644 --- a/src/main/java/com/profiler/context/DefaultTrace.java +++ b/src/main/java/com/profiler/context/DefaultTrace.java @@ -270,28 +270,9 @@ public final class DefaultTrace implements Trace { return parsingResult; } -// 재발할 경우 좀더 정확한 원인분석을 위해 과거 NullPointException 발생 로그의 일부를 첨부함. -// 2013-04-30 11:34:58 [DEBUG](db.interceptor.PreparedStatementBindVariableInterceptor) after com.mysql.jdbc.JDBC4PreparedStatement@1f31ad9: /* testquery */ delete from member where id = -1334720425 com.mysql.jdbc.PreparedStatement setInt(int, int) args:(1, -1334720425) result:null -// 2013-04-30 11:34:58 [DEBUG](db.interceptor.PreparedStatementBindVariableInterceptor) after com.mysql.jdbc.JDBC4PreparedStatement@1f31ad9: /* testquery */ delete from member where id = -1334720425 com.mysql.jdbc.PreparedStatement setObject(int, java.lang.Object) args:(1, -1334720425) result:null -// 2013-04-30 11:34:58 [DEBUG](db.interceptor.PreparedStatementExecuteQueryInterceptor) before com.mysql.jdbc.JDBC4PreparedStatement@1f31ad9: /* testquery */ delete from member where id = -1334720425 com.mysql.jdbc.PreparedStatement executeUpdate() args:null -// 2013-04-30 11:34:58 [WARN ](db.interceptor.PreparedStatementExecuteQueryInterceptor) -// java.lang.NullPointerException -// at com.profiler.context.DefaultTrace.recordSqlParsingResult(DefaultTrace.java:275) -// at com.profiler.modifier.db.interceptor.PreparedStatementExecuteQueryInterceptor.before(PreparedStatementExecuteQueryInterceptor.java:64) -// at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java) -// at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) -// at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) -// at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) -// at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:818) -// at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:1) -// at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587) -// at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:812) @Override public void recordSqlParsingResult(ParsingResult parsingResult) { if (parsingResult == null) { - // TODO 먼가 여기서 NullPointException이 발생한 Exception 기록이 잇음. - - logger.warn("ParsingResult is null"); return; } String sql = parsingResult.getSql(); diff --git a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java index 573792f3a..5d48210ef 100644 --- a/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java +++ b/src/main/java/com/profiler/interceptor/bci/JavaAssistClass.java @@ -330,9 +330,9 @@ public class JavaAssistClass implements InstrumentClass { if (interceptorType == STATIC_INTERCEPTOR) { parameterTypeString = JavaAssistUtils.getParameterDescription(behavior.getParameterTypes()); } - String parameter = getParameter(behavior); + final String parameter = getParameter(behavior); - CodeBuilder after = new CodeBuilder(); + final CodeBuilder after = new CodeBuilder(); if (useContextClassLoader) { after.begin(); beginAddFindInterceptorCode(id, after, interceptorType); @@ -362,9 +362,9 @@ public class JavaAssistClass implements InstrumentClass { } after.end(); } - String buildAfter = after.toString(); + final String buildAfter = after.toString(); if (logger.isDebugEnabled()) { - logger.debug("addStaticAfterInterceptor after behavior:{} code:{}", behavior.getLongName(), buildAfter); + logger.debug("addAfterInterceptor after behavior:{} code:{}", behavior.getLongName(), buildAfter); } behavior.insertAfter(buildAfter); @@ -402,7 +402,7 @@ public class JavaAssistClass implements InstrumentClass { } String buildCatch = catchCode.toString(); if (logger.isDebugEnabled()) { - logger.debug("addStaticAfterInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildCatch); + logger.debug("addAfterInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildCatch); } CtClass th = instrumentor.getClassPool().get("java.lang.Throwable"); behavior.addCatch(buildCatch, th); 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 ae594e6e4..a8441f9f5 100644 --- a/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java +++ b/src/main/java/com/profiler/modifier/db/interceptor/PreparedStatementCreateInterceptor.java @@ -6,12 +6,10 @@ import com.profiler.context.TraceContext; import com.profiler.interceptor.*; import com.profiler.interceptor.util.JDBCScope; import com.profiler.logging.LoggerFactory; -import com.profiler.logging.LoggingUtils; import com.profiler.modifier.db.DatabaseInfo; import com.profiler.util.InterceptorUtils; import com.profiler.util.MetaObject; -import java.sql.Connection; import com.profiler.logging.Logger; public class PreparedStatementCreateInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport { @@ -26,7 +24,6 @@ public class PreparedStatementCreateInterceptor implements SimpleAroundIntercept private final MetaObject setUrl = new MetaObject("__setUrl", Object.class); private final MetaObject setSql = new MetaObject("__setSql", Object.class); - private int apiId; private TraceContext traceContext; @Override @@ -65,29 +62,31 @@ public class PreparedStatementCreateInterceptor implements SimpleAroundIntercept return; } boolean success = InterceptorUtils.isSuccess(result); + ParsingResult parsingResult = null; if (success) { // preparedStatement의 생성이 성공하였을 경우만 PreparedStatement에 databaseInfo를 세팅해야 한다. DatabaseInfo databaseInfo = (DatabaseInfo) getUrl.invoke(target); this.setUrl.invoke(result, databaseInfo); + // 1. traceContext를 체크하면 안됨. traceContext에서 즉 같은 thread에서 prearedStatement에서 안만들수도 있음. + // 2. sampling 동작이 동작할 경우 preparedStatement를 create하는 thread가 trace 대상이 아닐수 있음. 먼제 sql을 저장해야 한다. + String sql = (String) args[0]; + + parsingResult = traceContext.parseSql(sql); + if (parsingResult != null) { + this.setSql.invoke(result, parsingResult); + } else { + if (logger.isErrorEnabled()) { + logger.error("sqlParsing fail. parsingResult is null sql:{}", sql); + } + } } Trace trace = traceContext.currentTraceObject(); if (trace == null) { return; } - if (target instanceof Connection) { - String sql = (String) args[0]; - // 성공하였을 때만 PreparedSteatement에 Parsing Result를 넣어야 한다. - ParsingResult parsingResult = trace.recordSqlInfo(sql); - if (success) { - if (parsingResult != null) { - this.setSql.invoke(result, parsingResult); - } - } - - trace.recordException(result); - } + trace.recordException(result); trace.recordApi(descriptor); trace.markAfterTime(); 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 a3f8d6316..bf86abaca 100644 --- a/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java +++ b/src/main/java/com/profiler/modifier/tomcat/interceptors/StandardHostValveInvokeInterceptor.java @@ -73,7 +73,7 @@ public class StandardHostValveInvokeInterceptor implements SimpleAroundIntercept return; } else { if (isDebug) { - logger.debug("TraceID not exist. start new trace. traceId:{} requestUrl:{}, remoteAddr:{}", new Object[] { traceId, requestURL, remoteAddr }); + logger.debug("TraceID not exist. start new trace. requestUrl:{}, remoteAddr:{}", new Object[] { requestURL, remoteAddr }); } } }