Translated comments to English

This commit is contained in:
Jongho Moon
2014-12-29 18:38:35 +09:00
parent 99ff0fe10a
commit eb6fdb00bf
44 changed files with 130 additions and 156 deletions
@@ -196,8 +196,10 @@ public class JavaAssistClass implements InstrumentClass {
if (traceValue == null) {
throw new NullPointerException("traceValue must not be null");
}
// testcase에서 classLoader가 다를수 있어서 isAssignableFrom으로 안함.
// 추가로 수정하긴해야 될듯함.
// TODO In unit test, we cannot use isAssignableFrom() because same class is loaded by different class loaders.
// So we compare interface names implemented by traceValue.
// We'd better find better solution.
final boolean marker = checkTraceValueMarker(traceValue);
if (!marker) {
throw new InstrumentException(traceValue + " marker interface not implements" );
@@ -213,14 +215,12 @@ public class JavaAssistClass implements InstrumentClass {
boolean requiredField = false;
for (java.lang.reflect.Method method : declaredMethods) {
// 2개 이상의 중복일때를 체크하지 않았음.
// TODO need to check duplicated getter/setter for the same type.
if (isSetter(method)) {
// setter
CtMethod setterMethod = CtNewMethod.setter(method.getName(), traceVariableType);
ctClass.addMethod(setterMethod);
requiredField = true;
} else if(isGetter(method)) {
// getter
CtMethod getterMethod = CtNewMethod.getter(method.getName(), traceVariableType);
ctClass.addMethod(getterMethod);
requiredField = true;
@@ -483,7 +483,7 @@ public class JavaAssistClass implements InstrumentClass {
} else {
interceptor = InterceptorRegistry.findInterceptor(interceptorId);
}
// 이제는 aroundType 인터셉터만 받고 코드 인젝션을 별도 type으로 받아야 함.
if (interceptor instanceof StaticAroundInterceptor) {
switch (type) {
case around:
@@ -531,7 +531,7 @@ public class JavaAssistClass implements InstrumentClass {
}
private void injectInterceptor(CtBehavior behavior, Interceptor interceptor) throws NotFoundException {
// traceContext는 가장먼제 inject되어야 한다.
// First of all, traceContext must be injected.
if (interceptor instanceof TraceContextSupport) {
final TraceContext traceContext = instrumentor.getAgent().getTraceContext();
((TraceContextSupport)interceptor).setTraceContext(traceContext);
@@ -630,12 +630,12 @@ public class JavaAssistClass implements InstrumentClass {
if (useContextClassLoader) {
after.begin();
beginAddFindInterceptorCode(id, after, interceptorType);
// TODO getMethod는 느림 캐쉬로 대체하던가 아니면 추가적인 방안이 필요함.
if (interceptorType == STATIC_INTERCEPTOR) {
after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};");
} else {
after.append(" java.lang.Class[] methodArgsClassParams = new Class[]{java.lang.Object.class, java.lang.Object[].class, java.lang.Object.class, java.lang.Throwable.class};");
}
// TODO need to find better way than reflection because it's slow.
after.format(" java.lang.reflect.Method method = interceptor.getClass().getMethod(\"%1$s\", methodArgsClassParams);", "after");
if (interceptorType == STATIC_INTERCEPTOR) {
after.format(" java.lang.Object[] methodParams = new java.lang.Object[] { %1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null };", target, ctClass.getName(), methodName, parameterTypeString, parameterIdentifier, returnType);
@@ -749,7 +749,8 @@ public class JavaAssistClass implements InstrumentClass {
final String target = getTargetIdentifier(behavior);
final String[] parameterType = JavaAssistUtils.parseParameterSignature(behavior.getSignature());
// 인터셉터 호출시 최대한 연산량을 줄이기 위해서 정보는 가능한 정적 데이터로 생성한다.
// If possible, use static data to reduce interceptor overhead.
String parameterDescription = null;
if (interceptorType == STATIC_INTERCEPTOR) {
parameterDescription = JavaAssistUtils.getParameterDescription(parameterType);
@@ -787,7 +788,7 @@ public class JavaAssistClass implements InstrumentClass {
code.format(" %1$s interceptor = com.navercorp.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id);
code.format(" interceptor.before(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s);", target, ctClass.getName(), methodName, parameterDescription, parameterIdentifier);
} else {
// simpleInterceptor인덱스에서 검색하여 typecasting을 제거한다.
// Separated getInterceptor() with getSimpleInterceptor() to remove type casting cost.
code.format(" %1$s interceptor = com.navercorp.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
code.format(" interceptor.before(%1$s, %2$s);", target, parameterIdentifier);
}
@@ -838,7 +839,7 @@ public class JavaAssistClass implements InstrumentClass {
}
/**
* 제대로 동작안함 다시 봐야 될것 같음. 생성자일경우의 bytecode 수정시 에러가 남.
* Does not work properly. Cannot modify bytecode of constructor
*
* @return
*/
@@ -1021,7 +1022,7 @@ public class JavaAssistClass implements InstrumentClass {
@Override
public void addGetter(String getterName, String variableName, String variableType) throws InstrumentException {
try {
// FIXME getField, getDeclaredField둘 중 뭐가 나을지. 자식 클래스에 getter를 만들려면 getField가 나을 것 같기도 하고.
// FIXME Which is better? getField() or getDeclaredField()? getFiled() seems like better chioce if we want to add getter to child classes.
CtField traceVariable = ctClass.getField(variableName);
CtMethod getterMethod = CtNewMethod.getter(getterName, traceVariable);
ctClass.addMethod(getterMethod);
@@ -51,7 +51,7 @@ public class Slf4jLoggerBinder implements PLoggerBinder {
@Override
public void shutdown() {
// 안해도 될것도 같고. LoggerFactory의unregister만 해도 될려나?
// Maybe we don't need to do this. Unregistering LoggerFactory would be enough.
loggerCache = null;
}
}
@@ -20,7 +20,7 @@ import com.navercorp.pinpoint.bootstrap.logging.PLoggerBinder;
import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
/**
* TestCase용의 쉽게 loggerBinder를 등록삭제할수 있는 api
* For unit test to register/unregister loggerBinder.
*
* @author emeroad
*/
@@ -165,7 +165,7 @@ public class Slf4jPLoggerAdapter implements PLogger {
}
private static String getTarget(Object target) {
// toString의 경우 sideeffect가 발생할수 있으므로 className을 호출하는것으로 변경함.
// Use class name instead of target.toString() becuase latter could cause side effects.
if (target == null) {
return "target=null";
} else {
@@ -194,12 +194,12 @@ public class Slf4jPLoggerAdapter implements PLogger {
}
private static String normalizedParameter(Object arg) {
// toString을 막 호출할 경우 사이드 이펙트가 있을수 있어 수정함.
// Do not call toString() because it could cause some side effects.
if (arg == null) {
return "null";
} else {
// Check if arg is simple type which is safe to invoke toString()
if (isSimpleType(arg)) {
// 안전한 타임에 대해서만 toString을 호출하도록 SimpleType 검사
return arg.toString();
} else {
return arg.getClass().getSimpleName();
@@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentMap;
/**
* concurrent lru cache
* Concurrent LRU cache
* @author emeroad
*/
public class LRUCache<T> {
@@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author emeroad
*/
public class SimpleCache<T> {
// 0인값은 존재 하지 않음을 나타냄.
// zero means not exist.
private final AtomicInteger idGen;
private final ConcurrentMap<T, Result> cache;
@@ -60,7 +60,8 @@ public class SimpleCache<T> {
if (find != null) {
return find;
}
//음수까지 활용하여 가능한 데이터 인코딩을 작게 유지되게 함.
// Use negative values too to reduce data size
final int newId = BytesUtils.zigzagToInt(idGen.getAndIncrement());
final Result result = new Result(false, newId);
final Result before = this.cache.putIfAbsent(value, result);
@@ -91,7 +91,8 @@ import com.navercorp.pinpoint.profiler.modifier.tomcat.WebappLoaderModifier;
*/
public class DefaultModifierRegistry implements ModifierRegistry {
// 왠간해서는 동시성 상황이 안나올것으로 보임. 사이즈를 크게 잡아서 체인을 가능한 뒤지지 않도록함.
// No concurrent issue because only one thread put entries to the map and get operations are started after the map is completely build.
// Set the map size big intentionally to keep hash collision low.
private final Map<String, AbstractModifier> registry = new HashMap<String, AbstractModifier>(512);
private final ByteCodeInstrumentor byteCodeInstrumentor;
@@ -101,7 +102,6 @@ public class DefaultModifierRegistry implements ModifierRegistry {
public DefaultModifierRegistry(Agent agent, ByteCodeInstrumentor byteCodeInstrumentor, ClassFileRetransformer retransformer) {
this.agent = agent;
// classLoader계층 구조 때문에 직접 type을 넣기가 애매하여 그냥 casting
this.byteCodeInstrumentor = byteCodeInstrumentor;
this.retransformer = retransformer;
this.profilerConfig = agent.getProfilerConfig();
@@ -125,14 +125,10 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
public void addConnectorModifier() {
// TODO FilterModifier는 인터페이스라서 변경못할 것으로 보임 확인 필요.
// FilterModifier filterModifier = new FilterModifier(byteCodeInstrumentor, agent);
// addModifier(filterModifier);
HttpClient4Modifier httpClient4Modifier = new HttpClient4Modifier(byteCodeInstrumentor, agent);
addModifier(httpClient4Modifier);
// jdk HTTPUrlConnector
// JDK HTTPUrlConnector
HttpURLConnectionModifier httpURLConnectionModifier = new HttpURLConnectionModifier(byteCodeInstrumentor, agent);
addModifier(httpURLConnectionModifier);
@@ -153,7 +149,7 @@ public class DefaultModifierRegistry implements ModifierRegistry {
final boolean arcus = profilerConfig.isArucs();
boolean memcached;
if (arcus) {
// arcus가 true일 경우 memcached는 자동으로 true가 되야 한다.
// memcached is true if arcus is true.
memcached = true;
} else {
memcached = profilerConfig.isMemcached();
@@ -166,14 +162,14 @@ public class DefaultModifierRegistry implements ModifierRegistry {
MemcachedClientModifier memcachedClientModifier = new MemcachedClientModifier(byteCodeInstrumentor, agent);
addModifier(memcachedClientModifier);
// Not working properly. commented out for now.
// FrontCacheMemcachedClientModifier frontCacheMemcachedClientModifier = new FrontCacheMemcachedClientModifier(byteCodeInstrumentor, agent);
// 관련 수정에 사이드 이펙트가 있이서 일단 disable함.
// addModifier(frontCacheMemcachedClientModifier);
if (arcus) {
ArcusClientModifier arcusClientModifier = new ArcusClientModifier(byteCodeInstrumentor, agent);
addModifier(arcusClientModifier);
// arcus의 Future임
// Future of Arcus
CollectionFutureModifier collectionFutureModifier = new CollectionFutureModifier(byteCodeInstrumentor, agent);
addModifier(collectionFutureModifier);
}
@@ -189,8 +185,8 @@ public class DefaultModifierRegistry implements ModifierRegistry {
OperationFutureModifier operationFutureModifier = new OperationFutureModifier(byteCodeInstrumentor, agent);
addModifier(operationFutureModifier);
// Not working properly. commented out for now.
// FrontCacheGetFutureModifier frontCacheGetFutureModifier = new FrontCacheGetFutureModifier(byteCodeInstrumentor, agent);
// 관련 수정에 사이드 이펙트가 있이서 일단 disable함.
// addModifier(frontCacheGetFutureModifier);
// future modifier end ---------------------------------------------------
@@ -226,7 +222,8 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
public void addJdbcModifier() {
// TODO 드라이버 존재 체크 로직을 앞단으로 이동 시킬수 없는지 검토
// TODO Can we check if JDBC driver exists here?
if (!profilerConfig.isJdbcProfile()) {
return;
}
@@ -252,15 +249,13 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
private void addMySqlDriver() {
// TODO MySqlDriver는 버전별로 Connection interface인지 class인지가 다름. 문제 없는지
// 확인필요.
// TODO In some MySQL drivers Connection is an interface and in the others it's a class. Is this OK?
AbstractModifier mysqlNonRegisteringDriverModifier = new MySQLNonRegisteringDriverModifier(byteCodeInstrumentor, agent);
addModifier(mysqlNonRegisteringDriverModifier);
// Mysql Dirver가 5.0.x에서 5.1.x로 버전업되면서 MySql Driver가 호환성을 깨버려서 호환성 보정작업을 해야함.
// MySql 5.1.x드라이버사용시 Driver가 리턴하는 Connection com.mysql.jdbc.Connection에서 com.mysql.jdbc.JDBC4Connection으로 변경되었음.
// http://devcafe.nhncorp.com/Lucy/forum/342628
// From MySQL driver 5.1.x, backward compatibility is broken.
// Driver returns not com.mysql.jdbc.Connection but com.mysql.jdbc.JDBC4Connection which extends com.mysql.jdbc.ConnectionImpl from 5.1.x
AbstractModifier mysqlConnectionImplModifier = new MySQLConnectionImplModifier(byteCodeInstrumentor, agent);
addModifier(mysqlConnectionImplModifier);
@@ -275,7 +270,8 @@ public class DefaultModifierRegistry implements ModifierRegistry {
MySQLPreparedStatementJDBC4Modifier myqlPreparedStatementJDBC4Modifier = new MySQLPreparedStatementJDBC4Modifier(byteCodeInstrumentor, agent);
addModifier(myqlPreparedStatementJDBC4Modifier);
// result set fectch counter를 만들어야 될듯.
// TODO Need to create result set fetch counter
// Modifier mysqlResultSetModifier = new MySQLResultSetModifier(byteCodeInstrumentor, agent);
// addModifier(mysqlResultSetModifier);
}
@@ -305,8 +301,8 @@ public class DefaultModifierRegistry implements ModifierRegistry {
AbstractModifier oracleDriverModifier = new OracleDriverModifier(byteCodeInstrumentor, agent);
addModifier(oracleDriverModifier);
// TODO PhysicalConnection으로 하니 view에서 api가 phy로 나와 모양이 나쁘다.
// 최상위인 클래스인 T4C T2C, OCI 따로 다 처리하는게 이쁠듯하다.
// TODO Intercepting PhysicalConnection makes view ugly.
// We'd better intercept top-level classes T4C, T2C and OCI each to makes view more readable.
AbstractModifier oracleConnectionModifier = new PhysicalConnectionModifier(byteCodeInstrumentor, agent);
addModifier(oracleConnectionModifier);
@@ -321,7 +317,7 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
private void addCubridDriver() {
// TODO cubrid의 경우도 connection에 대한 impl이 없음. 확인필요.
// TODO Cubrid doesn't have connection impl too. Check it out.
addModifier(new CubridConnectionModifier(byteCodeInstrumentor, agent));
addModifier(new CubridDriverModifier(byteCodeInstrumentor, agent));
addModifier(new CubridStatementModifier(byteCodeInstrumentor, agent));
@@ -332,7 +328,7 @@ public class DefaultModifierRegistry implements ModifierRegistry {
private void addDbcpDriver() {
// TODO cubrid의 경우도 connection에 대한 impl이 없음. 확인필요.
// TODO Cubrid doesn't have connection impl too. Check it out.
AbstractModifier dbcpBasicDataSourceModifier = new DBCPBasicDataSourceModifier(byteCodeInstrumentor, agent);
addModifier(dbcpBasicDataSourceModifier);
@@ -343,7 +339,7 @@ public class DefaultModifierRegistry implements ModifierRegistry {
}
/**
* orm (iBatis, myBatis 등) 지원.
* Support ORM(iBatis, myBatis, etc.)
*/
public void addOrmModifier() {
addIBatisSupport();
@@ -24,7 +24,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin;
/**
* ModifierProvider is a temporary interface to provide additional modifiers to Pinpoint profiler.
* This will be replaced {@link ProfilerPlugin} later.
* This will be replaced by {@link ProfilerPlugin} later.
*
* @deprecated
* @author lioolli
@@ -19,6 +19,9 @@ package com.navercorp.pinpoint.profiler.modifier.arcus;
import java.security.ProtectionDomain;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.navercorp.pinpoint.bootstrap.Agent;
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
@@ -27,14 +30,10 @@ import com.navercorp.pinpoint.bootstrap.instrument.Type;
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
import com.navercorp.pinpoint.bootstrap.interceptor.ParameterExtractorSupport;
import com.navercorp.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
import com.navercorp.pinpoint.profiler.interceptor.bci.*;
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
import com.navercorp.pinpoint.profiler.modifier.arcus.interceptor.ArcusScope;
import com.navercorp.pinpoint.profiler.modifier.arcus.interceptor.IndexParameterExtractor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author netspider
* @author emeroad
@@ -93,8 +92,7 @@ public class ArcusClientModifier extends AbstractModifier {
}
private boolean checkCompatibility(InstrumentClass arcusClient) {
// 하위 memcached class addOp가 있는지 체크
// final boolean addOp = arcusClient.hasMethod("addOp", new String[]{"(Ljava/lang/String;Lnet/spy/memcached/ops/Operation;)Lnet/spy/memcached/ops/Operation;");
// Check if the class has addOp method
final boolean addOp = arcusClient.hasMethod("addOp", new String[]{"java.lang.String", "net.spy.memcached.ops.Operation"}, "net.spy.memcached.ops.Operation");
if (!addOp) {
logger.warn("addOp() not found. skip ArcusClientModifier");
@@ -57,7 +57,7 @@ public class FrontCacheMemcachedClientModifier extends AbstractModifier {
return null;
}
// 모든 public 메소드에 ApiInterceptor를 적용한다.
// Inject ApiInterceptor to all public methods.
final List<MethodInfo> declaredMethods = aClass.getDeclaredMethods(new FrontCacheMemcachedMethodFilter());
for (MethodInfo method : declaredMethods) {
@@ -70,7 +70,7 @@ public class MemcachedClientModifier extends AbstractModifier {
"com.navercorp.pinpoint.profiler.modifier.arcus.interceptor.AddOpInterceptor");
aClass.addInterceptor("addOp", args, addOpInterceptor, Type.before);
// 모든 public 메소드에 ApiInterceptor를 적용한다.
// Inject ApiInterceptor to all public methods.
final List<MethodInfo> declaredMethods = aClass.getDeclaredMethods(new MemcachedMethodFilter());
for (MethodInfo method : declaredMethods) {
@@ -50,7 +50,7 @@ public class BaseOperationCancelInterceptor implements SimpleAroundInterceptor {
}
if (asyncTrace.getState() != DefaultAsyncTrace.STATE_INIT) {
// 이미 동작 완료된 상태임.
// Operation already completed.
return;
}
@@ -53,7 +53,7 @@ public class BaseOperationConstructInterceptor implements SimpleAroundIntercepto
return;
}
// 일단 이벤트가 세지 않는다는 가정하에 별도 timeout처리가 없음.
// Assuming no events are missed, do not process timeout.
// AsyncTrace asyncTrace = trace.createAsyncTrace();
// asyncTrace.markBeforeTime();
//
@@ -68,7 +68,7 @@ public class BaseOperationTransitionStateInterceptor implements SimpleAroundInte
}
return;
}
// TODO null 체크가 필요하지 않나하는데? 일단 사용하지 않는 interceptor이므로 TODO만 붙여 둔다.
// TODO Don't we have to check null? Don't fix now because this interceptor is deprecated.
OperationState newState = (OperationState) args[0];
BaseOperationImpl baseOperation = (BaseOperationImpl) target;
@@ -144,7 +144,8 @@ public class BaseOperationTransitionStateInterceptor implements SimpleAroundInte
if (newState == null) {
return false;
}
// arcus에만 추가된 타입이라. 따로 처리함.
// Check Arcus only state
return "TIMEDOUT".equals(newState.toString());
}
@@ -72,7 +72,7 @@ public class FutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMe
try {
trace.recordApi(methodDescriptor);
// 중요한 파라미터가 아님 레코딩 안함.
// Do not record because it's not important.
// String annotation = "future.get() timeout:" + args[0] + " " + ((TimeUnit)args[1]).name();
// trace.recordAttribute(AnnotationKey.ARCUS_COMMAND, annotation);
@@ -106,7 +106,7 @@ public class FutureGetInterceptor implements SimpleAroundInterceptor, ByteCodeMe
if (op != null) {
trace.recordException(op.getException());
}
// cancel일때 exception은 안던지는 것인가?
// When it's canceled, doen't it throw exception?
// if (op.isCancelled()) {
// trace.recordAttribute(AnnotationKey.EXCEPTION, "cancelled by user");
// }
@@ -133,7 +133,7 @@ public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteC
@Override
public void after(Object target, Object[] args, Object result, Throwable throwable) {
if (isDebug) {
// result는 로깅하지 않는다.
// Do not log result
logger.afterInterceptor(target, args);
}
@@ -150,7 +150,7 @@ public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteC
final com.ning.http.client.Request httpRequest = (com.ning.http.client.Request) args[0];
if (httpRequest != null) {
// httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다.
// Accessing httpRequest here not before() becuase it can cause side effect.
trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getUrl());
String endpoint = getEndpoint(httpRequest.getURI().getHost(), httpRequest.getURI().getPort());
@@ -236,8 +236,8 @@ public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteC
/**
* <pre>
* body는 string, byte, stream, entitywriter 중 하나가 입력된다.
* 여기에서는 stringdata만 수집하고 나머지는 일단 수집 안함.
* Body could be String, byte array, Stream or EntityWriter.
* We collect String data only.
* </pre>
*
* @param httpRequest
@@ -305,8 +305,7 @@ public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteC
} else if (part instanceof com.ning.http.multipart.StringPart) {
com.ning.http.multipart.StringPart p = (com.ning.http.multipart.StringPart) part;
sb.append(part.getName());
// string을 꺼내오는 방법이 없고, apache http client의 adaptation
// class라 무시.
// Ignore value because there's no way to get string value and StringPart is an adaptation class of Apache HTTP client.
sb.append("=STRING");
}
@@ -339,7 +338,7 @@ public class ExecuteRequestInterceptor implements SimpleAroundInterceptor, ByteC
}
/**
* com.ning.http.client.FluentStringsMap.toString()에서 큰따옴표, 공백, 세미콜론을 제거한 버전
* Returns string without double quotations marks, spaces, semi-colons from com.ning.http.client.FluentStringsMap.toString()
*
* @param params
* @param limit
@@ -29,7 +29,7 @@ import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
/**
* HTTP Client 4.3 이상 버전에 있는 클래스.
* For HTTP Client 4.3 or later.
*
* @author netspider
*
@@ -58,7 +58,7 @@ public class ClosableHttpAsyncClientModifier extends AbstractModifier {
InstrumentClass aClass = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
/**
* 아래 두 메소드는 오버로드 되었으나 호출 관계가 없어 scope 없어도 됨.
* Below two methods are overloaded, but they don't call each other. No Scope required.
*/
Interceptor executeInterceptor = byteCodeInstrumentor.newInterceptor(classLoader,
protectedDomain,
@@ -30,7 +30,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Apache httpclient4 modifier (4.2이하 버전에서만 사용 가능)
* Apache httpclient4 modifier (version 4.2 or before)
* <p/>
* <p/>
* <pre>
@@ -134,7 +134,7 @@ public abstract class AbstractHttpRequestExecute implements TraceContextSupport,
@Override
public void after(Object target, Object[] args, Object result, Throwable throwable) {
if (isDebug) {
// result는 로깅하지 않는다.
// Do not log result
logger.afterInterceptor(target, args);
}
@@ -145,7 +145,7 @@ public abstract class AbstractHttpRequestExecute implements TraceContextSupport,
try {
final HttpRequest httpRequest = getHttpRequest(args);
if (httpRequest != null) {
// httpRequest에 뭔가 access하는 작업은 위험이 있으므로 after에서 작업한다.
// Accessing httpRequest here not before() becuase it can cause side effect.
trace.recordAttribute(AnnotationKey.HTTP_URL, httpRequest.getRequestLine().getUri());
final NameIntValuePair<String> host = getHost(args);
if (host != null) {
@@ -191,8 +191,9 @@ public abstract class AbstractHttpRequestExecute implements TraceContextSupport,
if (cookieSampler.isSampling()) {
trace.recordAttribute(AnnotationKey.HTTP_COOKIE, StringUtils.drop(value, 1024));
}
// Cookie값이 2개 이상일수가 있나?
// 밑에서 break 를 쓰니 PMD에서 걸려서 수정함.
// Can a cookie have 2 or more values?
// PMD complains if we use break here
return;
}
}
@@ -258,7 +259,6 @@ public abstract class AbstractHttpRequestExecute implements TraceContextSupport,
int l;
while((l = reader.read(tmp)) != -1) {
buffer.append(tmp, 0, l);
// maxLength 이상 읽었을 경우 stream을 그만 읽는다.
if (buffer.length() >= maxLength) {
break;
}
@@ -109,8 +109,7 @@ public class AsyncInternalClientExecuteInterceptor extends AbstractHttpRequestEx
final org.apache.http.nio.protocol.HttpAsyncRequestProducer producer = (org.apache.http.nio.protocol.HttpAsyncRequestProducer) args[0];
try {
/**
* FIXME org.apache.http.nio.protocol.BasicAsyncRequestProducer.
* generateRequest() 는 문제가 되지 않지만 다른 구현체는 문제가 될 수 있다.
* FIXME Implementations other than org.apache.http.nio.protocol.BasicAsyncRequestProducer.generateRequest() can cause some trouble.
*/
return producer.generateRequest();
} catch (Exception e) {
@@ -29,7 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TODO classloader문제 있음.
* TODO Fix class loader issue.
* @author netspider
*
*/
@@ -56,7 +56,7 @@ public class ConnectMethodInterceptor implements SimpleAroundInterceptor, ByteCo
}
HttpURLConnection request = (HttpURLConnection) target;
// UUID format을 그대로.
final boolean sampling = trace.canSampled();
if (!sampling) {
request.setRequestProperty(Header.HTTP_SAMPLED.toString(), SamplingFlagUtils.SAMPLING_RATE_FALSE);
@@ -85,12 +85,11 @@ public class ConnectMethodInterceptor implements SimpleAroundInterceptor, ByteCo
final String host = url.getHost();
final int port = url.getPort();
// TODO protocol은 어떻게 표기하지???
// TODO How to represent protocol?
String endpoint = getEndpoint(host, port);
// DestinationId와 동일하므로 없는게 맞음.
// trace.recordEndPoint(endpoint);
// Don't record end point because it's same with destination id.
trace.recordDestinationId(endpoint);
trace.recordAttribute(AnnotationKey.HTTP_URL, url.toString());
}
@@ -108,7 +107,7 @@ public class ConnectMethodInterceptor implements SimpleAroundInterceptor, ByteCo
@Override
public void after(Object target, Object[] args, Object result, Throwable throwable) {
if (isDebug) {
// result는 로깅하지 않는다.
// do not log result
logger.afterInterceptor(target, args);
}
@@ -29,8 +29,7 @@ public class DefaultDatabaseInfo implements DatabaseInfo {
private ServiceType type = ServiceType.UNKNOWN_DB;
private ServiceType executeQueryType = ServiceType.UNKNOWN_DB_EXECUTE_QUERY;
private String databaseId;
// 입력된 url을 보정하지 않은 값
private String realUrl;
private String realUrl; // URL before refinement
private String normalizedUrl;
private List<String> host;
private String multipleHost;
@@ -68,7 +67,7 @@ public class DefaultDatabaseInfo implements DatabaseInfo {
@Override
public List<String> getHost() {
// host와 port의 경우 replication 설정등으로 n개가 될수 있어 애매하다.
// With replication, this is not simple because there could be multiple hosts or ports.
return host;
}
@@ -55,7 +55,7 @@ public class JDBCUrlParser {
}
private DatabaseInfo doParse(String url) {
// jdbc 체크
// check jdbc
String lowCaseURL = url.toLowerCase().trim();
if (!lowCaseURL.startsWith("jdbc:")) {
return createUnknownDataBase(url);
@@ -213,7 +213,7 @@ public class StringMaker {
/**
* ch1이나 ch2중 하나가 발견될때까지 역으로 스캔
* Find last ch1 or ch2
* @param ch1
* @param ch2
* @return
@@ -238,7 +238,7 @@ public class StringMaker {
return i-1;
}
}
// 찾지 못함..
// Not found
return -1;
}
@@ -100,7 +100,7 @@ public class CubridConnectionStringParser implements ConnectionStringParser {
final String hostAndPort = host + ":" + portString;
hostList.add(hostAndPort);
// alt host는 제외.
// skip alt host
return new DefaultDatabaseInfo(ServiceType.CUBRID, ServiceType.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, db);
}
@@ -108,11 +108,11 @@ public class CubridConnectionStringParser implements ConnectionStringParser {
/*
private DatabaseInfo parseCubrid(String url) {
// jdbc:cubrid:10.101.57.233:30102:pinpoint:::
// jdbc:cubrid:10.20.30.40:12345:pinpoint:::
StringMaker maker = new StringMaker(url);
maker.after("jdbc:cubrid:");
// 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯.
// mm db? 의 경우도 고려해야 될듯하다.
// 10.11.12.13:3306 In case of replication driver could have multiple values
// We have to consider mm db too.
String host = maker.after("//").before('/').value();
List<String> hostList = new ArrayList<String>(1);
hostList.add(host);
@@ -102,7 +102,7 @@ public class CubridPreparedStatementModifier extends AbstractModifier {
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
}
} catch (NotFoundInstrumentException e) {
// bind variable setter메소드를 못찾을 경우는 그냥 경고만 표시, 에러 아님.
// Cannot find bind variable setter method. This is not an error. Just some log will be enough.
if (logger.isDebugEnabled()) {
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
}
@@ -28,7 +28,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 현재 사용하지 않고 있음. 일단 살려둠.
* Not used anymore.
*
* @author emeroad
*/
public class CubridUStatementModifier extends AbstractModifier {
@@ -35,7 +35,7 @@ public class BindValueUtils {
final int end = length - 1;
for (int i = 0; i < length; i++) {
if (sb.length() >= limit) {
// 드롭된 bindValue를 생략하는 메시지를 첨부하면 bindValue를 통해 바인딩 sql 생성하기가 힘든면이 있으나 없으면 생략인지 아닌지 알수가 없어 수정.
// Appending omission postfix makes generating binded sql difficult. But without this, we cannot say if it's omitted or not.
appendLength(sb, length);
break;
}
@@ -35,7 +35,7 @@ public class ConnectionCloseInterceptor implements SimpleAroundInterceptor {
if (isDebug) {
logger.beforeInterceptor(target, args);
}
// close의 경우 호출이 실패하더라도 데이터를 삭제해야함.
// In case of close, we have to delete data even if the invocation failed.
DatabaseInfoTraceValueUtils.__setTraceDatabaseInfo(target, null);
}
@@ -21,7 +21,7 @@ import com.navercorp.pinpoint.bootstrap.interceptor.*;
import com.navercorp.pinpoint.common.ServiceType;
/**
* Datasource get을 추적해야 될것으로 예상됨.
* Maybe we should trace get of Datasource.
* @author emeroad
*/
public class DataSourceCloseInterceptor extends SpanEventSimpleAroundInterceptor {
@@ -32,23 +32,11 @@ public class DataSourceCloseInterceptor extends SpanEventSimpleAroundInterceptor
super(DataSourceCloseInterceptor.class);
}
// @Override
// protected void prepareBeforeTrace(Object target, Object[] args) {
// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다.
// scope.push();
// }
@Override
public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) {
trace.markBeforeTime();
}
// @Override
// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) {
// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다.
// scope.pop();
// }
@Override
public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) {
trace.recordServiceType(ServiceType.DBCP);
@@ -21,7 +21,7 @@ import com.navercorp.pinpoint.bootstrap.interceptor.*;
import com.navercorp.pinpoint.common.ServiceType;
/**
* Datasource get을 추적해야 될것으로 예상됨.
* Maybe we should trace get of Datasource.
* @author emeroad
*/
public class DataSourceGetConnectionInterceptor extends SpanEventSimpleAroundInterceptor {
@@ -32,31 +32,19 @@ public class DataSourceGetConnectionInterceptor extends SpanEventSimpleAroundInt
super(DataSourceGetConnectionInterceptor.class);
}
// @Override
// protected void prepareBeforeTrace(Object target, Object[] args) {
// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 push만 한다.
// scope.push();
// }
@Override
public void doInBeforeTrace(RecordableTrace trace, final Object target, Object[] args) {
trace.markBeforeTime();
}
// @Override
// protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) {
// // 예외 케이스 : getConnection()에서 Driver.connect()가 호출되는지 알고 싶으므로 pop만 한다.
// scope.pop();
// }
@Override
public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) {
trace.recordServiceType(ServiceType.DBCP);
if (args == null) {
// args == null인 경우 parameter가 없는 getConnection() 호출시
// getConnection() without any arguments
trace.recordApi(getMethodDescriptor());
} else if(args.length == 2) {
// args[1]은 패스워드라서 뺀다.
// skip args[1] because it's a password.
trace.recordApi(getMethodDescriptor(), args[0], 0);
}
trace.recordException(throwable);
@@ -42,14 +42,14 @@ public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptor {
if (scope == null) {
throw new NullPointerException("scope must not be null");
}
// mysql loadbalance 전용옵션 실제 destination은 하위의 구현체에서 레코딩한다.
// option for mysql loadbalance only. Destination is recored at lower implementations.
this.recordConnection = recordConnection;
this.scope = scope;
}
@Override
protected void logBeforeInterceptor(Object target, Object[] args) {
// parameter에 암호가 포함되어 있음 로깅하면 안됨.
// Must not log args because it contains a password
logger.beforeInterceptor(target, null);
}
@@ -71,11 +71,11 @@ public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptor {
@Override
protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) {
// 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음.
// Must not check if current transaction is trace target or not. Connection can be made by other thread.
scope.pop();
final boolean success = InterceptorUtils.isSuccess(throwable);
// 여기서는 trace context인지 아닌지 확인하면 안된다. trace 대상 thread가 아닌곳에서 connection이 생성될수 있음.
// Must not check if current transaction is trace target or not. Connection can be made by other thread.
final String driverUrl = (String) args[0];
DatabaseInfo databaseInfo = createDatabaseInfo(driverUrl);
if (success) {
@@ -90,13 +90,13 @@ public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptor {
if (recordConnection) {
final DatabaseInfo databaseInfo = DatabaseInfoTraceValueUtils.__getTraceDatabaseInfo(result, UnKnownDatabaseInfo.INSTANCE);
// database connect도 매우 무거운 액션이므로 카운트로 친다.
// Count database connect too because it's very heavy operation
trace.recordServiceType(databaseInfo.getExecuteQueryType());
trace.recordEndPoint(databaseInfo.getMultipleHost());
trace.recordDestinationId(databaseInfo.getDatabaseId());
}
final String driverUrl = (String) args[0];
// 여기서 databaseInfo.getRealUrl을 하면 위험하다. loadbalance connection일때 원본 url이 아닌 url이 오게 되어 있음.
// Invoking databaseInfo.getRealUrl() here is dangerous. It doesn't return real URL if it's a loadbalance connection.
trace.recordApiCachedString(getMethodDescriptor(), driverUrl, 0);
trace.recordException(throwable);
@@ -65,7 +65,7 @@ public class PreparedStatementBindVariableInterceptor implements StaticAroundInt
}
Integer index = NumberUtils.toInteger(args[0]);
if (index == null) {
// 어딘가 잘못됨.
// something is wrong
return;
}
String value = BindValueConverter.convert(methodName, args);
@@ -50,7 +50,7 @@ public class PreparedStatementCreateInterceptor extends SpanEventSimpleAroundInt
final boolean success = InterceptorUtils.isSuccess(throwable);
if (success) {
if (target instanceof DatabaseInfoTraceValue) {
// preparedStatement의 생성이 성공하였을 경우만 PreparedStatement에 databaseInfo를 세팅해야 한다.
// set databaeInfo to PreparedStatement only when preparedStatment is generated successfully.
DatabaseInfo databaseInfo = ((DatabaseInfoTraceValue) target).__getTraceDatabaseInfo();
if (databaseInfo != null) {
if (result instanceof DatabaseInfoTraceValue) {
@@ -59,8 +59,8 @@ public class PreparedStatementCreateInterceptor extends SpanEventSimpleAroundInt
}
}
if (result instanceof ParsingResultTraceValue) {
// 1. traceContext를 체크하면 안됨. traceContext에서 즉 같은 thread에서 prearedStatement에서 안만들수도 있음.
// 2. sampling 동작이 동작할 경우 preparedStatement create하는 thread가 trace 대상이 아닐수 있음. 먼제 sql을 저장해야 한다.
// 1. Don't check traceContext. preparedStatement can be created in other thread.
// 2. While sampling is active, the thread which creates preparedStatement could not be a sampling target. So record sql anyway.
String sql = (String) args[0];
ParsingResult parsingResult = getTraceContext().parseSql(sql);
if (parsingResult != null) {
@@ -84,9 +84,10 @@ public class PreparedStatementExecuteQueryInterceptor implements SimpleAroundInt
trace.recordApi(descriptor);
// trace.recordApi(apiId);
// clean 타이밍을 변경해야 될듯 하다.
// clearParameters api가 따로 있으나, 구지 캡쳐 하지 않아도 될듯함.시간남으면 하면 좋기는 함.
// ibatis 등에서 확인해봐도 cleanParameters 의 경우 대부분의 경우 일부러 호출하지 않음.
// Need to change where to invoke clean().
// There is cleanParameters method but it's not necessary to intercept that method.
// iBatis intentionally does not invoke it in most cases.
clean(target);
@@ -130,7 +131,7 @@ public class PreparedStatementExecuteQueryInterceptor implements SimpleAroundInt
}
try {
// TODO 일단 테스트로 실패일경우 종료 아닐경우 resultset fetch까지 계산. fetch count는 옵션으로 빼는게 좋을듯.
// TODO Test if it's success. if failed terminate. else calcaulte resultset fetch too. we'd better make resultset fetch optional.
trace.recordException(throwable);
trace.markAfterTime();
} finally {
@@ -56,7 +56,7 @@ public class StatementExecuteQueryInterceptor extends SpanEventSimpleAroundInter
Object arg = args[0];
if (arg instanceof String) {
trace.recordSqlInfo((String) arg);
// TODO parsing result 추가 처리 고려
// TODO more parsing result processing
}
}
trace.recordException(throwable);
@@ -58,7 +58,7 @@ public class StatementExecuteUpdateInterceptor extends SpanEventSimpleAroundInte
public void doInAfterTrace(RecordableTrace trace, Object target, Object[] args, Object result, Throwable throwable) {
trace.recordException(throwable);
// TODO 결과, 수행시간을.알수 있어야 될듯.
// TODO need to find result, execution time
trace.markAfterTime();
}
@@ -100,7 +100,7 @@ public class JtdsPreparedStatementModifier extends AbstractModifier {
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
}
} catch (NotFoundInstrumentException e) {
// bind variable setter메소드를 못찾을 경우는 그냥 경고만 표시, 에러 아님.
// Cannot find bind variable setter method. This is not an error. logging will be enough.
if (logger.isDebugEnabled()) {
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
}
@@ -57,7 +57,8 @@ public class MySQLConnectionImplModifier extends AbstractModifier {
mysqlConnection.addTraceValue(DatabaseInfoTraceValue.class);
// 해당 Interceptor를 공통클래스 만들경우 system에 로드해야 된다.
// If you want to make this common intercepter class, it has to be loaded to system.
// Interceptor createConnection = new ConnectionCreateInterceptor();
// String[] params = new String[] {
// "java.lang.String", "int", "java.util.Properties", "java.lang.String", "java.lang.String"
@@ -44,7 +44,7 @@ public class MySQLConnectionModifier extends AbstractModifier {
}
public String getTargetClass() {
// mysql의 과거버전의 경우 Connection class에 직접 구현이 되어있다.
// Connection has implementation in old versions of MySQL
return "com/mysql/jdbc/Connection";
}
@@ -55,14 +55,14 @@ public class MySQLConnectionModifier extends AbstractModifier {
try {
InstrumentClass mysqlConnection = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
if (mysqlConnection.isInterface()) {
// 최신버전의 mysql dirver를 사용했을 경우의 호환성 작업.
// Newer version of MySQL
return null;
}
mysqlConnection.addTraceValue(DatabaseInfoTraceValue.class);
// 해당 Interceptor를 공통클래스 만들경우 system에 로드해야 된다.
// If you want to make this common intercepter class, it has to be loaded to system.
// Interceptor createConnection = new ConnectionCreateInterceptor();
// String[] params = new String[] {
// "java.lang.String", "int", "java.util.Properties", "java.lang.String", "java.lang.String"
@@ -57,7 +57,8 @@ public class MySQLNonRegisteringDriverModifier extends AbstractModifier {
String[] params = new String[]{
"java.lang.String", "java.util.Properties"
};
// Driver에서는 scopeInterceptor를 걸면안된다. trace thread가 아닌곳에서 connection이 생성될수 있다.
// Don't use scope at Driver. Connection can be made at thread which is not being traced.
mysqlConnection.addInterceptor("connect", params, createConnection);
if (this.logger.isInfoEnabled()) {
@@ -73,10 +73,11 @@ public class MySQLPreparedStatementJDBC4Modifier extends AbstractModifier {
}
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
// TODO 문자열에 추가로 파라미터 type을 넣어야 될거 같음.
// jdbc 드라이버 마다 구현api가 약간식 차이가 있는데 파라미터 타입이 없을경우, api 판별에 한계가 있음.
// TODO Need to add paramter type to filter arguments
// Cannot specify methods without parameter type information because each JDBC driver has different API.
BindVariableFilter exclude = new IncludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"});
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod(exclude);
// TODO 해당 로직 공통화 필요?
// bci 쪽에 multi api 스펙에 대한 자동으로 인터셉터를 n개 걸어주는 api가 더 좋지 않을까한다.
final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME);
@@ -32,7 +32,7 @@ import java.util.List;
*/
public class MySqlConnectionStringParser implements ConnectionStringParser {
// jdbc:mysql:loadbalance://10.25.141.70:3306,10.25.141.69:3306/MySQL?characterEncoding=UTF-8
// jdbc:mysql:loadbalance://10.22.33.44:3306,10.22.33.55:3306/MySQL?characterEncoding=UTF-8
private static final String JDBC_MYSQL_LOADBALANCE = "jdbc:mysql:loadbalance:";
@Override
@@ -48,14 +48,14 @@ public class MySqlConnectionStringParser implements ConnectionStringParser {
}
private DatabaseInfo parseLoadbalancedUrl(String url) {
// jdbc:mysql://10.98.133.22:3306/test_lucy_db
// jdbc:mysql://1.2.3.4:5678/test_db
StringMaker maker = new StringMaker(url);
maker.after("jdbc:mysql:");
// 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯.
// mm db? 의 경우도 고려해야 될듯하다.
// 1.2.3.4:5678 In case of replication driver could have multiple values
// We have to consider mm db too.
String host = maker.after("//").before('/').value();
// regex cache코드 삭제. 자주 호출되는 api가 아니라 메모리에 안가지고있는게 좋을듯함하다.
// Decided not to cache regex. This is not invoked often so don't waste memory.
String[] parsedHost = host.split(",");
List<String> hostList = Arrays.asList(parsedHost);
@@ -70,11 +70,11 @@ public class MySqlConnectionStringParser implements ConnectionStringParser {
}
private DatabaseInfo parseNormal(String url) {
// jdbc:mysql://10.98.133.22:3306/test_lucy_db
// jdbc:mysql://1.2.3.4:5678/test_db
StringMaker maker = new StringMaker(url);
maker.after("jdbc:mysql:");
// 10.98.133.22:3306 replacation driver같은 경우 n개가 가능할듯.
// mm db? 의 경우도 고려해야 될듯하다.
// 1.2.3.4:5678 In case of replication driver could have multiple values
// We have to consider mm db too.
String host = maker.after("//").before('/').value();
List<String> hostList = new ArrayList<String>(1);
hostList.add(host);