You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/03/22 09:20:14 UTC
[skywalking] branch master updated: Provide HTTP parameter in the
profiling contet (#4546)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new ace781f Provide HTTP parameter in the profiling contet (#4546)
ace781f is described below
commit ace781ff490310de09313f19194281826f9064b0
Author: mrproliu <74...@qq.com>
AuthorDate: Sun Mar 22 17:19:57 2020 +0800
Provide HTTP parameter in the profiling contet (#4546)
* Provide active HTTP parameter collection automatically in the profiling context
* Fix style check
* fix style error
* Add profile status, storage it into TracingContext. simplify to get profiling method
* Change the profile status field name in TracingContext
* Replace gone images
* resolve issues
* resole description issues
Co-authored-by: Mrproliu <mr...@lagou.com>
Co-authored-by: kezhenxu94 <ke...@163.com>
---
.../apm/agent/core/context/ContextManager.java | 1 +
.../apm/agent/core/context/TracingContext.java | 14 ++---
.../apm/agent/core/context/trace/AbstractSpan.java | 5 ++
.../core/context/trace/AbstractTracingSpan.java | 5 ++
.../apm/agent/core/context/trace/NoopSpan.java | 5 ++
.../{ProfilingStatus.java => ProfileStatus.java} | 22 ++++++-
.../agent/core/profile/ProfileStatusReference.java | 69 ++++++++++++++++++++++
.../core/profile/ProfileTaskExecutionContext.java | 23 ++++----
.../core/profile/ProfileTaskExecutionService.java | 12 ++--
.../apm/agent/core/profile/ProfileThread.java | 4 +-
.../apm/agent/core/profile/ThreadProfiler.java | 9 +--
.../interceptor/AbstractMethodInterceptor.java | 21 +++++--
.../plugin/tomcat78x/TomcatInvokeInterceptor.java | 35 +++++++----
.../skywalking/e2e/profile/query/ProfiledSpan.java | 3 +
.../e2e/profile/query/ProfiledSpanMatcher.java | 15 +++++
.../e2e/profile/query/ProfiledSpanTag.java | 15 ++---
...ofiledSpan.java => ProfiledSpanTagMatcher.java} | 25 ++++----
.../src/main/resources/profiledSegment.gql | 3 +
.../apache/skywalking/e2e/profile/ProfileE2E.java | 2 +-
.../resources/expected/profile/profileSegment.yml | 35 +++++++++++
20 files changed, 253 insertions(+), 70 deletions(-)
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
index d609492..0a5a96d 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManager.java
@@ -224,4 +224,5 @@ public class ContextManager implements BootService {
return runtimeContext;
}
+
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
index d73998a..a31145e 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
@@ -39,6 +39,7 @@ import org.apache.skywalking.apm.agent.core.dictionary.DictionaryManager;
import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.agent.core.profile.ProfileStatusReference;
import org.apache.skywalking.apm.agent.core.profile.ProfileTaskExecutionService;
import org.apache.skywalking.apm.agent.core.sampling.SamplingService;
import org.apache.skywalking.apm.util.StringUtil;
@@ -106,9 +107,9 @@ public class TracingContext implements AbstractTracerContext {
private final long createTime;
/**
- * profiling status
+ * profile status
*/
- private volatile boolean profiling;
+ private final ProfileStatusReference profileStatus;
/**
* Initialize all fields with default value.
@@ -128,7 +129,7 @@ public class TracingContext implements AbstractTracerContext {
if (PROFILE_TASK_EXECUTION_SERVICE == null) {
PROFILE_TASK_EXECUTION_SERVICE = ServiceManager.INSTANCE.findService(ProfileTaskExecutionService.class);
}
- this.profiling = PROFILE_TASK_EXECUTION_SERVICE.addProfiling(this, segment.getTraceSegmentId(), firstOPName);
+ this.profileStatus = PROFILE_TASK_EXECUTION_SERVICE.addProfiling(this, segment.getTraceSegmentId(), firstOPName);
}
/**
@@ -521,7 +522,7 @@ public class TracingContext implements AbstractTracerContext {
return;
}
- profiling = PROFILE_TASK_EXECUTION_SERVICE.profilingRecheck(this, segment.getTraceSegmentId(), operationName);
+ PROFILE_TASK_EXECUTION_SERVICE.profilingRecheck(this, segment.getTraceSegmentId(), operationName);
}
/**
@@ -688,8 +689,7 @@ public class TracingContext implements AbstractTracerContext {
return this.createTime;
}
- public boolean isProfiling() {
- return this.profiling;
+ public ProfileStatusReference profileStatus() {
+ return this.profileStatus;
}
-
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
index 88ee212..75946d3 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
@@ -126,4 +126,9 @@ public interface AbstractSpan extends AsyncSpan {
AbstractSpan start(long startTime);
AbstractSpan setPeer(String remotePeer);
+
+ /**
+ * @return true if the span's owner(tracing context main thread) is been profiled.
+ */
+ boolean isProfiling();
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
index fb170ab..001f934 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
@@ -358,4 +358,9 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
isAsyncStopped = true;
return this;
}
+
+ @Override
+ public boolean isProfiling() {
+ return this.owner.profileStatus().isProfiling();
+ }
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
index c08db0e..234af2d 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
@@ -130,6 +130,11 @@ public class NoopSpan implements AbstractSpan {
}
@Override
+ public boolean isProfiling() {
+ return false;
+ }
+
+ @Override
public AbstractSpan prepareForAsync() {
return this;
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatus.java
similarity index 61%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java
copy to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatus.java
index 305b8a8..1fab052 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatus.java
@@ -18,11 +18,29 @@
package org.apache.skywalking.apm.agent.core.profile;
-public enum ProfilingStatus {
+/**
+ * Profile status, include entire profile cycle
+ */
+public enum ProfileStatus {
+ /**
+ * No profile
+ */
+ NONE,
- READY,
+ /**
+ * Prepare to profile, until {@link ProfileTask#getMinDurationThreshold()} reached,
+ * Once the status changed to profiling, the thread snapshot is officially started
+ */
+ PENDING,
+ /**
+ * Profile operation has been started.
+ */
PROFILING,
+ /**
+ * The current {@link org.apache.skywalking.apm.agent.core.context.TracingContext} has finished,
+ * or the current thread isn't available.
+ */
STOPPED
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatusReference.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatusReference.java
new file mode 100644
index 0000000..7d1149f
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileStatusReference.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.profile;
+
+/**
+ * Wrapper {@link ProfileStatus}, make sure {@link org.apache.skywalking.apm.agent.core.context.TracingContext} with {@link ThreadProfiler} have same reference with {@link ProfileStatus},
+ * And only the profile module could change the status
+ */
+public class ProfileStatusReference {
+
+ private volatile ProfileStatus status;
+
+ private ProfileStatusReference(ProfileStatus status) {
+ this.status = status;
+ }
+
+ /**
+ * Create with not watching
+ */
+ public static ProfileStatusReference createWithNone() {
+ return new ProfileStatusReference(ProfileStatus.NONE);
+ }
+
+ /**
+ * Create with pending to profile
+ */
+ public static ProfileStatusReference createWithPending() {
+ return new ProfileStatusReference(ProfileStatus.PENDING);
+ }
+
+ public ProfileStatus get() {
+ return this.status;
+ }
+
+ /**
+ * The profile monitoring is watching, wait for some profile conditions.
+ */
+ public boolean isBeingWatched() {
+ return this.status != ProfileStatus.NONE;
+ }
+
+ public boolean isProfiling() {
+ return this.status == ProfileStatus.PROFILING;
+ }
+
+ /**
+ * Update status, only access with profile module
+ */
+ void updateStatus(ProfileStatus status) {
+ this.status = status;
+ }
+
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java
index bb1949f..d1f5caf 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java
@@ -74,48 +74,49 @@ public class ProfileTaskExecutionContext {
*
* @return is add profile success
*/
- public boolean attemptProfiling(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
+ public ProfileStatusReference attemptProfiling(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
// check has available slot
final int usingSlotCount = currentProfilingCount.get();
if (usingSlotCount >= Config.Profile.MAX_PARALLEL) {
- return false;
+ return ProfileStatusReference.createWithNone();
}
// check first operation name matches
if (!Objects.equals(task.getFistSpanOPName(), firstSpanOPName)) {
- return false;
+ return ProfileStatusReference.createWithNone();
}
// if out limit started profiling count then stop add profiling
if (totalStartedProfilingCount.get() > task.getMaxSamplingCount()) {
- return false;
+ return ProfileStatusReference.createWithNone();
}
// try to occupy slot
if (!currentProfilingCount.compareAndSet(usingSlotCount, usingSlotCount + 1)) {
- return false;
+ return ProfileStatusReference.createWithNone();
}
final ThreadProfiler threadProfiler = new ThreadProfiler(tracingContext, traceSegmentId, Thread.currentThread(), this);
int slotLength = profilingSegmentSlots.length();
for (int slot = 0; slot < slotLength; slot++) {
if (profilingSegmentSlots.compareAndSet(slot, null, threadProfiler)) {
- break;
+ return threadProfiler.profilingStatus();
}
}
- return true;
+ return ProfileStatusReference.createWithNone();
}
/**
* profiling recheck
*/
- public boolean profilingRecheck(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
+ public void profilingRecheck(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
// if started, keep profiling
- if (tracingContext.isProfiling()) {
- return true;
+ if (tracingContext.profileStatus().isBeingWatched()) {
+ return;
}
- return attemptProfiling(tracingContext, traceSegmentId, firstSpanOPName);
+ // update profiling status
+ tracingContext.profileStatus().updateStatus(attemptProfiling(tracingContext, traceSegmentId, firstSpanOPName).get());
}
/**
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionService.java
index afe840e..308b20c 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionService.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionService.java
@@ -91,11 +91,11 @@ public class ProfileTaskExecutionService implements BootService, TracingThreadLi
/**
* check and add {@link TracingContext} profiling
*/
- public boolean addProfiling(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
+ public ProfileStatusReference addProfiling(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
// get current profiling task, check need profiling
final ProfileTaskExecutionContext executionContext = taskExecutionContext.get();
if (executionContext == null) {
- return false;
+ return ProfileStatusReference.createWithNone();
}
return executionContext.attemptProfiling(tracingContext, traceSegmentId, firstSpanOPName);
@@ -104,14 +104,14 @@ public class ProfileTaskExecutionService implements BootService, TracingThreadLi
/**
* Re-check current trace need profiling, in case that third-party plugins change the operation name.
*/
- public boolean profilingRecheck(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
+ public void profilingRecheck(TracingContext tracingContext, ID traceSegmentId, String firstSpanOPName) {
// get current profiling task, check need profiling
final ProfileTaskExecutionContext executionContext = taskExecutionContext.get();
if (executionContext == null) {
- return false;
+ return;
}
- return executionContext.profilingRecheck(tracingContext, traceSegmentId, firstSpanOPName);
+ executionContext.profilingRecheck(tracingContext, traceSegmentId, firstSpanOPName);
}
/**
@@ -247,7 +247,7 @@ public class ProfileTaskExecutionService implements BootService, TracingThreadLi
@Override
public void afterMainThreadFinish(TracingContext tracingContext) {
- if (tracingContext.isProfiling()) {
+ if (tracingContext.profileStatus().isBeingWatched()) {
// stop profiling tracing context
ProfileTaskExecutionContext currentExecutionContext = taskExecutionContext.get();
if (currentExecutionContext != null) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileThread.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileThread.java
index b8c6e44..ba0b7ce 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileThread.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileThread.java
@@ -81,9 +81,9 @@ public class ProfileThread implements Runnable {
continue;
}
- switch (currentProfiler.profilingStatus()) {
+ switch (currentProfiler.profilingStatus().get()) {
- case READY:
+ case PENDING:
// check tracing context running time
currentProfiler.startProfilingIfNeed();
break;
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ThreadProfiler.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ThreadProfiler.java
index b860b36..8587a97 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ThreadProfiler.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ThreadProfiler.java
@@ -42,7 +42,7 @@ public class ThreadProfiler {
private long profilingMaxTimeMills;
// after min duration threshold check, it will start dump
- private ProfilingStatus profilingStatus = ProfilingStatus.READY;
+ private final ProfileStatusReference profilingStatus;
// thread dump sequence
private int dumpSequence = 0;
@@ -52,6 +52,7 @@ public class ThreadProfiler {
this.traceSegmentId = traceSegmentId;
this.profilingThread = profilingThread;
this.executionContext = executionContext;
+ this.profilingStatus = ProfileStatusReference.createWithPending();
this.profilingMaxTimeMills = TimeUnit.MINUTES.toMillis(Config.Profile.MAX_DURATION);
}
@@ -62,7 +63,7 @@ public class ThreadProfiler {
if (System.currentTimeMillis() - tracingContext.createTime() > executionContext.getTask()
.getMinDurationThreshold()) {
this.profilingStartTime = System.currentTimeMillis();
- this.profilingStatus = ProfilingStatus.PROFILING;
+ this.tracingContext.profileStatus().updateStatus(ProfileStatus.PROFILING);
}
}
@@ -70,7 +71,7 @@ public class ThreadProfiler {
* Stop profiling status
*/
public void stopProfiling() {
- this.profilingStatus = ProfilingStatus.STOPPED;
+ this.tracingContext.profileStatus().updateStatus(ProfileStatus.STOPPED);
}
/**
@@ -145,7 +146,7 @@ public class ThreadProfiler {
return tracingContext;
}
- public ProfilingStatus profilingStatus() {
+ public ProfileStatusReference profilingStatus() {
return profilingStatus;
}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java
index 1de75ec..d601067 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java
@@ -109,12 +109,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
SpanLayer.asHttp(span);
if (Config.Plugin.SpringMVC.COLLECT_HTTP_PARAMS) {
- final Map<String, String[]> parameterMap = request.getParameterMap();
- if (parameterMap != null && !parameterMap.isEmpty()) {
- String tagValue = CollectionUtil.toString(parameterMap);
- tagValue = Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD > 0 ? StringUtil.cut(tagValue, Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD) : tagValue;
- Tags.HTTP.PARAMS.set(span, tagValue);
- }
+ collectHttpParam(request, span);
}
stackDepth = new StackDepth();
@@ -185,6 +180,11 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
ContextManager.getRuntimeContext().remove(CONTROLLER_METHOD_STACK_DEPTH);
}
+ // Active HTTP parameter collection automatically in the profiling context.
+ if (!Config.Plugin.SpringMVC.COLLECT_HTTP_PARAMS && span.isProfiling()) {
+ collectHttpParam(request, span);
+ }
+
ContextManager.stopSpan();
}
@@ -196,4 +196,13 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
+
+ private void collectHttpParam(HttpServletRequest request, AbstractSpan span) {
+ final Map<String, String[]> parameterMap = request.getParameterMap();
+ if (parameterMap != null && !parameterMap.isEmpty()) {
+ String tagValue = CollectionUtil.toString(parameterMap);
+ tagValue = Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD > 0 ? StringUtil.cut(tagValue, Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD) : tagValue;
+ Tags.HTTP.PARAMS.set(span, tagValue);
+ }
+ }
}
diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptor.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptor.java
index 3434fdb..aa37060 100644
--- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/TomcatInvokeInterceptor.java
@@ -83,25 +83,14 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
SpanLayer.asHttp(span);
if (Config.Plugin.Tomcat.COLLECT_HTTP_PARAMS) {
- final Map<String, String[]> parameterMap = new HashMap<>();
- final org.apache.coyote.Request coyoteRequest = request.getCoyoteRequest();
- final Parameters parameters = coyoteRequest.getParameters();
- for (final Enumeration<String> names = parameters.getParameterNames(); names.hasMoreElements(); ) {
- final String name = names.nextElement();
- parameterMap.put(name, parameters.getParameterValues(name));
- }
-
- if (!parameterMap.isEmpty()) {
- String tagValue = CollectionUtil.toString(parameterMap);
- tagValue = Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD > 0 ? StringUtil.cut(tagValue, Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD) : tagValue;
- Tags.HTTP.PARAMS.set(span, tagValue);
- }
+ collectHttpParam(request, span);
}
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
+ Request request = (Request) allArguments[0];
HttpServletResponse response = (HttpServletResponse) allArguments[1];
AbstractSpan span = ContextManager.activeSpan();
@@ -109,6 +98,10 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(response.getStatus()));
}
+ // Active HTTP parameter collection automatically in the profiling context.
+ if (!Config.Plugin.Tomcat.COLLECT_HTTP_PARAMS && span.isProfiling()) {
+ collectHttpParam(request, span);
+ }
ContextManager.stopSpan();
ContextManager.getRuntimeContext().remove(Constants.FORWARD_REQUEST_FLAG);
return ret;
@@ -121,4 +114,20 @@ public class TomcatInvokeInterceptor implements InstanceMethodsAroundInterceptor
span.log(t);
span.errorOccurred();
}
+
+ private void collectHttpParam(Request request, AbstractSpan span) {
+ final Map<String, String[]> parameterMap = new HashMap<>();
+ final org.apache.coyote.Request coyoteRequest = request.getCoyoteRequest();
+ final Parameters parameters = coyoteRequest.getParameters();
+ for (final Enumeration<String> names = parameters.getParameterNames(); names.hasMoreElements(); ) {
+ final String name = names.nextElement();
+ parameterMap.put(name, parameters.getParameterValues(name));
+ }
+
+ if (!parameterMap.isEmpty()) {
+ String tagValue = CollectionUtil.toString(parameterMap);
+ tagValue = Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD > 0 ? StringUtil.cut(tagValue, Config.Plugin.Http.HTTP_PARAMS_LENGTH_THRESHOLD) : tagValue;
+ Tags.HTTP.PARAMS.set(span, tagValue);
+ }
+ }
}
diff --git a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java
index 3b7d2a2..b07e00e 100644
--- a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java
+++ b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java
@@ -22,6 +22,8 @@ import com.google.common.primitives.Ints;
import lombok.Data;
import lombok.ToString;
+import java.util.List;
+
@Data
@ToString
public class ProfiledSpan implements Comparable<ProfiledSpan> {
@@ -31,6 +33,7 @@ public class ProfiledSpan implements Comparable<ProfiledSpan> {
private String startTime;
private String endTime;
private String endpointName;
+ private List<ProfiledSpanTag> tags;
@Override
public int compareTo(ProfiledSpan o) {
diff --git a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanMatcher.java b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanMatcher.java
index 71fcf7e..82e244e 100644
--- a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanMatcher.java
+++ b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanMatcher.java
@@ -23,6 +23,11 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@@ -33,6 +38,7 @@ public class ProfiledSpanMatcher extends AbstractMatcher<ProfiledSpan> {
private String startTime;
private String endTime;
private String endpointName;
+ private List<ProfiledSpanTagMatcher> tags;
@Override
public void verify(ProfiledSpan span) {
@@ -42,5 +48,14 @@ public class ProfiledSpanMatcher extends AbstractMatcher<ProfiledSpan> {
doVerify(startTime, span.getStartTime());
doVerify(endTime, span.getEndTime());
doVerify(endpointName, span.getEndpointName());
+
+ assertThat(tags).hasSameSizeAs(span.getTags());
+
+ tags.sort(Comparator.comparing(ProfiledSpanTagMatcher::getKey));
+ span.getTags().sort(Comparator.comparing(ProfiledSpanTag::getKey));
+
+ for (int i = 0; i < tags.size(); i++) {
+ tags.get(i).verify(span.getTags().get(i));
+ }
}
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTag.java
similarity index 81%
rename from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java
rename to test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTag.java
index 305b8a8..62042bf 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfilingStatus.java
+++ b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTag.java
@@ -16,13 +16,14 @@
*
*/
-package org.apache.skywalking.apm.agent.core.profile;
+package org.apache.skywalking.e2e.profile.query;
-public enum ProfilingStatus {
+import lombok.Data;
+import lombok.ToString;
- READY,
-
- PROFILING,
-
- STOPPED
+@Data
+@ToString
+public class ProfiledSpanTag {
+ private String key;
+ private String value;
}
diff --git a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTagMatcher.java
similarity index 64%
copy from test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java
copy to test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTagMatcher.java
index 3b7d2a2..ef44436 100644
--- a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpan.java
+++ b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/profile/query/ProfiledSpanTagMatcher.java
@@ -18,22 +18,25 @@
package org.apache.skywalking.e2e.profile.query;
-import com.google.common.primitives.Ints;
import lombok.Data;
+import lombok.EqualsAndHashCode;
import lombok.ToString;
+import org.apache.skywalking.e2e.verification.AbstractMatcher;
@Data
-@ToString
-public class ProfiledSpan implements Comparable<ProfiledSpan> {
- private String spanId;
- private String parentSpanId;
- private String serviceCode;
- private String startTime;
- private String endTime;
- private String endpointName;
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class ProfiledSpanTagMatcher extends AbstractMatcher<ProfiledSpanTag> {
+ private String key;
+ private String value;
@Override
- public int compareTo(ProfiledSpan o) {
- return Ints.compare(Integer.parseInt(spanId), Integer.parseInt(o.spanId));
+ public void verify(ProfiledSpanTag profiledSpanTag) {
+ if (value == null) {
+ value = "";
+ }
+
+ doVerify(key, profiledSpanTag.getKey());
+ doVerify(value, profiledSpanTag.getValue());
}
}
diff --git a/test/e2e/e2e-data/src/main/resources/profiledSegment.gql b/test/e2e/e2e-data/src/main/resources/profiledSegment.gql
index 164fb84..852c32f 100644
--- a/test/e2e/e2e-data/src/main/resources/profiledSegment.gql
+++ b/test/e2e/e2e-data/src/main/resources/profiledSegment.gql
@@ -18,6 +18,9 @@
segment: getProfiledSegment(segmentId: $segmentId) {
spans {
spanId parentSpanId serviceCode startTime endTime endpointName type peer component isError layer
+ tags {
+ key value
+ }
}
}
}",
diff --git a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/profile/ProfileE2E.java b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/profile/ProfileE2E.java
index 47fa9a6..c143293 100644
--- a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/profile/ProfileE2E.java
+++ b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/profile/ProfileE2E.java
@@ -169,7 +169,7 @@ public class ProfileE2E extends SkyWalkingTestAdapter {
final Map<String, String> user = ImmutableMap.of(
"name", "SkyWalking", "enableProfiling", String.valueOf(needProfiling)
);
- return restTemplate.postForEntity(instrumentedServiceUrl + "/profile/users", user, String.class);
+ return restTemplate.postForEntity(instrumentedServiceUrl + "/profile/users?e2e=true", user, String.class);
}
private void verifyProfiledSegment(String taskId) throws Exception {
diff --git a/test/e2e/e2e-test/src/test/resources/expected/profile/profileSegment.yml b/test/e2e/e2e-test/src/test/resources/expected/profile/profileSegment.yml
index 4499a58..f6646e4 100644
--- a/test/e2e/e2e-test/src/test/resources/expected/profile/profileSegment.yml
+++ b/test/e2e/e2e-test/src/test/resources/expected/profile/profileSegment.yml
@@ -20,27 +20,62 @@ spans:
startTime: gt 0
endTime: gt 0
endpointName: /profile/users
+ tags:
+ - key: url
+ value: not null
+ - key: http.method
+ value: POST
+ - key: http.params
+ value: "e2e=[true]"
- spanId: 1
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/PreparedStatement/executeQuery
+ tags:
+ - key: db.type
+ value: sql
+ - key: db.instance
+ value: testdb
+ - key: db.statement
+ value: "call next value for hibernate_sequence"
- spanId: 2
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/PreparedStatement/executeUpdate
+ tags:
+ - key: db.type
+ value: sql
+ - key: db.instance
+ value: testdb
+ - key: db.statement
+ value: "insert into user (name, id) values (?, ?)"
- spanId: 3
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/Connection/commit
+ tags:
+ - key: db.type
+ value: sql
+ - key: db.instance
+ value: testdb
+ - key: db.statement
+ value:
- spanId: 4
parentSpanId: 0
serviceCode: not null
startTime: gt 0
endTime: gt 0
endpointName: H2/JDBI/Connection/commit
+ tags:
+ - key: db.type
+ value: sql
+ - key: db.instance
+ value: testdb
+ - key: db.statement
+ value: