diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/AnnotationKey.java b/commons/src/main/java/com/navercorp/pinpoint/common/AnnotationKey.java
index 6e72c3e5b..3dc1aa214 100644
--- a/commons/src/main/java/com/navercorp/pinpoint/common/AnnotationKey.java
+++ b/commons/src/main/java/com/navercorp/pinpoint/common/AnnotationKey.java
@@ -19,6 +19,10 @@ public enum AnnotationKey {
API(12, "API"),
API_METADATA(13, "API-METADATA"),
RETURN_DATA(14, "RETRUN_DATA", true),
+
+ CAll_URL(15, "CALL_URL"),
+ CAll_PARAM(16, "CALL_PARAM", true),
+ PROTOCAL(17, "PROTOCAL", true),
// 정확한 에러 원인을 모를 경우.
ERROR_API_METADATA_ERROR(10000010, "API-METADATA-ERROR"),
diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/ServiceType.java b/commons/src/main/java/com/navercorp/pinpoint/common/ServiceType.java
index d080d96e8..473f935e1 100644
--- a/commons/src/main/java/com/navercorp/pinpoint/common/ServiceType.java
+++ b/commons/src/main/java/com/navercorp/pinpoint/common/ServiceType.java
@@ -53,6 +53,7 @@ public enum ServiceType {
TEST_STAND_ALONE((short) 1005, "TEST_STAND_ALONE", !TERMINAL, RECORD_STATISTICS, !INCLUDE_DESTINATION, NORMAL_SCHEMA),
TOMCAT((short) 1010, "TOMCAT", !TERMINAL, RECORD_STATISTICS, !INCLUDE_DESTINATION, NORMAL_SCHEMA),
BLOC((short) 1020, "BLOC", !TERMINAL, RECORD_STATISTICS, !INCLUDE_DESTINATION, NORMAL_SCHEMA),
+ BLOC_INTERNAL_METHOD((short) 1021, "INTERNAL_METHOD", !TERMINAL, !RECORD_STATISTICS, !INCLUDE_DESTINATION, NORMAL_SCHEMA),
/**
* Database
diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/AnnotationUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/AnnotationUtils.java
index 613cec81a..7ea8a23b1 100644
--- a/commons/src/main/java/com/navercorp/pinpoint/common/util/AnnotationUtils.java
+++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/AnnotationUtils.java
@@ -63,6 +63,10 @@ public class AnnotationUtils {
if (serviceType == ServiceType.HTTP_CLIENT_INTERNAL) {
return findAnnotationBo(list, AnnotationKey.HTTP_CALL_RETRY_COUNT);
}
+
+ if (serviceType == ServiceType.BLOC_INTERNAL_METHOD) {
+ return findAnnotationBo(list, AnnotationKey.CAll_URL);
+ }
// span에 해당하는 Tomcat의 경우 Span에 포함된 rpc 필드를 사용하므로 annotation에서 찾을필요가 없음.
// if (span.getServiceType() == ServiceType.TOMCAT) {
diff --git a/pom.xml b/pom.xml
index 89307ccb9..91ff6ff33 100644
--- a/pom.xml
+++ b/pom.xml
@@ -349,6 +349,11 @@
lucy-bloc-http11
5.5.23
+
+ com.nhncorp.lucy
+ bloc-core
+ 4.0.3
+
diff --git a/profiler/pom.xml b/profiler/pom.xml
index f36373681..f0d6c7ee9 100644
--- a/profiler/pom.xml
+++ b/profiler/pom.xml
@@ -177,6 +177,12 @@
+
+
+ com.nhncorp.lucy
+ bloc-core
+ provided
+
com.ibatis
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java
index d9b26864f..3b4b491fe 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java
@@ -18,12 +18,13 @@ import com.nhn.pinpoint.profiler.modifier.arcus.OperationFutureModifier;
import com.nhn.pinpoint.profiler.modifier.bloc.handler.HTTPHandlerModifier;
import com.nhn.pinpoint.profiler.modifier.bloc4.NettyInboundHandlerModifier;
import com.nhn.pinpoint.profiler.modifier.bloc4.NpcHandlerModifier;
+import com.nhn.pinpoint.profiler.modifier.bloc4.RequestProcessorModifier;
import com.nhn.pinpoint.profiler.modifier.connector.asynchttpclient.AsyncHttpClientModifier;
import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.BasicFutureModifier;
import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.ClosableHttpAsyncClientModifier;
import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.ClosableHttpClientModifier;
-import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.HttpClient4Modifier;
import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.DefaultHttpRequestRetryHandlerModifier;
+import com.nhn.pinpoint.profiler.modifier.connector.httpclient4.HttpClient4Modifier;
import com.nhn.pinpoint.profiler.modifier.connector.jdkhttpconnector.HttpURLConnectionModifier;
import com.nhn.pinpoint.profiler.modifier.connector.lucynet.CompositeInvocationFutureModifier;
import com.nhn.pinpoint.profiler.modifier.connector.lucynet.DefaultInvocationFutureModifier;
@@ -218,6 +219,9 @@ public class DefaultModifierRegistry implements ModifierRegistry {
NpcHandlerModifier npcHandlerModifier = new NpcHandlerModifier(byteCodeInstrumentor, agent);
addModifier(npcHandlerModifier);
+
+ RequestProcessorModifier requestProcessorModifier = new RequestProcessorModifier(byteCodeInstrumentor, agent);
+ addModifier(requestProcessorModifier);
}
public void addTomcatModifier() {
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/RequestProcessorModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/RequestProcessorModifier.java
new file mode 100644
index 000000000..b6dc219fa
--- /dev/null
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/RequestProcessorModifier.java
@@ -0,0 +1,45 @@
+package com.nhn.pinpoint.profiler.modifier.bloc4;
+
+import java.security.ProtectionDomain;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nhn.pinpoint.bootstrap.Agent;
+import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
+import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
+import com.nhn.pinpoint.bootstrap.instrument.InstrumentException;
+import com.nhn.pinpoint.bootstrap.interceptor.Interceptor;
+import com.nhn.pinpoint.profiler.modifier.AbstractModifier;
+
+public class RequestProcessorModifier extends AbstractModifier {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ public RequestProcessorModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
+ super(byteCodeInstrumentor, agent);
+ }
+
+ @Override
+ public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Modifing. {}", javassistClassName);
+ }
+
+ try {
+ InstrumentClass npcHandler = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
+ Interceptor messageReceivedInterceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.modifier.bloc4.interceptor.ProcessInterceptor");
+ npcHandler.addInterceptor("process", new String[] {"com.nhncorp.lucy.bloc.core.processor.BlocRequest"}, messageReceivedInterceptor);
+
+ return npcHandler.toBytecode();
+ } catch (InstrumentException e) {
+ logger.warn("RequestProcessorModifier fail. Caused:", e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public String getTargetClass() {
+ return "com/nhncorp/lucy/bloc/core/processor/RequestProcessor";
+ }
+}
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/interceptor/ProcessInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/interceptor/ProcessInterceptor.java
new file mode 100644
index 000000000..bc2ddff06
--- /dev/null
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/bloc4/interceptor/ProcessInterceptor.java
@@ -0,0 +1,83 @@
+package com.nhn.pinpoint.profiler.modifier.bloc4.interceptor;
+
+import com.nhn.pinpoint.bootstrap.context.Trace;
+import com.nhn.pinpoint.bootstrap.context.TraceContext;
+import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport;
+import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor;
+import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader;
+import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport;
+import com.nhn.pinpoint.bootstrap.logging.PLogger;
+import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory;
+import com.nhn.pinpoint.common.AnnotationKey;
+import com.nhn.pinpoint.common.ServiceType;
+import com.nhncorp.lucy.bloc.core.processor.BlocRequest;
+
+public class ProcessInterceptor implements SimpleAroundInterceptor, ByteCodeMethodDescriptorSupport, TraceContextSupport, TargetClassLoader {
+
+ private final PLogger logger = PLoggerFactory.getLogger(this.getClass());
+ private final boolean isDebug = logger.isDebugEnabled();
+
+ private MethodDescriptor descriptor;
+ private TraceContext traceContext;
+ private ServiceType serviceType = ServiceType.INTERNAL_METHOD;
+
+
+ @Override
+ public void before(Object target, Object[] args) {
+ if (isDebug) {
+ logger.beforeInterceptor(target, args);
+ }
+
+ Trace trace = traceContext.currentTraceObject();
+
+ if (trace == null) {
+ return;
+ }
+
+ trace.traceBlockBegin();
+ trace.markBeforeTime();
+
+ trace.recordServiceType(serviceType);
+ }
+
+ @Override
+ public void after(Object target, Object[] args, Object result, Throwable throwable) {
+ if (isDebug) {
+ logger.afterInterceptor(target, args);
+ }
+
+ Trace trace = traceContext.currentTraceObject();
+
+ if (trace == null) {
+ return;
+ }
+
+ try {
+ trace.recordApi(descriptor);
+ trace.recordException(throwable);
+
+ if (args[0] != null) {
+ BlocRequest blocRequest = (BlocRequest)args[0];
+ trace.recordAttribute(AnnotationKey.CAll_URL, blocRequest.getPath());
+ trace.recordAttribute(AnnotationKey.PROTOCAL, blocRequest.getProtocol());
+ }
+
+ trace.markAfterTime();
+ } finally {
+ trace.traceBlockEnd();
+ }
+ }
+
+ @Override
+ public void setMethodDescriptor(MethodDescriptor descriptor) {
+ this.descriptor = descriptor;
+ this.traceContext.cacheApi(descriptor);
+ }
+
+ @Override
+ public void setTraceContext(TraceContext traceContext) {
+ this.traceContext = traceContext;
+ }
+}
+