From a4881f969a23b3f5a636cbcea969b0afb6d7612d Mon Sep 17 00:00:00 2001 From: King Jin Date: Mon, 18 May 2020 18:39:48 +0800 Subject: [PATCH] support export trace info to app for external usage --- agent/src/assembly/component/core.xml | 1 + bootstrap-core/pom.xml | 4 + .../bootstrap/classloader/ProfilerLibs.java | 1 + ...rvletRequestListenerInterceptorHelper.java | 9 ++ .../AgentDirBaseClassPathResolver.java | 3 +- info-export/pom.xml | 52 ++++++++++++ .../pinpoint/export/DefaultTraceInfo.java | 68 +++++++++++++++ .../export/DefaultTraceInfoHolder.java | 69 +++++++++++++++ .../navercorp/pinpoint/export/TraceInfo.java | 53 ++++++++++++ .../export/TraceInfoExportHelper.java | 84 +++++++++++++++++++ .../pinpoint/export/TraceInfoHolder.java | 58 +++++++++++++ pom.xml | 6 ++ 12 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 info-export/pom.xml create mode 100644 info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfo.java create mode 100644 info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfoHolder.java create mode 100644 info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfo.java create mode 100644 info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoExportHelper.java create mode 100644 info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoHolder.java diff --git a/agent/src/assembly/component/core.xml b/agent/src/assembly/component/core.xml index 86690094d3545..f05c9e13684d5 100644 --- a/agent/src/assembly/component/core.xml +++ b/agent/src/assembly/component/core.xml @@ -44,6 +44,7 @@ com.navercorp.pinpoint:pinpoint-annotations com.navercorp.pinpoint:pinpoint-commons + com.navercorp.pinpoint:pinpoint-trace-info-export com.navercorp.pinpoint:pinpoint-bootstrap-core com.navercorp.pinpoint:pinpoint-bootstrap-java7 com.navercorp.pinpoint:pinpoint-bootstrap-java8 diff --git a/bootstrap-core/pom.xml b/bootstrap-core/pom.xml index 4bc6f17394578..79c9fd618d7bf 100644 --- a/bootstrap-core/pom.xml +++ b/bootstrap-core/pom.xml @@ -21,6 +21,10 @@ com.navercorp.pinpoint pinpoint-commons + + com.navercorp.pinpoint + pinpoint-trace-info-export + diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/classloader/ProfilerLibs.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/classloader/ProfilerLibs.java index ac3135bcb22a3..939481e7679dd 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/classloader/ProfilerLibs.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/classloader/ProfilerLibs.java @@ -36,6 +36,7 @@ public class ProfilerLibs { "com.navercorp.pinpoint.io", "com.navercorp.pinpoint.rpc", "com.navercorp.pinpoint.loader.plugins", + "com.navercorp.pinpoint.export", // grpc "com.navercorp.pinpoint.grpc", diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/request/ServletRequestListenerInterceptorHelper.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/request/ServletRequestListenerInterceptorHelper.java index 2e7f606b6e58e..08cd74f4ea94e 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/request/ServletRequestListenerInterceptorHelper.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/request/ServletRequestListenerInterceptorHelper.java @@ -23,6 +23,7 @@ import com.navercorp.pinpoint.bootstrap.context.SpanRecorder; import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.context.TraceId; import com.navercorp.pinpoint.bootstrap.logging.PLogger; import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.RequestRecorderFactory; @@ -33,6 +34,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.request.util.ParameterRecorder; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.common.util.Assert; +import com.navercorp.pinpoint.export.TraceInfoExportHelper; /** * @author jaehong.kim @@ -107,6 +109,10 @@ public void initialized(T request, final ServiceType serviceType, final MethodDe return; } + TraceId traceId = trace.getTraceId(); + if (traceId != null) { + TraceInfoExportHelper.exportTraceInfo(request, traceId.getTransactionId(), traceId.getSpanId()); + } final SpanEventRecorder recorder = trace.traceBlockBegin(); recorder.recordServiceType(serviceType); recorder.recordApi(methodDescriptor); @@ -144,6 +150,9 @@ public void destroyed(T request, final Throwable throwable, final int statusCode return; } + // clear trace info which is put in initialized method + TraceInfoExportHelper.clearExportedTraceInfo(request); + // TODO STATDISABLE this logic was added to disable statistics tracing if (!trace.canSampled()) { traceContext.removeTraceObject(); diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/AgentDirBaseClassPathResolver.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/AgentDirBaseClassPathResolver.java index a6370185f8a39..dacb8ca922c3a 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/AgentDirBaseClassPathResolver.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/agentdir/AgentDirBaseClassPathResolver.java @@ -46,7 +46,8 @@ public class AgentDirBaseClassPathResolver implements ClassPathResolver { private final JarDescription bootstrapJava7 = new JarDescription("pinpoint-bootstrap-java7", false); private final JarDescription bootstrapJava8 = new JarDescription("pinpoint-bootstrap-java8", false); private final JarDescription bootstrapJava9 = new JarDescription("pinpoint-bootstrap-java9", false); - private final List bootJarDescriptions = Arrays.asList(commons, bootstrapCore, annotations, bootstrapJava7, bootstrapJava8, bootstrapJava9); + private final JarDescription traceInfoExport = new JarDescription("pinpoint-trace-info-export", false); + private final List bootJarDescriptions = Arrays.asList(commons, bootstrapCore, annotations, bootstrapJava7, bootstrapJava8, bootstrapJava9, traceInfoExport); private final String classPath; diff --git a/info-export/pom.xml b/info-export/pom.xml new file mode 100644 index 0000000000000..79d2bf1fe26f9 --- /dev/null +++ b/info-export/pom.xml @@ -0,0 +1,52 @@ + + + + + 4.0.0 + + com.navercorp.pinpoint + pinpoint + 2.0.2 + + + pinpoint-trace-info-export + pinpoint-trace-info-export + jar + + + 1.6 + + + + + + maven-compiler-plugin + 3.8.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + + diff --git a/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfo.java b/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfo.java new file mode 100644 index 0000000000000..a0ef8268ca9bd --- /dev/null +++ b/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfo.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.export; + +/** + * @author yjqg6666 + * @since 2020-05-15 14:43:39 + */ +@SuppressWarnings("unused") +public class DefaultTraceInfo implements TraceInfo { + + private String transactionId; + + private long spanId; + + public DefaultTraceInfo(String txId, long spanId) { + setTransactionId(txId); + setSpanId(spanId); + } + + public DefaultTraceInfo() { + } + + @Override + public String getTransactionId() { + return transactionId; + } + + @Override + public void setTransactionId(String txId) { + if (txId == null) { + throw new NullPointerException("TransactionId can NOT be null"); + } + this.transactionId = txId; + } + + @Override + public long getSpanId() { + return spanId; + } + + @Override + public void setSpanId(long spanId) { + this.spanId = spanId; + } + + @Override + public String toString() { + return "DefaultTraceInfo{" + + "transactionId='" + transactionId + '\'' + + ", spanId=" + spanId + + '}'; + } +} \ No newline at end of file diff --git a/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfoHolder.java b/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfoHolder.java new file mode 100644 index 0000000000000..cf781b7e8d04e --- /dev/null +++ b/info-export/src/main/java/com/navercorp/pinpoint/export/DefaultTraceInfoHolder.java @@ -0,0 +1,69 @@ +/* + * Copyright 2020 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.export; + +/** + * @author yjqg6666 + * @since 2020-05-15 14:25:50 + */ +@SuppressWarnings("unused") +public class DefaultTraceInfoHolder implements TraceInfoHolder { + + private static final ThreadLocal HOLDER = new ThreadLocal(); + + @Override + public String getTransactionId() { + TraceInfo traceInfo = getTraceInfo(); + return traceInfo == null ? null : traceInfo.getTransactionId(); + } + + @Override + public long getSpanId() { + TraceInfo traceInfo = getTraceInfo(); + return traceInfo == null ? 0 : traceInfo.getSpanId(); + } + + @Override + public TraceInfo getTraceInfo() { + return HOLDER.get(); + } + + @Override + public void setTraceInfo(TraceInfo traceInfo) { + if (traceInfo == null) { + throw new NullPointerException("TraceInfo can NOT be null"); + } + if (traceInfo.getTransactionId() == null) { + throw new NullPointerException("TraceInfo.transactionId can NOT be null"); + } + HOLDER.set(traceInfo); + } + + public void setTraceInfo(String txId, long spanId) { + HOLDER.set(new DefaultTraceInfo(txId, spanId)); + } + + @Override + public void clearTraceInfo() { + HOLDER.remove(); + } + + @Override + public String toString() { + return "DefaultTraceInfoHolder{data=" + getTraceInfo() + "}"; + } +} diff --git a/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfo.java b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfo.java new file mode 100644 index 0000000000000..e2603c2da2e4d --- /dev/null +++ b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.export; + +/** + * @author yjqg6666 + */ +@SuppressWarnings("unused") +public interface TraceInfo { + + /** + * get transaction id + * + * @return txId + */ + String getTransactionId(); + + /** + * set transaction id + * + * @param txId txId + */ + void setTransactionId(String txId); + + /** + * get span id + * + * @return span id + */ + long getSpanId(); + + /** + * set span id + * + * @param spanId span id + */ + void setSpanId(long spanId); + +} diff --git a/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoExportHelper.java b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoExportHelper.java new file mode 100644 index 0000000000000..ac0580153e05c --- /dev/null +++ b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoExportHelper.java @@ -0,0 +1,84 @@ +/* + * Copyright 2020 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.export; + + +import java.lang.reflect.Method; + +/** + * @author yjqg6666 + */ +@SuppressWarnings("unused") +public class TraceInfoExportHelper { + + public static final String TRACE_INFO_CLZ_NAME = "com.navercorp.pinpoint.export.DefaultTraceInfo"; + public static final String TRACE_INFO_HOLDER_CLZ_NAME = "com.navercorp.pinpoint.export.DefaultTraceInfoHolder"; + + public static void exportTraceInfo(Object appLoadedObject, String transactionId, Long spanId) { + if (transactionId == null || spanId == null) { + return; + } + ClassLoader appClassLoader = getAppClassLoader(appLoadedObject); + if (appClassLoader == null) { + return; + } + + try { + Class traceInfoClass = Class.forName(TRACE_INFO_CLZ_NAME, false, appClassLoader); + Class traceInfoHolderClass = Class.forName(TRACE_INFO_HOLDER_CLZ_NAME, false, appClassLoader); + Object traceInfoObj = traceInfoClass.getDeclaredConstructor().newInstance(); + Method setTxIdMethod = traceInfoClass.getDeclaredMethod("setTransactionId", String.class); + setTxIdMethod.invoke(traceInfoObj, transactionId); + Method setSpanIdMethod = traceInfoClass.getDeclaredMethod("setSpanId", Long.TYPE); + setSpanIdMethod.invoke(traceInfoObj, spanId); + Object traceInfoHolderObj = traceInfoHolderClass.getDeclaredConstructor().newInstance(); + Method setTraceInfoMethod = traceInfoHolderClass.getDeclaredMethod("setTraceInfo", TraceInfo.class); + setTraceInfoMethod.invoke(traceInfoHolderObj, traceInfoObj); + } catch (Throwable t) { + //t.printStackTrace(); + //do nothing even no logging for no introduced dependency + } + } + + private static ClassLoader getAppClassLoader(Object appLoadedObject) { + if (appLoadedObject == null) { + return null; + } + Class targetClass = appLoadedObject.getClass(); + if (targetClass == null) { + return null; + } + return targetClass.getClassLoader(); + } + + public static void clearExportedTraceInfo(Object appLoadedObject) { + ClassLoader appClassLoader = getAppClassLoader(appLoadedObject); + if (appClassLoader == null) { + return; + } + try { + Class traceInfoHolderClass = Class.forName(TRACE_INFO_HOLDER_CLZ_NAME, false, appClassLoader); + Object traceInfoHolderObj = traceInfoHolderClass.getDeclaredConstructor().newInstance(); + Method setTraceInfoMethod = traceInfoHolderClass.getDeclaredMethod("clearTraceInfo"); + setTraceInfoMethod.invoke(traceInfoHolderObj); + } catch (Throwable t) { + //t.printStackTrace(); + //do nothing even no logging for no introduced dependency + } + } + +} diff --git a/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoHolder.java b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoHolder.java new file mode 100644 index 0000000000000..4484b8a805b26 --- /dev/null +++ b/info-export/src/main/java/com/navercorp/pinpoint/export/TraceInfoHolder.java @@ -0,0 +1,58 @@ +/* + * Copyright 2020 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.export; + +/** + * @author yjqg6666 + */ +@SuppressWarnings("unused") +public interface TraceInfoHolder { + + /** + * get transaction in trace info + * + * @return transaction id + */ + String getTransactionId(); + + /** + * get span id in trace info + * + * @return span id + */ + long getSpanId(); + + /** + * get TraceInfo in holder + * + * @return trace info + */ + TraceInfo getTraceInfo(); + + /** + * set the TraceInfo in holder + * + * @param traceInfo traceInfo + */ + void setTraceInfo(TraceInfo traceInfo); + + /** + * clear TraceInfo in holder, should be called after request served. + */ + void clearTraceInfo(); + +} diff --git a/pom.xml b/pom.xml index a7b404002a74d..ee011a04d0eda 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,7 @@ bootstrap-java7 bootstrap-java8 bootstrap-java9 + info-export collector commons commons-buffer @@ -161,6 +162,11 @@ pinpoint-commons ${project.version} + + com.navercorp.pinpoint + pinpoint-trace-info-export + ${project.version} + com.navercorp.pinpoint pinpoint-commons-buffer