From efd9e580d7c369e2caaa87c676c029bf8fe10348 Mon Sep 17 00:00:00 2001 From: wangj881 <857445952@qq.com> Date: Tue, 16 May 2023 18:29:12 +0800 Subject: [PATCH] recoder webinfo --- .../profiles/release/pinpoint-env.config | 14 +- .../config/DefaultThriftTransportConfig.java | 35 +- .../config/ThriftTransportConfig.java | 8 + .../bootstrap/context/SpanRecorder.java | 27 + .../bootstrap/context/TraceContext.java | 11 + .../thrift/ThriftSpanWebInfoHandler.java | 86 + .../receiver/SpanDispatchHandler.java | 13 +- .../applicationContext-collector.xml | 1 + .../common/server/bo/SpanWebInfoBo.java | 266 ++ .../common/server/bo/thrift/SpanFactory.java | 48 +- .../pinpoint/common/PinpointConstants.java | 47 + .../AbstractServerHandleInterceptor.java | 94 +- plugins/spring/pom.xml | 30 + .../spring/web/SpringWebMvcConstants.java | 21 + .../plugin/spring/web/SpringWebMvcPlugin.java | 52 + .../SpringWebMvcTraceMetadataProvider.java | 1 + .../RequestBodyObtainInterceptor.java | 134 ++ .../ResponseBodyObtainInterceptor.java | 141 ++ .../StandardHostValveInvokeInterceptor.java | 94 + ...nnectorsExecuteRootHandlerInterceptor.java | 101 +- .../pinpoint/test/TestSpanStorageFactory.java | 2 +- profiler/pom.xml | 16 + .../context/AsyncSpanChunkFactory.java | 5 + .../context/DefaultBaseTraceFactory.java | 62 +- .../context/DefaultSpanChunkFactory.java | 5 + .../profiler/context/DefaultTraceContext.java | 24 + .../profiler/context/DisableTrace.java | 29 +- .../pinpoint/profiler/context/Span.java | 16 + .../profiler/context/SpanChunkFactory.java | 2 + .../profiler/context/SpanWebInfo.java | 57 + .../pinpoint/profiler/context/WebInfo.java | 198 ++ .../profiler/context/id/DefaultShared.java | 12 + .../pinpoint/profiler/context/id/Shared.java | 4 + .../provider/StorageFactoryProvider.java | 13 +- .../context/recorder/DefaultSpanRecorder.java | 47 + .../recorder/TraceRootSpanRecorder.java | 45 + .../context/storage/BufferedStorage.java | 221 +- .../storage/BufferedStorageFactory.java | 14 +- .../context/storage/LogStorageFactory.java | 7 + .../profiler/context/storage/Storage.java | 7 + .../storage/TraceLogDelegateStorage.java | 7 + .../thrift/SpanThriftMessageConverter.java | 48 +- .../pinpoint/profiler/util/JacksonUtil.java | 36 + .../context/storage/BufferedStorageTest.java | 2 +- .../pinpoint/thrift/dto/TSpanWebInfo.java | 2138 +++++++++++++++++ .../thrift/io/DefaultTBaseLocator.java | 20 +- 46 files changed, 4178 insertions(+), 83 deletions(-) create mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/handler/thrift/ThriftSpanWebInfoHandler.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanWebInfoBo.java create mode 100644 plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/RequestBodyObtainInterceptor.java create mode 100644 plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/ResponseBodyObtainInterceptor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanWebInfo.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/WebInfo.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JacksonUtil.java create mode 100644 thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanWebInfo.java diff --git a/agent/src/main/resources/profiles/release/pinpoint-env.config b/agent/src/main/resources/profiles/release/pinpoint-env.config index 25fb02b50b62..6e9d6e962eb6 100644 --- a/agent/src/main/resources/profiles/release/pinpoint-env.config +++ b/agent/src/main/resources/profiles/release/pinpoint-env.config @@ -1121,4 +1121,16 @@ profiler.jdk.concurrent.completable-future=true # which package of runnable(callable) instance can be thread plugin trace # Set the package name to track # eg) profiler.thread.match.package=com.company.shopping.cart, com.company.payment -profiler.thread.match.package= \ No newline at end of file +profiler.thread.match.package= +########################################################### +# 控制是否进行报文采集 +profiler.spring.web.body=true +# 0 代表全量采集;1 代表正常报文按照采样率,异常报文全量采集;2 代表报文采集按照采样率来走 +profiler.spring.web.body.strategy=0 +# 是否需要通过响应体的某个字段响应码来判定异常 +profiler.spring.web.body.response.judge.enable=true +# 响应字段,严格区分大小写(用来进行异常打标) +profiler.spring.web.body.response.judge.sign=status +# 响应码(用来进行异常打标) +profiler.spring.web.body.response.judge.code=0000 +########################################################### diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultThriftTransportConfig.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultThriftTransportConfig.java index 78db39d8f7d5..499deb0bf172 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultThriftTransportConfig.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultThriftTransportConfig.java @@ -75,6 +75,12 @@ public class DefaultThriftTransportConfig implements ThriftTransportConfig { private static final String DEFAULT_DATA_SENDER_PINPOINT_CLIENT_WRITE_BUFFER_LOW_WATER_MAK = "16m"; private String tcpDataSenderPinpointClientWriteBufferLowWaterMark = DEFAULT_DATA_SENDER_PINPOINT_CLIENT_WRITE_BUFFER_LOW_WATER_MAK; + /** + * 报文异常判断配置 + */ + private boolean responseJudge = false; + private String responseJudgeSign = "status"; + private String responseJudgeCode = "0000"; public DefaultThriftTransportConfig() { } @@ -120,6 +126,10 @@ public void read(DefaultProfilerConfig profilerConfig) { this.tcpDataSenderPinpointClientHandshakeInterval = profilerConfig.readLong("profiler.tcpdatasender.client.handshake.interval", DEFAULT_DATA_SENDER_PINPOINT_CLIENT_HANDSHAKE_INTERVAL); this.tcpDataSenderPinpointClientWriteBufferHighWaterMark = profilerConfig.readString("profiler.tcpdatasender.client.write.buffer.highwatermark", DEFAULT_DATA_SENDER_PINPOINT_CLIENT_WRITE_BUFFER_HIGH_WATER_MAK); this.tcpDataSenderPinpointClientWriteBufferLowWaterMark = profilerConfig.readString("profiler.tcpdatasender.client.write.buffer.lowwatermark", DEFAULT_DATA_SENDER_PINPOINT_CLIENT_WRITE_BUFFER_LOW_WATER_MAK); + + this.responseJudge = profilerConfig.readBoolean("profiler.spring.web.body.response.judge.enable", false); + this.responseJudgeSign = profilerConfig.readString("profiler.spring.web.body.response.judge.sign", "status"); + this.responseJudgeCode = profilerConfig.readString("profiler.spring.web.body.response.judge.code", "0000"); } @Override @@ -292,6 +302,24 @@ public int getStatDataSenderChunkSize() { return statDataSenderChunkSize; } + + + @Override + public boolean isResponseJudge() { + return responseJudge; + } + + @Override + public String getResponseJudgeSign() { + return responseJudgeSign; + } + + @Override + public String getResponseJudgeCode() { + return responseJudgeCode; + } + + @Override public String toString() { return "DefaultThriftTransportConfig{" + @@ -327,8 +355,11 @@ public String toString() { ", tcpDataSenderPinpointClientReconnectInterval=" + tcpDataSenderPinpointClientReconnectInterval + ", tcpDataSenderPinpointClientPingInterval=" + tcpDataSenderPinpointClientPingInterval + ", tcpDataSenderPinpointClientHandshakeInterval=" + tcpDataSenderPinpointClientHandshakeInterval + - ", tcpDataSenderPinpointClientWriteBufferHighWaterMark=" + tcpDataSenderPinpointClientWriteBufferHighWaterMark + - ", tcpDataSenderPinpointClientWriteBufferLowWaterMark=" + tcpDataSenderPinpointClientWriteBufferLowWaterMark + + ", tcpDataSenderPinpointClientWriteBufferHighWaterMark='" + tcpDataSenderPinpointClientWriteBufferHighWaterMark + '\'' + + ", tcpDataSenderPinpointClientWriteBufferLowWaterMark='" + tcpDataSenderPinpointClientWriteBufferLowWaterMark + '\'' + + ", responseJudge=" + responseJudge + + ", responseJudgeSign='" + responseJudgeSign + '\'' + + ", responseJudgeCode='" + responseJudgeCode + '\'' + '}'; } } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ThriftTransportConfig.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ThriftTransportConfig.java index 54c9c53e067e..73c55146ed2d 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ThriftTransportConfig.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ThriftTransportConfig.java @@ -93,4 +93,12 @@ public interface ThriftTransportConfig { int getStatDataSenderChunkSize(); + /** + * 报文异常判断相关 + */ + boolean isResponseJudge(); + + String getResponseJudgeSign(); + + String getResponseJudgeCode(); } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/SpanRecorder.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/SpanRecorder.java index 29caaec2ab08..f5039e887517 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/SpanRecorder.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/SpanRecorder.java @@ -53,4 +53,31 @@ public interface SpanRecorder extends FrameAttachment { void recordLogging(LoggingInfo loggingInfo); void recordStatusCode(int statusCode); + + void recordWebInfoRequestUrl(String requestUrl); + + void recordWebInfoRequestBody(Object requestBody); + + void recordWebInfoRequestHeader(Object requestHeader); + + void recordWebInfoResponseBody(Object responseBody); + + void recordWebInfoResponseHeader(Object responseHeader); + + void recordWebInfoRequestMethod(String requestMethod); + + void recordWebInfoStatusCode(int statusCode); + + /** + * 判断是否已经进行了请求体的采集 + * @return + */ + boolean requestBodyTraced(); + + /** + * 记录报文采样策略 + * @param strategy + */ + void recordWebInfoStrategy(byte strategy); + } \ No newline at end of file diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java index fd3d6053d579..312dfc5896e2 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java @@ -98,4 +98,15 @@ public interface TraceContext { JdbcContext getJdbcContext(); + /** + * 是否做报文采集 + * @return + */ + boolean bodyObtainEnable(); + + /** + * 报文采样策略 + * @return + */ + byte bodyObtainStrategy(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/thrift/ThriftSpanWebInfoHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/thrift/ThriftSpanWebInfoHandler.java new file mode 100644 index 000000000000..3f87537e820f --- /dev/null +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/thrift/ThriftSpanWebInfoHandler.java @@ -0,0 +1,86 @@ +/* + * Copyright 2018 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.collector.handler.thrift; + +import com.navercorp.pinpoint.collector.handler.SimpleHandler; +import com.navercorp.pinpoint.collector.sample.Sample; +import com.navercorp.pinpoint.collector.service.TraceService; +import com.navercorp.pinpoint.common.server.bo.SpanWebInfoBo; +import com.navercorp.pinpoint.common.server.bo.thrift.SpanFactory; +import com.navercorp.pinpoint.io.request.ServerRequest; +import com.navercorp.pinpoint.kafka.KafkaProducerGroup; +import com.navercorp.pinpoint.kafka.KafkaProducerManager; +import com.navercorp.pinpoint.thrift.dto.TSpanWebInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/** + * @author emeroad + */ +@Service +public class ThriftSpanWebInfoHandler implements SimpleHandler { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final TraceService traceService; + + private final SpanFactory spanFactory; + + @Autowired + private Sample sampleService; + + private KafkaProducerGroup kafkaProducerGroup = KafkaProducerManager.getGroup("spanwebinfo"); + + + public ThriftSpanWebInfoHandler(TraceService traceService, SpanFactory spanFactory) { + this.traceService = Objects.requireNonNull(traceService, "traceService"); + this.spanFactory = Objects.requireNonNull(spanFactory, "spanFactory"); + } + + @Override + public void handleSimple(ServerRequest serverRequest) { + final Object data = serverRequest.getData(); + if (logger.isDebugEnabled()) { + logger.debug("Handle simple data={}", data); + } + if (data instanceof TSpanWebInfo) { + handleSpanWebInfo((TSpanWebInfo) data); + } else { + throw new UnsupportedOperationException("data is not support type : " + data); + } + } + + private void handleSpanWebInfo(TSpanWebInfo tbase) { + try { + final SpanWebInfoBo spanWebInfoBo = this.spanFactory.buildSpanWebInfoBo(tbase); + if(sampleService.getKafkaFlag()) { + if (sampleService.sample(spanWebInfoBo.getTransactionId().hashCode())) { + if (kafkaProducerGroup == null) { + kafkaProducerGroup = KafkaProducerManager.getGroup("spanwebinfo"); + } + kafkaProducerGroup.put(spanWebInfoBo); + } + } + } catch (Exception e) { + logger.warn("Failed to handle SpanWebInfo={}, Caused={}", tbase, e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/SpanDispatchHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/SpanDispatchHandler.java index bd82119ced1f..d16fec0dbb29 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/SpanDispatchHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/receiver/SpanDispatchHandler.java @@ -32,11 +32,20 @@ public class SpanDispatchHandler implements DispatchHandler { private final SimpleHandler spanDataHandler; private final SimpleHandler spanChunkHandler; - + + private final SimpleHandler spanWebInfoHandler; + + + public SpanDispatchHandler(SimpleHandler spanDataHandler, SimpleHandler spanChunkHandler, SimpleHandler spanWebInfoHandler) { + this.spanDataHandler = Objects.requireNonNull(spanDataHandler, "spanDataHandler"); + this.spanChunkHandler = Objects.requireNonNull(spanChunkHandler, "spanChunkHandler"); + this.spanWebInfoHandler = Objects.requireNonNull(spanWebInfoHandler, "spanWebInfoHandler"); + } public SpanDispatchHandler(SimpleHandler spanDataHandler, SimpleHandler spanChunkHandler) { this.spanDataHandler = Objects.requireNonNull(spanDataHandler, "spanDataHandler"); this.spanChunkHandler = Objects.requireNonNull(spanChunkHandler, "spanChunkHandler"); + this.spanWebInfoHandler = null; } private SimpleHandler getSimpleHandler(Header header) { @@ -46,6 +55,8 @@ private SimpleHandler getSimpleHandler(Header header) { return spanDataHandler; case DefaultTBaseLocator.SPANCHUNK: return spanChunkHandler; + case DefaultTBaseLocator.SPAN_WEB_INFO: + return spanWebInfoHandler; } throw new UnsupportedOperationException("unsupported header:" + header); } diff --git a/collector/src/main/resources/applicationContext-collector.xml b/collector/src/main/resources/applicationContext-collector.xml index a990e1ac3a35..2cb9d8849643 100644 --- a/collector/src/main/resources/applicationContext-collector.xml +++ b/collector/src/main/resources/applicationContext-collector.xml @@ -133,6 +133,7 @@ + diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanWebInfoBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanWebInfoBo.java new file mode 100644 index 000000000000..4fcf3d892d72 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanWebInfoBo.java @@ -0,0 +1,266 @@ +/* + * Copyright 2019 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.common.server.bo; + +import com.navercorp.pinpoint.common.profiler.util.TransactionId; + + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanWebInfoBo implements BasicSpan { + + private byte version = 0; + + private String agentId; + private String applicationId; + private long agentStartTime; + + private TransactionId transactionId; + + private long spanId; + private long parentSpanId; + private String requestBody; + private String requestUrl; + private String requestHeader; + private String responseBody; + private String responseHeader; + private long collectorAcceptTime; + + private String parentApplicationName; + + /** + * 报文异常标志 + */ + private byte busiCode; + /** + * 请求方法 + */ + private String requestMethod; + /** + * 响应码 + */ + private int statusCode; + /** + * 采样策略 + */ + private byte httpMsgStrategy; + + /** + * 耗时 + */ + private int elapsedTime; + + + + public SpanWebInfoBo() { + } + + @Override + public int getVersion() { + return version & 0xFF; + } + + public void setVersion(int version) { + SpanBo.checkVersion(version); + // check range + this.version = (byte) (version & 0xFF); + } + + @Override + public String getAgentId() { + return agentId; + } + + @Override + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + @Override + public String getApplicationId() { + return applicationId; + } + + @Override + public void setApplicationId(String applicationId) { + this.applicationId = applicationId; + } + + @Override + public long getAgentStartTime() { + return agentStartTime; + } + + @Override + public void setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + } + + @Override + public TransactionId getTransactionId() { + return transactionId; + } + + public void setTransactionId(TransactionId transactionId) { + this.transactionId = transactionId; + } + + @Override + public long getSpanId() { + return spanId; + } + + @Override + public void setSpanId(long spanId) { + this.spanId = spanId; + } + + + public String getRequestBody() { + return requestBody; + } + + public void setRequestBody(String requestBody) { + this.requestBody = requestBody; + } + + public String getRequestUrl() { + return requestUrl; + } + + public void setRequestUrl(String requestUrl) { + this.requestUrl = requestUrl; + } + + public String getRequestHeader() { + return requestHeader; + } + + public void setRequestHeader(String requestHeader) { + this.requestHeader = requestHeader; + } + + public String getResponseBody() { + return responseBody; + } + + public void setResponseBody(String responseBody) { + this.responseBody = responseBody; + } + + public String getResponseHeader() { + return responseHeader; + } + + public void setResponseHeader(String responseHeader) { + this.responseHeader = responseHeader; + } + + public long getCollectorAcceptTime() { + return collectorAcceptTime; + } + + public void setCollectorAcceptTime(long collectorAcceptTime) { + this.collectorAcceptTime = collectorAcceptTime; + } + + public long getParentSpanId() { + return parentSpanId; + } + + public void setParentSpanId(long parentSpanId) { + this.parentSpanId = parentSpanId; + } + + public void setVersion(byte version) { + this.version = version; + } + + public String getRequestMethod() { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) { + this.requestMethod = requestMethod; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public byte getHttpMsgStrategy() { + return httpMsgStrategy; + } + + public void setHttpMsgStrategy(byte httpMsgStrategy) { + this.httpMsgStrategy = httpMsgStrategy; + } + + public byte getBusiCode() { + return busiCode; + } + + public void setBusiCode(byte busiCode) { + this.busiCode = busiCode; + } + + public int getElapsedTime() { + return elapsedTime; + } + + public void setElapsedTime(int elapsedTime) { + this.elapsedTime = elapsedTime; + } + + public String getParentApplicationName() { + return parentApplicationName; + } + + public void setParentApplicationName(String parentApplicationName) { + this.parentApplicationName = parentApplicationName; + } + + @Override + public String toString() { + return "SpanWebInfoBo{" + + "version=" + version + + ", agentId='" + agentId + '\'' + + ", applicationId='" + applicationId + '\'' + + ", agentStartTime=" + agentStartTime + + ", transactionId=" + transactionId + + ", spanId=" + spanId + + ", parentSpanId=" + parentSpanId + + ", requestBody='" + requestBody + '\'' + + ", requestUrl='" + requestUrl + '\'' + + ", requestHeader='" + requestHeader + '\'' + + ", responseBody='" + responseBody + '\'' + + ", responseHeader='" + responseHeader + '\'' + + ", collectorAcceptTime=" + collectorAcceptTime + + ", parentApplicationName='" + parentApplicationName + '\'' + + ", busiCode=" + busiCode + + ", requestMethod='" + requestMethod + '\'' + + ", statusCode=" + statusCode + + ", httpMsgStrategy=" + httpMsgStrategy + + ", elapsedTime=" + elapsedTime + + '}'; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/thrift/SpanFactory.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/thrift/SpanFactory.java index c53e2c952d1a..469ba802131d 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/thrift/SpanFactory.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/thrift/SpanFactory.java @@ -18,26 +18,14 @@ import com.google.common.annotations.VisibleForTesting; -import com.navercorp.pinpoint.common.server.bo.AnnotationBo; -import com.navercorp.pinpoint.common.server.bo.AnnotationComparator; -import com.navercorp.pinpoint.common.server.bo.AnnotationFactory; -import com.navercorp.pinpoint.common.server.bo.LocalAsyncIdBo; -import com.navercorp.pinpoint.common.server.bo.SpanBo; -import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; -import com.navercorp.pinpoint.common.server.bo.SpanEventBo; -import com.navercorp.pinpoint.common.server.bo.SpanEventComparator; +import com.navercorp.pinpoint.common.server.bo.*; import com.navercorp.pinpoint.common.server.bo.filter.EmptySpanEventFilter; import com.navercorp.pinpoint.common.server.bo.filter.SpanEventFilter; import com.navercorp.pinpoint.common.server.util.AcceptedTimeService; import com.navercorp.pinpoint.common.server.util.EmptyAcceptedTimeService; import com.navercorp.pinpoint.common.profiler.util.TransactionId; import com.navercorp.pinpoint.common.profiler.util.TransactionIdUtils; -import com.navercorp.pinpoint.thrift.dto.TAnnotation; -import com.navercorp.pinpoint.thrift.dto.TIntStringValue; -import com.navercorp.pinpoint.thrift.dto.TLocalAsyncId; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; +import com.navercorp.pinpoint.thrift.dto.*; import org.apache.commons.collections.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -388,4 +376,36 @@ private AnnotationBo newAnnotationBo(TAnnotation tAnnotation) { return annotationBo; } + public SpanWebInfoBo buildSpanWebInfoBo(TSpanWebInfo tSpanWebInfo) { + final SpanWebInfoBo spanWebInfoBo = newSpanWebInfoBo(tSpanWebInfo); + long acceptedTime = acceptedTimeService.getAcceptedTime(); + spanWebInfoBo.setCollectorAcceptTime(acceptedTime); + return spanWebInfoBo; + } + + private SpanWebInfoBo newSpanWebInfoBo(TSpanWebInfo tSpanWebInfo) { + final SpanWebInfoBo spanWebInfoBo = new SpanWebInfoBo(); + spanWebInfoBo.setAgentId(tSpanWebInfo.getAgentId()); + spanWebInfoBo.setApplicationId(tSpanWebInfo.getApplicationName()); + spanWebInfoBo.setAgentStartTime(tSpanWebInfo.getAgentStartTime()); + + final TransactionId transactionId = newTransactionId(tSpanWebInfo.getTransactionId(), tSpanWebInfo.getAgentId()); + spanWebInfoBo.setTransactionId(transactionId); + + spanWebInfoBo.setSpanId(tSpanWebInfo.getSpanId()); + spanWebInfoBo.setParentSpanId(tSpanWebInfo.getParentSpanId()); + spanWebInfoBo.setRequestBody(tSpanWebInfo.getRequestBody()); + spanWebInfoBo.setRequestUrl(tSpanWebInfo.getRequestUrl()); + spanWebInfoBo.setRequestHeader(tSpanWebInfo.getRequestHeader()); + spanWebInfoBo.setResponseBody(tSpanWebInfo.getResponseBody()); + spanWebInfoBo.setResponseHeader(tSpanWebInfo.getResponseHeader()); + spanWebInfoBo.setBusiCode(tSpanWebInfo.getStatus()); + spanWebInfoBo.setHttpMsgStrategy(tSpanWebInfo.getWebBodyStrategy()); + spanWebInfoBo.setRequestMethod(tSpanWebInfo.getRequestMethod()); + spanWebInfoBo.setStatusCode(tSpanWebInfo.getStatusCode()); + spanWebInfoBo.setElapsedTime(tSpanWebInfo.getElapsedTime()); + spanWebInfoBo.setParentApplicationName(tSpanWebInfo.getParentApplicationName()); + + return spanWebInfoBo; + } } diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/PinpointConstants.java b/commons/src/main/java/com/navercorp/pinpoint/common/PinpointConstants.java index 4946e1b57b34..2fd72cc66dd1 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/PinpointConstants.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/PinpointConstants.java @@ -16,6 +16,10 @@ package com.navercorp.pinpoint.common; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + /** * @author emeroad */ @@ -25,4 +29,47 @@ public final class PinpointConstants { public static final int AGENT_NAME_MAX_LEN = 24; + public static final String EMPTY_STRING = ""; + + /** + * 正常响应码的取值区间 + */ + public static final int STATUS_CODE_200 = 200; + public static final int STATUS_CODE_299 = 299; + + /** + * 采样策略 + * # 0 代表全量采集;1 代表正常报文按照采样率,异常报文全量采集;2 代表报文采集按照采样率来走 + */ + public static final byte STRATEGY_0 = 0; + public static final byte STRATEGY_1 = 1; + public static final byte STRATEGY_2 = 2; + + + /** + * 报文状态标志: + * 0代表正常,1代表异常,2代表未知 + */ + public static final byte WEBINFO_STATUS_NORMAL = 0; + public static final byte WEBINFO_STATUS_ABNORMAL = 1; + public static final byte WEBINFO_STATUS_UNKNOWN = 2; + + /** + * 报文长度限制相关 + */ + public static final Map RESPONSE_BODY_LENGTH_LIMIT_MAP = Collections.unmodifiableMap(unmodifiableMap("报文长度超出限制(52kB),采集截取前10240个字符。")); + public static final Map REQUEST_BODY_LENGTH_LIMIT_MAP = Collections.unmodifiableMap(unmodifiableMap("报文长度超出限制(20kB),采集截取前10240个字符。")); + + public static final String REQUEST_BODY = "requestBody"; + public static final String RESPONSE_BODY = "responseBody"; + + public static final Integer REQUEST_BODY_LENGTH_LIMIT = 20480; + public static final Integer RESPONSE_BODY_LENGTH_LIMIT = 53248; + public static final Integer BODY_LIMIT_LENGTH = 10240; + + private static Map unmodifiableMap(String limitInfo) { + Map map = new HashMap(1); + map.put("limitInfo", limitInfo); + return map; + } } diff --git a/plugins/jetty/src/main/java/com/navercorp/pinpoint/plugin/jetty/interceptor/AbstractServerHandleInterceptor.java b/plugins/jetty/src/main/java/com/navercorp/pinpoint/plugin/jetty/interceptor/AbstractServerHandleInterceptor.java index 0b861d65736e..3569ad2b5ff2 100644 --- a/plugins/jetty/src/main/java/com/navercorp/pinpoint/plugin/jetty/interceptor/AbstractServerHandleInterceptor.java +++ b/plugins/jetty/src/main/java/com/navercorp/pinpoint/plugin/jetty/interceptor/AbstractServerHandleInterceptor.java @@ -25,6 +25,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.request.ServletRequestListenerInterceptorHelper; import com.navercorp.pinpoint.bootstrap.plugin.request.util.ParameterRecorder; import com.navercorp.pinpoint.bootstrap.plugin.request.util.RemoteAddressResolverFactory; +import com.navercorp.pinpoint.common.PinpointConstants; import com.navercorp.pinpoint.plugin.common.servlet.util.HttpServletRequestAdaptor; import com.navercorp.pinpoint.plugin.common.servlet.util.ParameterRecorderFactory; import com.navercorp.pinpoint.plugin.jetty.JettyConfiguration; @@ -33,6 +34,10 @@ import javax.servlet.DispatcherType; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; /** * @author Chaein Jung @@ -43,6 +48,7 @@ public abstract class AbstractServerHandleInterceptor implements AroundIntercept private final boolean isDebug = logger.isDebugEnabled(); private final boolean isInfo = logger.isInfoEnabled(); + private final TraceContext traceContext; private final MethodDescriptor methodDescriptor; private final ServletRequestListenerInterceptorHelper servletRequestListenerInterceptorHelper; @@ -55,6 +61,7 @@ public AbstractServerHandleInterceptor(TraceContext traceContext, MethodDescript requestRequestAdaptor = RemoteAddressResolverFactory.wrapRealIpSupport(requestRequestAdaptor, config.getRealIpHeader(), config.getRealIpEmptyValue()); ParameterRecorder parameterRecorder = ParameterRecorderFactory.newParameterRecorderFactory(config.getExcludeProfileMethodFilter(), config.isTraceRequestParam()); this.servletRequestListenerInterceptorHelper = new ServletRequestListenerInterceptorHelper(JettyConstants.JETTY, traceContext, requestRequestAdaptor, config.getExcludeUrlFilter(), parameterRecorder, requestRecorderFactory); + this.traceContext = traceContext; } abstract HttpServletRequest toHttpServletRequest(Object[] args); @@ -90,13 +97,27 @@ public void after(Object target, Object[] args, Object result, Throwable throwab try { final HttpServletRequest request = toHttpServletRequest(args); final HttpServletResponse response = toHttpServletResponse(args); + final int statusCode = getStatusCode(response); if (request.getDispatcherType() == DispatcherType.ASYNC || request.getDispatcherType() == DispatcherType.ERROR) { if (isDebug) { logger.debug("Skip async servlet request event. isAsyncStarted={}, dispatcherType={}", request.isAsyncStarted(), request.getDispatcherType()); } return; } - final int statusCode = getStatusCode(response); + + Trace trace = traceContext.currentTraceObject(); + if (null != trace) { + recorderWebInfo(trace, request, response, statusCode); + + } else if (traceContext.bodyObtainEnable() && traceContext.bodyObtainStrategy() < PinpointConstants.STRATEGY_2) { + // 此处代表被采样率过滤掉的trace,同时采样策略需要采集此部分调用报文 + Trace rawTraceObject = traceContext.currentRawTraceObject(); + if (null != rawTraceObject) { + recorderWebInfo(rawTraceObject, request, response, statusCode); + } + + } + this.servletRequestListenerInterceptorHelper.destroyed(request, throwable, statusCode); } catch (Throwable t) { if (isInfo) { @@ -105,6 +126,31 @@ public void after(Object target, Object[] args, Object result, Throwable throwab } } + /** + * 采集报文信息 + * + * @param trace + * @param request + * @param response + * @param statusCode + */ + private void recorderWebInfo(Trace trace, HttpServletRequest request, HttpServletResponse response, int statusCode) { + try { + SpanRecorder spanRecorder = trace.getSpanRecorder(); + if (null != spanRecorder) { + // 采集请求/响应头========================== + if (traceContext.bodyObtainEnable()) { + headerObtain(request, response, spanRecorder, statusCode); + } + // ========================================= + } + } catch (Throwable t) { + if (isInfo) { + logger.info("采集报文报错,异常信息:", t); + } + } + } + private int getStatusCode(final HttpServletResponse response) { try { return response.getStatus(); @@ -112,4 +158,50 @@ private int getStatusCode(final HttpServletResponse response) { } return 0; } + + /** + * 采集请求头、响应头、请求url + * + * @param request 请求 + * @param response 响应 + * @param spanRecorder 采集器 + * @param statusCode + */ + private void headerObtain(HttpServletRequest request, HttpServletResponse response, SpanRecorder spanRecorder, int statusCode) { + + // 赋值采样策略 + spanRecorder.recordWebInfoStrategy(traceContext.bodyObtainStrategy()); + + // 采集请求方式 + spanRecorder.recordWebInfoRequestMethod(request.getMethod()); + + // 采集响应码 + spanRecorder.recordWebInfoStatusCode(statusCode); + + // 采集请求url + spanRecorder.recordWebInfoRequestUrl(request.getRequestURL().toString()); + + Enumeration requestHeaderNames = request.getHeaderNames(); + Collection responseHeaderNames = response.getHeaderNames(); + Map requestHeaders = new HashMap(16); + while (requestHeaderNames.hasMoreElements()) { + String name = requestHeaderNames.nextElement(); + String value = request.getHeader(name); + requestHeaders.put(name, value); + } + // 采集请求头 + if (!requestHeaders.isEmpty()) { + spanRecorder.recordWebInfoRequestHeader(requestHeaders); + + } + if (!responseHeaderNames.isEmpty()) { + Map responseHeaders = new HashMap(responseHeaderNames.size()); + for (String responseHeaderName : responseHeaderNames) { + String value = response.getHeader(responseHeaderName); + responseHeaders.put(responseHeaderName, value); + } + // 采集响应头 + spanRecorder.recordWebInfoResponseHeader(responseHeaders); + } + } } \ No newline at end of file diff --git a/plugins/spring/pom.xml b/plugins/spring/pom.xml index 0747a776e4c6..ee6673cf3bd4 100644 --- a/plugins/spring/pom.xml +++ b/plugins/spring/pom.xml @@ -29,5 +29,35 @@ spring-context provided + + + + org.springframework + spring-web + provided + + + org.springframework + spring-webmvc + provided + + + + javax.servlet + javax.servlet-api + provided + + + + org.apache.tomcat + servlet-api + provided + + + org.apache.tomcat + catalina + provided + + diff --git a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcConstants.java b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcConstants.java index 26c8e6427fff..545265d3e3c5 100644 --- a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcConstants.java +++ b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcConstants.java @@ -16,9 +16,13 @@ package com.navercorp.pinpoint.plugin.spring.web; +import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.common.trace.AnnotationKeyFactory; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.common.trace.ServiceTypeFactory; +import java.util.*; + /** * @author Woonduk Kang(emeroad) */ @@ -27,4 +31,21 @@ private SpringWebMvcConstants() { } public static final ServiceType SPRING_MVC = ServiceTypeFactory.of(5051, "SPRING_MVC", "SPRING"); + + public static final ServiceType BODY_OBTAIN_SERVICE_TYPE = ServiceTypeFactory.of(5088, "SPRING_OBTAIN", "SPRING_OBTAIN"); + + public static final String BODY_OBTAIN_SCOPE = "BodyObtainScope"; + + public static final String PRE_HANDLE_SCOPE = "PreHandleScope"; + + public static final List TRACE_METHODS = Collections.unmodifiableList(unmodifiableList()); + + private static List unmodifiableList() { + List list = new ArrayList(4); + list.add("GET"); + list.add("POST"); + list.add("PUT"); + list.add("DELETE"); + return list; + } } diff --git a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcPlugin.java b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcPlugin.java index 6c3d397097d1..c6d92e65a61e 100644 --- a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcPlugin.java +++ b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcPlugin.java @@ -27,8 +27,11 @@ import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplate; import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplateAware; import com.navercorp.pinpoint.bootstrap.interceptor.BasicMethodInterceptor; +import com.navercorp.pinpoint.bootstrap.interceptor.scope.ExecutionPolicy; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.plugin.spring.web.interceptor.RequestBodyObtainInterceptor; +import com.navercorp.pinpoint.plugin.spring.web.interceptor.ResponseBodyObtainInterceptor; /** @@ -43,6 +46,14 @@ public class SpringWebMvcPlugin implements ProfilerPlugin, TransformTemplateAwar public void setup(ProfilerPluginSetupContext context) { transformTemplate.transform("org.springframework.web.servlet.FrameworkServlet", FrameworkServletTransform.class); + // ============================================================================================= + + // 注册报文采集拦截器 + transformTemplate.transform("org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor", RequestBodyResolverTransform.class); + transformTemplate.transform("org.springframework.web.method.support.InvocableHandlerMethod", ResponseBodyResolverTransform.class); + + + // ============================================================================================= } public static class FrameworkServletTransform implements TransformCallback { @@ -61,6 +72,47 @@ public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, Strin } } + public static class RequestBodyResolverTransform implements TransformCallback { + + @Override + public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); + // Add server metadata + InstrumentMethod startInternalEditor = target.getDeclaredMethod("readWithMessageConverters", + "org.springframework.web.context.request.NativeWebRequest", + "org.springframework.core.MethodParameter", + "java.lang.reflect.Type"); + if (startInternalEditor != null) { + startInternalEditor.addScopedInterceptor(RequestBodyObtainInterceptor.class, SpringWebMvcConstants.BODY_OBTAIN_SCOPE, ExecutionPolicy.ALWAYS); + } + return target.toBytecode(); + } + } + + public static class ResponseBodyResolverTransform implements TransformCallback { + + @Override + public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { + InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); + // Add server metadata +// InstrumentMethod startInternalEditor = target.getDeclaredMethod("doInvoke", +// "java.lang.Object[]"); + + InstrumentMethod startInternalEditor = target.getDeclaredMethod("invokeForRequest", + "org.springframework.web.context.request.NativeWebRequest", + "org.springframework.web.method.support.ModelAndViewContainer", + "java.lang.Object[]"); + + + if (startInternalEditor != null) { + startInternalEditor.addScopedInterceptor(ResponseBodyObtainInterceptor.class, SpringWebMvcConstants.BODY_OBTAIN_SCOPE, ExecutionPolicy.ALWAYS); + } + return target.toBytecode(); + } + } + + + @Override public void setTransformTemplate(TransformTemplate transformTemplate) { this.transformTemplate = transformTemplate; diff --git a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcTraceMetadataProvider.java b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcTraceMetadataProvider.java index f236123475db..e6cc610ffda5 100644 --- a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcTraceMetadataProvider.java +++ b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/SpringWebMvcTraceMetadataProvider.java @@ -30,6 +30,7 @@ public class SpringWebMvcTraceMetadataProvider implements TraceMetadataProvider @Override public void setup(TraceMetadataSetupContext context) { context.addServiceType(SpringWebMvcConstants.SPRING_MVC); + context.addServiceType(SpringWebMvcConstants.BODY_OBTAIN_SERVICE_TYPE); } } diff --git a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/RequestBodyObtainInterceptor.java b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/RequestBodyObtainInterceptor.java new file mode 100644 index 000000000000..8bca35b180b3 --- /dev/null +++ b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/RequestBodyObtainInterceptor.java @@ -0,0 +1,134 @@ +/* + * Copyright 2014 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.plugin.spring.web.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.*; +import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; +import com.navercorp.pinpoint.common.PinpointConstants; +import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.plugin.spring.web.SpringWebMvcConstants; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletRequest; + + + +/** + * @author emeroad + */ +public class RequestBodyObtainInterceptor implements AroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private final TraceContext traceContext; + private final MethodDescriptor descriptor; + + + public RequestBodyObtainInterceptor(TraceContext traceContext, MethodDescriptor descriptor) { + this.traceContext = traceContext; + this.descriptor = descriptor; + } + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + SpanEventRecorder recorder = trace.traceBlockBegin(); + recorder.recordServiceType(SpringWebMvcConstants.BODY_OBTAIN_SERVICE_TYPE); + + } + + /** + * 采集请求体 + * + * @param target 目标方法 + * @param args 拦截方法的参数 + * @param result 拦截方法的返回值,也就是我们要采集的请求体 + * @param throwable 拦截方法的异常 + */ + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + Trace trace = traceContext.currentTraceObject(); + try { + NativeWebRequest nativeRequest = (NativeWebRequest) args[0]; + HttpServletRequest request = (HttpServletRequest) nativeRequest.getNativeRequest(); + + if (trace == null) { + // 此处代表被采样率过滤掉的trace,同时采样策略需要采集此部分调用报文 + if (traceContext.bodyObtainEnable() && traceContext.bodyObtainStrategy() < PinpointConstants.STRATEGY_2) { + Trace rawTraceObject = traceContext.currentRawTraceObject(); + if (null != rawTraceObject) { + recorderWebInfo(rawTraceObject, request, result, throwable); + } + } + return; + } + + // 报文采集 + recorderWebInfo(trace, request, result, throwable); + + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("==========pinpoint获取请求体异常====:{}", th.getMessage(), th); + } + } finally { + if (trace != null) { + trace.traceBlockEnd(); + } + } + } + + private void recorderWebInfo(Trace trace, HttpServletRequest request, Object result, Throwable throwable) { + // 可以定义哪些请求要采集 + String method = request.getMethod(); + if (SpringWebMvcConstants.TRACE_METHODS.contains(method)) { + + SpanEventRecorder recorder = trace.currentSpanEventRecorder(); + if (null != recorder) { + recorder.recordApi(descriptor); + recorder.recordException(throwable); + } + SpanRecorder spanRecorder = trace.getSpanRecorder(); + if (null == spanRecorder) { + return; + } + + // 赋值采样策略 +// spanRecorder.recordWebInfoStrategy(traceContext.bodyObtainStrategy()); + + // 判断是否进行报文采集 + if (traceContext.bodyObtainEnable() && null != result) { + // 采集请求体(@requestBody 注解的参数) + spanRecorder.recordWebInfoRequestBody(result); + } + + } + } +} \ No newline at end of file diff --git a/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/ResponseBodyObtainInterceptor.java b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/ResponseBodyObtainInterceptor.java new file mode 100644 index 000000000000..0f657964ea79 --- /dev/null +++ b/plugins/spring/src/main/java/com/navercorp/pinpoint/plugin/spring/web/interceptor/ResponseBodyObtainInterceptor.java @@ -0,0 +1,141 @@ +/* + * Copyright 2014 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.plugin.spring.web.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.*; +import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; +import com.navercorp.pinpoint.common.PinpointConstants; +import com.navercorp.pinpoint.plugin.spring.web.SpringWebMvcConstants; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * @author emeroad + */ +public class ResponseBodyObtainInterceptor implements AroundInterceptor { + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final boolean isDebug = logger.isDebugEnabled(); + + private final TraceContext traceContext; + private final MethodDescriptor descriptor; + + public ResponseBodyObtainInterceptor(TraceContext traceContext, MethodDescriptor descriptor) { + this.traceContext = traceContext; + this.descriptor = descriptor; + } + + @Override + public void before(Object target, Object[] args) { + if (isDebug) { + logger.beforeInterceptor(target, args); + } + + Trace trace = traceContext.currentTraceObject(); + if (trace == null) { + return; + } + + SpanEventRecorder recorder = trace.traceBlockBegin(); + recorder.recordServiceType(SpringWebMvcConstants.BODY_OBTAIN_SERVICE_TYPE); + } + + /** + * 采集请求体 + * + * @param target 目标方法 + * @param args 拦截方法的参数 + * @param result 拦截方法的返回值,也就是我们要采集的响应体 + * @param throwable 拦截方法的异常 + */ + @Override + public void after(Object target, Object[] args, Object result, Throwable throwable) { + if (isDebug) { + logger.afterInterceptor(target, args, result, throwable); + } + Trace trace = traceContext.currentTraceObject(); + try { + NativeWebRequest nativeRequest = (NativeWebRequest) args[0]; + HttpServletRequest request = (HttpServletRequest) nativeRequest.getNativeRequest(); + + if (null == trace) { + // 此处代表被采样率过滤掉的trace,同时采样策略需要采集此部分调用报文 + if (traceContext.bodyObtainEnable() && traceContext.bodyObtainStrategy() < PinpointConstants.STRATEGY_2) { + Trace rawTraceObject = traceContext.currentRawTraceObject(); + if (null != rawTraceObject) { + recorderWebInfo(rawTraceObject, request, result, throwable); + } + } + return; + } + + // 报文采集 + recorderWebInfo(trace, request, result, throwable); + + } catch (Throwable th) { + if (logger.isWarnEnabled()) { + logger.warn("==========pinpoint获取响应体异常====:{}", th.getMessage(), th); + } + } finally { + if (null != trace) { + trace.traceBlockEnd(); + } + } + } + + private void recorderWebInfo(Trace trace, HttpServletRequest request, Object result, Throwable throwable) throws Exception { + // 可以定义哪些请求要采集 + String method = request.getMethod(); + if (SpringWebMvcConstants.TRACE_METHODS.contains(method)) { + SpanEventRecorder recorder = trace.currentSpanEventRecorder(); + if (null != recorder) { + recorder.recordApi(descriptor); + recorder.recordException(throwable); + } + + // 判断是否进行报文采集 + if (this.traceContext.bodyObtainEnable()) { + SpanRecorder spanRecorder = trace.getSpanRecorder(); + if (null == spanRecorder) { + return; + } + // 赋值采样策略 + spanRecorder.recordWebInfoStrategy(this.traceContext.bodyObtainStrategy()); + + // 采集请求url,url在tomcat插件同样采集了一次,避免某一个插件失效采不到url + spanRecorder.recordWebInfoRequestUrl(request.getRequestURL().toString()); + + // 采集请求参数(@requestParam注解的参数) + Map parameterMap = request.getParameterMap(); + + // spanRecorder.requestBodyTraced()代表已经在@requestBody处采集了请求体,此处逻辑无需执行 + if (!spanRecorder.requestBodyTraced() && null != parameterMap) { + spanRecorder.recordWebInfoRequestBody(parameterMap); + } + + // 采集响应体 + if (null != result) { + spanRecorder.recordWebInfoResponseBody(result); + } + } + } + } +} \ No newline at end of file diff --git a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardHostValveInvokeInterceptor.java b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardHostValveInvokeInterceptor.java index b752267c200c..2a6aa5b7d58c 100644 --- a/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardHostValveInvokeInterceptor.java +++ b/plugins/tomcat/src/main/java/com/navercorp/pinpoint/plugin/tomcat/interceptor/StandardHostValveInvokeInterceptor.java @@ -26,6 +26,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.request.ServletRequestListenerInterceptorHelper; import com.navercorp.pinpoint.bootstrap.plugin.request.util.ParameterRecorder; import com.navercorp.pinpoint.bootstrap.plugin.request.util.RemoteAddressResolverFactory; +import com.navercorp.pinpoint.common.PinpointConstants; import com.navercorp.pinpoint.plugin.common.servlet.util.ArgumentValidator; import com.navercorp.pinpoint.plugin.common.servlet.util.HttpServletRequestAdaptor; import com.navercorp.pinpoint.plugin.common.servlet.util.ParameterRecorderFactory; @@ -36,6 +37,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; /** * @author emeroad @@ -48,6 +53,7 @@ public class StandardHostValveInvokeInterceptor implements AroundInterceptor { private final MethodDescriptor methodDescriptor; private final ArgumentValidator argumentValidator; + private final TraceContext traceContext; private final ServletRequestListenerInterceptorHelper servletRequestListenerInterceptorHelper; @@ -60,6 +66,7 @@ public StandardHostValveInvokeInterceptor(TraceContext traceContext, MethodDescr requestAdaptor = RemoteAddressResolverFactory.wrapRealIpSupport(requestAdaptor, config.getRealIpHeader(), config.getRealIpEmptyValue()); ParameterRecorder parameterRecorder = ParameterRecorderFactory.newParameterRecorderFactory(config.getExcludeProfileMethodFilter(), config.isTraceRequestParam()); this.servletRequestListenerInterceptorHelper = new ServletRequestListenerInterceptorHelper(TomcatConstants.TOMCAT, traceContext, requestAdaptor, config.getExcludeUrlFilter(), parameterRecorder, requestRecorderFactory); + this.traceContext = traceContext; } @Override @@ -100,10 +107,25 @@ public void after(Object target, Object[] args, Object result, Throwable throwab return; } + Trace trace = traceContext.currentTraceObject(); + try { final HttpServletRequest request = (HttpServletRequest) args[0]; final HttpServletResponse response = (HttpServletResponse) args[1]; int statusCode = getStatusCode(response); + + if (null != trace) { + recorderWebInfo(trace, request, response, statusCode); + + } else if (traceContext.bodyObtainEnable() && traceContext.bodyObtainStrategy() < PinpointConstants.STRATEGY_2) { + // 此处代表被采样率过滤掉的trace,同时采样策略需要采集此部分调用报文 + Trace rawTraceObject = traceContext.currentRawTraceObject(); + if (null != rawTraceObject) { + recorderWebInfo(rawTraceObject, request, response, statusCode); + } + + } + this.servletRequestListenerInterceptorHelper.destroyed(request, throwable, statusCode); } catch (Throwable t) { if (isInfo) { @@ -112,6 +134,78 @@ public void after(Object target, Object[] args, Object result, Throwable throwab } } + /** + * 采集报文信息 + * + * @param trace + * @param request + * @param response + * @param statusCode + */ + private void recorderWebInfo(Trace trace, HttpServletRequest request, HttpServletResponse response, int statusCode) { + try { + SpanRecorder spanRecorder = trace.getSpanRecorder(); + if (null != spanRecorder) { + + // 采集请求/响应头,标记请求异常/正常 ========================== + if (traceContext.bodyObtainEnable()) { + headerObtain(request, response, spanRecorder, statusCode); + } + // ========================================= + } + } catch (Throwable t) { + if (isInfo) { + logger.info("采集报文报错,异常信息:", t); + } + } + } + + /** + * 采集请求头、响应头、请求url + * + * @param request 请求 + * @param response 响应 + * @param spanRecorder 采集器 + * @param statusCode + */ + private void headerObtain(HttpServletRequest request, HttpServletResponse response, SpanRecorder spanRecorder, int statusCode) { + + // 赋值采样策略 + spanRecorder.recordWebInfoStrategy(traceContext.bodyObtainStrategy()); + + // 采集请求方式 + spanRecorder.recordWebInfoRequestMethod(request.getMethod()); + + // 采集响应码 + spanRecorder.recordWebInfoStatusCode(statusCode); + + // 采集请求url + spanRecorder.recordWebInfoRequestUrl(request.getRequestURL().toString()); + + Enumeration requestHeaderNames = request.getHeaderNames(); + Collection responseHeaderNames = response.getHeaderNames(); + Map requestHeaders = new HashMap(16); + while (requestHeaderNames.hasMoreElements()) { + String name = requestHeaderNames.nextElement(); + String value = request.getHeader(name); + requestHeaders.put(name, value); + } + // 采集请求头 + if (!requestHeaders.isEmpty()) { + spanRecorder.recordWebInfoRequestHeader(requestHeaders); + + } + if (!responseHeaderNames.isEmpty()) { + Map responseHeaders = new HashMap(responseHeaderNames.size()); + for (String responseHeaderName : responseHeaderNames) { + String value = response.getHeader(responseHeaderName); + responseHeaders.put(responseHeaderName, value); + } + // 采集响应头 + spanRecorder.recordWebInfoResponseHeader(responseHeaders); + } + } + private int getStatusCode(final HttpServletResponse response) { try { // Tomcat 6 diff --git a/plugins/undertow/src/main/java/com/navercorp/pinpoint/plugin/undertow/interceptor/ConnectorsExecuteRootHandlerInterceptor.java b/plugins/undertow/src/main/java/com/navercorp/pinpoint/plugin/undertow/interceptor/ConnectorsExecuteRootHandlerInterceptor.java index ea534707c83b..8a2952e6b434 100644 --- a/plugins/undertow/src/main/java/com/navercorp/pinpoint/plugin/undertow/interceptor/ConnectorsExecuteRootHandlerInterceptor.java +++ b/plugins/undertow/src/main/java/com/navercorp/pinpoint/plugin/undertow/interceptor/ConnectorsExecuteRootHandlerInterceptor.java @@ -17,8 +17,7 @@ package com.navercorp.pinpoint.plugin.undertow.interceptor; import com.navercorp.pinpoint.bootstrap.config.Filter; -import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; -import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.context.*; import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; import com.navercorp.pinpoint.bootstrap.logging.PLogger; import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; @@ -27,6 +26,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.request.ServletRequestListenerInterceptorHelper; import com.navercorp.pinpoint.bootstrap.plugin.request.util.ParameterRecorder; import com.navercorp.pinpoint.bootstrap.plugin.request.util.RemoteAddressResolverFactory; +import com.navercorp.pinpoint.common.PinpointConstants; import com.navercorp.pinpoint.plugin.common.servlet.util.ArgumentValidator; import com.navercorp.pinpoint.plugin.undertow.ParameterRecorderFactory; import com.navercorp.pinpoint.plugin.undertow.UndertowConfig; @@ -34,6 +34,11 @@ import com.navercorp.pinpoint.plugin.undertow.UndertowHttpHeaderFilter; import io.undertow.server.HttpHandler; import io.undertow.server.HttpServerExchange; +import io.undertow.util.HeaderMap; +import io.undertow.util.HeaderValues; +import io.undertow.util.HttpString; +import java.util.HashMap; +import java.util.Map; /** * @author jaehong.kim @@ -48,8 +53,10 @@ public class ConnectorsExecuteRootHandlerInterceptor implements AroundIntercepto private final UndertowHttpHeaderFilter httpHeaderFilter; private final ServletRequestListenerInterceptorHelper servletRequestListenerInterceptorHelper; + private final TraceContext traceContext; public ConnectorsExecuteRootHandlerInterceptor(TraceContext traceContext, MethodDescriptor descriptor, RequestRecorderFactory requestRecorderFactory) { this.methodDescriptor = descriptor; + this.traceContext = traceContext; final UndertowConfig config = new UndertowConfig(traceContext.getProfilerConfig()); this.argumentValidator = new ConnectorsArgumentValidator(config.getHttpHandlerClassNameFilter()); RequestAdaptor requestAdaptor = new HttpServerExchangeAdaptor(); @@ -93,6 +100,23 @@ public void after(Object target, Object[] args, Object result, Throwable throwab try { final HttpServerExchange request = (HttpServerExchange) args[1]; final int statusCode = getStatusCode(request); + + // 请求、响应头信息采集逻辑=================== + if (traceContext.bodyObtainEnable()) { + Trace currentTraceObject = traceContext.currentTraceObject(); + if (null != currentTraceObject) { + recorderWebInfo(currentTraceObject, request, statusCode); + + } else if (traceContext.bodyObtainStrategy() < PinpointConstants.STRATEGY_2) { + // 此处代表被采样率过滤掉的trace,同时采样策略需要采集此部分调用报文 + Trace rawTraceObject = traceContext.currentRawTraceObject(); + if (null != rawTraceObject) { + recorderWebInfo(rawTraceObject, request, statusCode); + } + } + } + // ========================================= + // TODO Get exception. e.g. request.getAttachment(DefaultResponseListener.EXCEPTION) this.servletRequestListenerInterceptorHelper.destroyed(request, throwable, statusCode); } catch (Throwable t) { @@ -102,6 +126,29 @@ public void after(Object target, Object[] args, Object result, Throwable throwab } } + + /** + * 采集报文信息 + * + * @param trace + * @param request + * @param statusCode + */ + private void recorderWebInfo(Trace trace, HttpServerExchange request, int statusCode) { + try { + SpanRecorder spanRecorder = trace.getSpanRecorder(); + if (null != spanRecorder) { + // 采集请求/响应头,标记请求异常/正常 ========================== + headerObtain(request, spanRecorder, statusCode); + // ========================================= + } + } catch (Throwable t) { + if (isInfo) { + logger.info("采集报文报错,异常信息:", t); + } + } + } + private int getStatusCode(final HttpServerExchange response) { try { return response.getStatusCode(); @@ -142,4 +189,54 @@ public boolean validate(Object[] args) { return true; } } + + + /** + * 采集请求头、响应头、请求url + * + * @param request HttpServerExchange + * @param spanRecorder 采集器 + * @param statusCode 响应码 + */ + private void headerObtain(HttpServerExchange request, SpanRecorder spanRecorder, int statusCode) { + + // 赋值采样策略 + spanRecorder.recordWebInfoStrategy(traceContext.bodyObtainStrategy()); + + // 采集请求方式 + spanRecorder.recordWebInfoRequestMethod(request.getRequestMethod().toString()); + + // 采集响应码 + spanRecorder.recordWebInfoStatusCode(statusCode); + + // 采集请求url + spanRecorder.recordWebInfoRequestUrl(request.getRequestURL()); + + HeaderMap requestHeaders = request.getRequestHeaders(); + HeaderMap responseHeaders = request.getResponseHeaders(); + + // 遍历请求头 + if (null != requestHeaders) { + Map requestHeadersMap = new HashMap(requestHeaders.size()); + for (HttpString headerName : requestHeaders.getHeaderNames()) { + HeaderValues headerValues = requestHeaders.get(headerName); + requestHeadersMap.put(headerName.toString(), headerValues); + } + // 采集请求头 + spanRecorder.recordWebInfoRequestHeader(requestHeadersMap); + } + + // 遍历响应头 + if (null != responseHeaders) { + Map responseHeadersMap = new HashMap(responseHeaders.size()); + for (HttpString headerName : responseHeaders.getHeaderNames()) { + HeaderValues headerValues = responseHeaders.get(headerName); + responseHeadersMap.put(headerName.toString(), headerValues); + } + // 采集响应头 + spanRecorder.recordWebInfoResponseHeader(responseHeadersMap); + } + + } + } \ No newline at end of file diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/TestSpanStorageFactory.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/TestSpanStorageFactory.java index 28186ef9b1dd..e6f526cfa760 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/TestSpanStorageFactory.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/TestSpanStorageFactory.java @@ -41,7 +41,7 @@ public TestSpanStorageFactory(@SpanDataSender DataSender dataSender) { @Override public Storage createStorage(SpanChunkFactory spanChunkFactory) { - return new BufferedStorage(spanChunkFactory, this.dataSender, 1); + return new BufferedStorage(spanChunkFactory, this.dataSender, 1, false, "STAUTS", "0000"); } } diff --git a/profiler/pom.xml b/profiler/pom.xml index 5b33c14bbf7f..516480ce5b0c 100644 --- a/profiler/pom.xml +++ b/profiler/pom.xml @@ -212,6 +212,22 @@ junit test + + + com.fasterxml.jackson.core + jackson-core + compile + + + com.fasterxml.jackson.core + jackson-annotations + compile + + + com.fasterxml.jackson.core + jackson-databind + compile + diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncSpanChunkFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncSpanChunkFactory.java index 328f83a67056..6dc84ece63ce 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncSpanChunkFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/AsyncSpanChunkFactory.java @@ -38,4 +38,9 @@ public AsyncSpanChunkFactory(TraceRoot traceRoot, LocalAsyncId localAsyncId) { public SpanChunk newSpanChunk(List spanEventList) { return new DefaultAsyncSpanChunk(traceRoot, spanEventList, localAsyncId); } + + @Override + public SpanWebInfo newSpanWebInfo(WebInfo webInfo) { + return new SpanWebInfo(traceRoot, webInfo); + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java index b4b380f37d68..2d7afaf3a4aa 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultBaseTraceFactory.java @@ -74,11 +74,11 @@ public Trace continueTraceObject(final TraceId traceId) { // TODO need to consider as a target to sample in case Trace object has a sampling flag (true) marked on previous node. // Check max throughput(permits per seconds) final TraceSampler.State state = traceSampler.isContinueSampled(); + final TraceRoot traceRoot = traceRootFactory.continueTraceRoot(traceId, state.nextId()); + final Span span = spanFactory.newSpan(traceRoot); + final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); + final Storage storage = storageFactory.createStorage(spanChunkFactory); if (state.isSampled()) { - final TraceRoot traceRoot = traceRootFactory.continueTraceRoot(traceId, state.nextId()); - final Span span = spanFactory.newSpan(traceRoot); - final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); - final Storage storage = storageFactory.createStorage(spanChunkFactory); final CallStack callStack = callStackFactory.newCallStack(); final boolean samplingEnable = true; @@ -89,7 +89,9 @@ public Trace continueTraceObject(final TraceId traceId) { final DefaultTrace trace = new DefaultTrace(span, callStack, storage, samplingEnable, spanRecorder, wrappedSpanEventRecorder, handle); return trace; } else { - return newDisableTrace(state.nextId()); + final boolean samplingEnable = false; + final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), samplingEnable); + return newDisableTrace(state.nextId(), span, spanRecorder, storage); } } @@ -106,15 +108,15 @@ public Trace newTraceObject() { // TODO need to modify how to inject a datasender final TraceSampler.State state = traceSampler.isNewSampled(); final boolean sampling = state.isSampled(); - if (sampling) { - final TraceRoot traceRoot = traceRootFactory.newTraceRoot(state.nextId()); - final Span span = spanFactory.newSpan(traceRoot); + final TraceRoot traceRoot = traceRootFactory.newTraceRoot(state.nextId()); + final Span span = spanFactory.newSpan(traceRoot); + final TraceId traceId = traceRoot.getTraceId(); + final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); final Storage storage = storageFactory.createStorage(spanChunkFactory); + if (sampling) { final CallStack callStack = callStackFactory.newCallStack(); - final TraceId traceId = traceRoot.getTraceId(); - final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final WrappedSpanEventRecorder wrappedSpanEventRecorder = recorderFactory.newWrappedSpanEventRecorder(traceRoot); final ActiveTraceHandle handle = registerActiveTrace(traceRoot); @@ -122,7 +124,7 @@ public Trace newTraceObject() { return trace; } else { - return newDisableTrace(state.nextId()); + return newDisableTrace(state.nextId(), span, spanRecorder, storage); } } @@ -152,19 +154,19 @@ public Trace continueAsyncTraceObject(TraceRoot traceRoot, LocalAsyncId localAsy public Trace continueAsyncTraceObject(final TraceId traceId) { final TraceSampler.State state = traceSampler.isContinueSampled(); final boolean sampling = state.isSampled(); - if (sampling) { - final TraceRoot traceRoot = traceRootFactory.continueTraceRoot(traceId, state.nextId()); - final Span span = spanFactory.newSpan(traceRoot); - + final TraceRoot traceRoot = traceRootFactory.continueTraceRoot(traceId, state.nextId()); + final Span span = spanFactory.newSpan(traceRoot); + final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); final Storage storage = storageFactory.createStorage(spanChunkFactory); + + if (sampling) { final CallStack callStack = callStackFactory.newCallStack(); final ActiveTraceHandle handle = registerActiveTrace(traceRoot); final SpanAsyncStateListener asyncStateListener = new SpanAsyncStateListener(span, storageFactory); final AsyncState asyncState = new ListenableAsyncState(asyncStateListener, handle); - final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final WrappedSpanEventRecorder wrappedSpanEventRecorder = recorderFactory.newWrappedSpanEventRecorder(traceRoot, asyncState); @@ -173,7 +175,7 @@ public Trace continueAsyncTraceObject(final TraceId traceId) { final AsyncTrace asyncTrace = new AsyncTrace(traceRoot, trace, asyncState); return asyncTrace; } else { - return newDisableTrace(state.nextId()); + return newDisableTrace(state.nextId(), span, spanRecorder, storage); } } @@ -183,11 +185,13 @@ public Trace continueAsyncTraceObject(final TraceId traceId) { public Trace newAsyncTraceObject() { final TraceSampler.State state = traceSampler.isNewSampled(); final boolean sampling = state.isSampled(); - if (sampling) { - final TraceRoot traceRoot = traceRootFactory.newTraceRoot(state.nextId()); - final Span span = spanFactory.newSpan(traceRoot); + final TraceRoot traceRoot = traceRootFactory.newTraceRoot(state.nextId()); + final Span span = spanFactory.newSpan(traceRoot); + final TraceId traceId = traceRoot.getTraceId(); + final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); final Storage storage = storageFactory.createStorage(spanChunkFactory); + if (sampling) { final CallStack callStack = callStackFactory.newCallStack(); final ActiveTraceHandle handle = registerActiveTrace(traceRoot); @@ -195,8 +199,6 @@ public Trace newAsyncTraceObject() { final AsyncState asyncState = new ListenableAsyncState(asyncStateListener, handle); - final TraceId traceId = traceRoot.getTraceId(); - final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); final WrappedSpanEventRecorder wrappedSpanEventRecorder = recorderFactory.newWrappedSpanEventRecorder(traceRoot, asyncState); @@ -206,7 +208,7 @@ public Trace newAsyncTraceObject() { return asyncTrace; } else { - return newDisableTrace(state.nextId()); + return newDisableTrace(state.nextId(), span, spanRecorder, storage); } } @@ -214,14 +216,22 @@ public Trace newAsyncTraceObject() { public Trace disableSampling() { final TraceSampler.State state = traceSampler.getContinueDisableState(); final long nextContinuedDisabledId = state.nextId(); - return newDisableTrace(nextContinuedDisabledId); + final boolean sampling = state.isSampled(); + final TraceRoot traceRoot = traceRootFactory.newTraceRoot(state.nextId()); + final Span span = spanFactory.newSpan(traceRoot); + final TraceId traceId = traceRoot.getTraceId(); + final SpanRecorder spanRecorder = recorderFactory.newSpanRecorder(span, traceId.isRoot(), sampling); + final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(traceRoot); + final Storage storage = storageFactory.createStorage(spanChunkFactory); + + return newDisableTrace(nextContinuedDisabledId, span, spanRecorder, storage); } - private Trace newDisableTrace(long nextDisabledId) { + private Trace newDisableTrace(long nextDisabledId, Span span, SpanRecorder spanRecorder, Storage storage) { final long traceStartTime = System.currentTimeMillis(); final long threadId = Thread.currentThread().getId(); final ActiveTraceHandle activeTraceHandle = registerActiveTrace(nextDisabledId, traceStartTime, threadId); - final Trace disableTrace = new DisableTrace(nextDisabledId, traceStartTime, activeTraceHandle); + final Trace disableTrace = new DisableTrace(nextDisabledId, traceStartTime, activeTraceHandle, span, spanRecorder, storage); return disableTrace; } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java index 042516cb1102..1bacdd800ea8 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java @@ -36,4 +36,9 @@ public DefaultSpanChunkFactory(TraceRoot traceRoot) { public SpanChunk newSpanChunk(List spanEventList) { return new DefaultSpanChunk(traceRoot, spanEventList); } + + @Override + public SpanWebInfo newSpanWebInfo(WebInfo webInfo) { + return new SpanWebInfo(traceRoot, webInfo); + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java index 575b5ac6de9d..a3c309d982d0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java @@ -59,6 +59,19 @@ public class DefaultTraceContext implements TraceContext { private final JdbcContext jdbcContext; + /** + * 报文采集开关 + */ + private final boolean bodyObtainEnable; + + + /** + * 报文采集策略 + * 0 代表全量采集;1 代表正常报文按照采样率,异常报文全量采集;2 代表报文采集按照采样率来走 + */ + private final byte bodyObtainStrategy; + + public DefaultTraceContext(final ProfilerConfig profilerConfig, final AgentInformation agentInformation, final TraceIdFactory traceIdFactory, @@ -81,6 +94,8 @@ public DefaultTraceContext(final ProfilerConfig profilerConfig, this.apiMetaDataService = Assert.requireNonNull(apiMetaDataService, "apiMetaDataService"); this.stringMetaDataService = Assert.requireNonNull(stringMetaDataService, "stringMetaDataService"); this.sqlMetaDataService = Assert.requireNonNull(sqlMetaDataService, "sqlMetaDataService"); + this.bodyObtainEnable = profilerConfig.readBoolean("profiler.spring.web.body", false); + this.bodyObtainStrategy = (byte) profilerConfig.readInt("profiler.spring.web.body.strategy", 2); } /** @@ -239,4 +254,13 @@ public JdbcContext getJdbcContext() { return jdbcContext; } + @Override + public boolean bodyObtainEnable() { + return bodyObtainEnable; + } + + @Override + public byte bodyObtainStrategy() { + return bodyObtainStrategy; + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java index a67c0f309c4e..d9357d7fb0fd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java @@ -18,9 +18,11 @@ import com.navercorp.pinpoint.bootstrap.context.*; import com.navercorp.pinpoint.bootstrap.context.scope.TraceScope; +import com.navercorp.pinpoint.common.PinpointConstants; import com.navercorp.pinpoint.common.util.Assert; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceHandle; import com.navercorp.pinpoint.profiler.context.scope.DefaultTraceScopePool; +import com.navercorp.pinpoint.profiler.context.storage.Storage; /** @@ -38,10 +40,17 @@ public class DisableTrace implements Trace { private final ActiveTraceHandle handle; private boolean closed = false; - public DisableTrace(long id, long startTime, ActiveTraceHandle handle) { + private final SpanRecorder spanRecorder; + private final Span span; + private final Storage storage; + + public DisableTrace(long id, long startTime, ActiveTraceHandle handle, Span span, SpanRecorder spanRecorder, Storage storage) { this.id = id; this.startTime = startTime; this.handle = Assert.requireNonNull(handle, "handle"); + this.span = Assert.requireNonNull(span, "span"); + this.spanRecorder = Assert.requireNonNull(spanRecorder, "spanRecorder"); + this.storage = Assert.requireNonNull(storage, "storage"); } @Override @@ -77,7 +86,9 @@ public void traceBlockEnd(int stackId) { @Override public TraceId getTraceId() { - throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); + return this.span.getTraceRoot().getTraceId(); + +// throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); } @Override @@ -112,9 +123,17 @@ public void close() { if (closed) { return; } - closed = true; final long purgeTime = System.currentTimeMillis(); - handle.purge(purgeTime); + try { + span.getWebInfo().setDisabled(true); + span.setElapsedTime((int) (purgeTime - this.startTime)); + storage.sendWebInfo(span); + } catch (Throwable t) { + // 增强的方法发生异常 + } finally { + closed = true; + handle.purge(purgeTime); + } } @@ -125,7 +144,7 @@ public int getCallStackFrameId() { @Override public SpanRecorder getSpanRecorder() { - return null; + return spanRecorder; } @Override diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/Span.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/Span.java index c504f389e1bd..e976259ef11e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/Span.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/Span.java @@ -52,6 +52,21 @@ public class Span extends DefaultFrameAttachment { private IntStringValue exceptionInfo; // optional + private WebInfo webInfo; + + + public WebInfo getWebInfo() { + if (null == webInfo) { + webInfo = new WebInfo(); + } + return webInfo; + } + + public void setWebInfo(WebInfo webInfo) { + this.webInfo = webInfo; + } + + public Span(final TraceRoot traceRoot) { if (traceRoot == null) { @@ -214,6 +229,7 @@ public String toString() { ", acceptorHost='" + acceptorHost + '\'' + ", apiId=" + apiId + ", exceptionInfo=" + exceptionInfo + + ", webInfo=" + webInfo + "} " + super.toString(); } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java index 7b3749311adc..9514fd7ccecf 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactory.java @@ -23,4 +23,6 @@ */ public interface SpanChunkFactory { SpanChunk newSpanChunk(List spanEventList); + + SpanWebInfo newSpanWebInfo(WebInfo webInfo); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanWebInfo.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanWebInfo.java new file mode 100644 index 000000000000..9684a47770bf --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanWebInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright 2018 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.profiler.context; + +import com.navercorp.pinpoint.common.util.Assert; +import com.navercorp.pinpoint.common.util.IntStringValue; +import com.navercorp.pinpoint.profiler.context.id.TraceRoot; + +import java.util.ArrayList; +import java.util.List; + +/** + * 存放请求/响应报文、url、头信息的span扩展块 + * + * @author wangj881 + */ +public class SpanWebInfo extends DefaultFrameAttachment { + + private final TraceRoot traceRoot; + + private final WebInfo webInfo; + + public SpanWebInfo(TraceRoot traceRoot, WebInfo webInfo) { + this.traceRoot = Assert.requireNonNull(traceRoot, "traceRoot"); + this.webInfo = Assert.requireNonNull(webInfo, "webInfo"); + } + + public TraceRoot getTraceRoot() { + return traceRoot; + } + + public WebInfo getWebInfo() { + return webInfo; + } + + @Override + public String toString() { + return "SpanWebInfo{" + + "traceRoot=" + traceRoot + + ", webInfo=" + webInfo + + '}'; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/WebInfo.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/WebInfo.java new file mode 100644 index 000000000000..5d04fb91a20f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/WebInfo.java @@ -0,0 +1,198 @@ +/* + * Copyright 2018 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.profiler.context; + + +/** + * 存放请求/响应报文、url、头信息的span扩展块 + * + * @author wangj881 + */ +public class WebInfo extends DefaultFrameAttachment { + + private String requestUrl; + + private Object requestBody; + + private Object requestHeader; + + private Object responseBody; + + private Object responseHeader; + + private String requestMethod; + + private int statusCode; + + private String parentApplicationName; + + /** + * 判断是否有报文采集的标志位 + */ + private boolean flag = false; + + /** + * 报文状态标志: + * 0代表正常,1代表异常,2代表未知 + */ + private byte status = 2; + + /** + * 采样策略 + */ + private byte webBodyStrategy = 2; + + /** + * 判断该次采集是disableTrace还是defaultTrace,默认是defaultTrace + */ + private boolean disabled = false; + + /** + * 耗时 + */ + private int elapsedTime; + + @Override + public String toString() { + return "WebInfo{" + + "requestUrl='" + requestUrl + '\'' + + ", requestBody=" + requestBody + + ", requestHeader=" + requestHeader + + ", responseBody=" + responseBody + + ", responseHeader=" + responseHeader + + ", requestMethod='" + requestMethod + '\'' + + ", statusCode=" + statusCode + + ", parentApplicationName='" + parentApplicationName + '\'' + + ", flag=" + flag + + ", status=" + status + + ", webBodyStrategy=" + webBodyStrategy + + ", disabled=" + disabled + + ", elapsedTime=" + elapsedTime + + '}'; + } + + public String getParentApplicationName() { + return parentApplicationName; + } + + public void setParentApplicationName(String parentApplicationName) { + this.parentApplicationName = parentApplicationName; + } + + public WebInfo() { + } + + public int getElapsedTime() { + return elapsedTime; + } + + public void setElapsedTime(int elapsedTime) { + this.elapsedTime = elapsedTime; + } + + public boolean isDisabled() { + return disabled; + } + + public void setDisabled(boolean disabled) { + this.disabled = disabled; + } + + public String getRequestUrl() { + return requestUrl; + } + + public void setRequestUrl(String requestUrl) { + this.requestUrl = requestUrl; + } + + public Object getRequestBody() { + return requestBody; + } + + public void setRequestBody(Object requestBody) { + this.requestBody = requestBody; + setFlag(true); + } + + public Object getRequestHeader() { + return requestHeader; + } + + public void setRequestHeader(Object requestHeader) { + this.requestHeader = requestHeader; + setFlag(true); + } + + public Object getResponseBody() { + return responseBody; + } + + public void setResponseBody(Object responseBody) { + this.responseBody = responseBody; + setFlag(true); + } + + public Object getResponseHeader() { + return responseHeader; + } + + public void setResponseHeader(Object responseHeader) { + this.responseHeader = responseHeader; + setFlag(true); + } + + public String getRequestMethod() { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) { + this.requestMethod = requestMethod; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public boolean isFlag() { + return flag; + } + + public void setFlag(boolean flag) { + this.flag = flag; + } + + public byte getStatus() { + return status; + } + + public void setStatus(byte status) { + this.status = status; + } + + public byte getWebBodyStrategy() { + return webBodyStrategy; + } + + public void setWebBodyStrategy(byte webBodyStrategy) { + this.webBodyStrategy = webBodyStrategy; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/DefaultShared.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/DefaultShared.java index 8fa5e5b67ced..9deb38606afe 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/DefaultShared.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/DefaultShared.java @@ -45,6 +45,8 @@ public class DefaultShared implements Shared { private volatile int statusCode; + private volatile boolean exceptionFlag; + @Override public void maskErrorCode(int errorCode) { // synchronized (this) { @@ -122,4 +124,14 @@ public void setStatusCode(int statusCode) { public int getStatusCode() { return this.statusCode; } + + @Override + public void maskExceptionFlag(boolean flag) { + this.exceptionFlag = flag; + } + + @Override + public boolean isException() { + return exceptionFlag; + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/Shared.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/Shared.java index 3a31a5064b7b..a68f4b281cff 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/Shared.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/id/Shared.java @@ -46,4 +46,8 @@ public interface Shared { void setStatusCode(int statusCode); int getStatusCode(); + + void maskExceptionFlag(boolean flag); + + boolean isException(); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/StorageFactoryProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/StorageFactoryProvider.java index a8b432e316be..9d97b3121ca0 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/StorageFactoryProvider.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/StorageFactoryProvider.java @@ -37,10 +37,19 @@ public class StorageFactoryProvider implements Provider { private final ProfilerConfig profilerConfig; private final DataSender spanDataSender; + /** + * 报文异常判断相关 + */ + private final boolean responseJudge; + private final String responseJudgeSign; + private final String responseJudgeCode; @Inject public StorageFactoryProvider(ProfilerConfig profilerConfig, @SpanDataSender DataSender spanDataSender) { this.profilerConfig = Assert.requireNonNull(profilerConfig, "profilerConfig"); this.spanDataSender = Assert.requireNonNull(spanDataSender, "spanDataSender"); + this.responseJudge = profilerConfig.getThriftTransportConfig().isResponseJudge(); + this.responseJudgeSign = profilerConfig.getThriftTransportConfig().getResponseJudgeSign(); + this.responseJudgeCode = profilerConfig.getThriftTransportConfig().getResponseJudgeCode(); } @Override @@ -55,9 +64,9 @@ public StorageFactory get() { private StorageFactory newStorageFactory() { if (profilerConfig.isIoBufferingEnable()) { int ioBufferingBufferSize = this.profilerConfig.getIoBufferingBufferSize(); - return new BufferedStorageFactory(ioBufferingBufferSize, this.spanDataSender); + return new BufferedStorageFactory(ioBufferingBufferSize, this.spanDataSender, this.responseJudge, this.responseJudgeSign, this.responseJudgeCode); } else { - return new BufferedStorageFactory(Integer.MAX_VALUE, this.spanDataSender); + return new BufferedStorageFactory(Integer.MAX_VALUE, this.spanDataSender, this.responseJudge, this.responseJudgeSign, this.responseJudgeCode); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/DefaultSpanRecorder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/DefaultSpanRecorder.java index 71dbd9a27782..522280e6753d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/DefaultSpanRecorder.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/DefaultSpanRecorder.java @@ -16,13 +16,16 @@ package com.navercorp.pinpoint.profiler.context.recorder; import com.navercorp.pinpoint.bootstrap.context.SpanRecorder; +import com.navercorp.pinpoint.common.trace.AnnotationKey; import com.navercorp.pinpoint.common.trace.LoggingInfo; import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.common.util.StringUtils; import com.navercorp.pinpoint.profiler.context.Annotation; import com.navercorp.pinpoint.profiler.context.DefaultTrace; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.errorhandler.IgnoreErrorHandler; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; +import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataService; import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataService; import com.navercorp.pinpoint.profiler.metadata.StringMetaDataService; import org.slf4j.Logger; @@ -172,4 +175,48 @@ public Object detachFrameObject() { public void recordStatusCode(int statusCode) { span.getTraceRoot().getShared().setStatusCode(statusCode); } + @Override + public void recordWebInfoRequestUrl(String requestUrl) { + this.span.getWebInfo().setRequestUrl(requestUrl); + } + + @Override + public void recordWebInfoRequestBody(Object requestBody) { + this.span.getWebInfo().setRequestBody(requestBody); + } + + @Override + public void recordWebInfoRequestHeader(Object requestHeader) { + this.span.getWebInfo().setRequestHeader(requestHeader); + } + + @Override + public void recordWebInfoResponseBody(Object responseBody) { + this.span.getWebInfo().setResponseBody(responseBody); + } + + @Override + public void recordWebInfoResponseHeader(Object responseHeader) { + this.span.getWebInfo().setResponseHeader(responseHeader); + } + + @Override + public void recordWebInfoRequestMethod(String requestMethod) { + this.span.getWebInfo().setRequestMethod(requestMethod); + } + + @Override + public void recordWebInfoStatusCode(int statusCode) { + this.span.getWebInfo().setStatusCode(statusCode); + } + + @Override + public boolean requestBodyTraced() { + return null != this.span.getWebInfo().getRequestBody(); + } + + @Override + public void recordWebInfoStrategy(byte strategy) { + this.span.getWebInfo().setWebBodyStrategy(strategy); + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/TraceRootSpanRecorder.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/TraceRootSpanRecorder.java index 1ee0bc27c51a..5e51282059ed 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/TraceRootSpanRecorder.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/recorder/TraceRootSpanRecorder.java @@ -159,6 +159,51 @@ public void recordStatusCode(int statusCode) { traceRoot.getShared().setStatusCode(statusCode); } + @Override + public void recordWebInfoRequestUrl(String requestUrl) { + + } + + @Override + public void recordWebInfoRequestBody(Object requestBody) { + + } + + @Override + public void recordWebInfoRequestHeader(Object requestHeader) { + + } + + @Override + public void recordWebInfoResponseBody(Object responseBody) { + + } + + @Override + public void recordWebInfoResponseHeader(Object responseHeader) { + + } + + @Override + public void recordWebInfoRequestMethod(String requestMethod) { + + } + + @Override + public void recordWebInfoStatusCode(int statusCode) { + + } + + @Override + public boolean requestBodyTraced() { + return true; + } + + @Override + public void recordWebInfoStrategy(byte strategy) { + + } + @Override public Object attachFrameObject(Object frameObject) { return null; diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java index 337b8bdcb804..35394bef7477 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorage.java @@ -16,16 +16,24 @@ package com.navercorp.pinpoint.profiler.context.storage; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.Lists; +import com.navercorp.pinpoint.common.PinpointConstants; import com.navercorp.pinpoint.common.util.Assert; import com.navercorp.pinpoint.common.util.CollectionUtils; +import com.navercorp.pinpoint.common.util.StringUtils; import com.navercorp.pinpoint.profiler.context.*; import com.navercorp.pinpoint.profiler.sender.DataSender; +import com.navercorp.pinpoint.profiler.util.JacksonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author emeroad @@ -44,12 +52,23 @@ public class BufferedStorage implements Storage { private final DataSender dataSender; + /** + * 报文异常判断相关 + */ + private final boolean responseJudge; + private final String responseJudgeSign; + private final String responseJudgeCode; - public BufferedStorage(SpanChunkFactory spanChunkFactory, DataSender dataSender, int bufferSize) { + + public BufferedStorage(SpanChunkFactory spanChunkFactory, DataSender dataSender, int bufferSize, + boolean responseJudge, String responseJudgeSign, String responseJudgeCode) { this.spanChunkFactory = Assert.requireNonNull(spanChunkFactory, "spanChunkFactory"); this.dataSender = Assert.requireNonNull(dataSender, "dataSender"); this.bufferSize = bufferSize; this.storage = allocateBuffer(); + this.responseJudge = responseJudge; + this.responseJudgeSign = responseJudgeSign; + this.responseJudgeCode = responseJudgeCode; } @Override @@ -96,6 +115,8 @@ public void store(Span span) { if (isDebug) { logger.debug("Flush {}", span); } + // 报文采集信息发送 + sendWebInfo(span); final boolean success = this.dataSender.send(span); if (!success) { // WARN : Do not call span.toString () @@ -104,6 +125,19 @@ public void store(Span span) { } } + @Override + public void sendWebInfo(Span span) { + if (span.getWebInfo().isFlag()) { + WebInfo webInfo = span.getWebInfo(); + span.setWebInfo(null); + // 增加采集耗时 + webInfo.setElapsedTime(span.getElapsedTime()); + // 增加上游服务名称 + webInfo.setParentApplicationName(span.getParentApplicationName()); + sendSpanWebInfo(webInfo); + } + } + @Override public void flush() { final List spanEventList = clearBuffer(); if (CollectionUtils.hasLength(spanEventList)) { @@ -125,6 +159,191 @@ private void sendSpanChunk(List spanEventList) { } } + private void sendSpanWebInfo(WebInfo webInfo) { + + final SpanWebInfo spanWebInfo = this.spanChunkFactory.newSpanWebInfo(webInfo); + + // 对webinfo的相关字段做前置处理,长度截取、异常判断等,若无需发送,则直接return + if (sendBefore(spanWebInfo)) { + return; + } + + if (isDebug) { + logger.debug("Flush {}", spanWebInfo); + } + final boolean success = this.dataSender.send(spanWebInfo); + if (!success) { + // WARN : Do not call span.toString () + // concurrentmodificationexceptionr may occur in spanProcessV2 + logger.debug("send fail"); + } + } + + /** + * 对webinfo的相关字段做前置处理,长度截取、异常判断等 + * + * @param spanWebInfo + */ + private boolean sendBefore(SpanWebInfo spanWebInfo) { + WebInfo webInfo = spanWebInfo.getWebInfo(); + + // 1. 对报文做正常异常判断 + // ===== ①. 先判断响应报文关键字;②. 判断响应码; ③. 判断是否有异常堆栈 ===== + // 对响应做正常异常判断 + if (responseJudge) { + baseRspCheck(webInfo); + } + // 如果请求状态已经标记为1(异常),说明在响应体的位置已经判断过了,此处响应码不可重复判断。 + if (PinpointConstants.WEBINFO_STATUS_ABNORMAL != webInfo.getStatus()) { + // 标记请求状态(正常/异常),2xx正常,其余异常 + if (PinpointConstants.STATUS_CODE_200 <= webInfo.getStatusCode() && webInfo.getStatusCode() <= PinpointConstants.STATUS_CODE_299) { + webInfo.setStatus(PinpointConstants.STRATEGY_0); + } else { + webInfo.setStatus(PinpointConstants.STRATEGY_1); + } + } + // 判断方法栈是否有异常,如果有,则标记 + if (spanWebInfo.getTraceRoot().getShared().isException() && PinpointConstants.WEBINFO_STATUS_ABNORMAL != webInfo.getStatus()) { + webInfo.setStatus(PinpointConstants.STRATEGY_1); + } + // 2. 再判断报文是否需要发送(只有不在采样率内的报文会有此逻辑) + // 此判断表示:不被采样的报文舍弃 + if (webInfo.isDisabled() && PinpointConstants.STRATEGY_2 == webInfo.getWebBodyStrategy()) { + return true; + } + + // 此判断表示:异常全量,不被采样的正常报文舍弃 + if (webInfo.isDisabled() && PinpointConstants.STRATEGY_1 == webInfo.getWebBodyStrategy() && PinpointConstants.WEBINFO_STATUS_NORMAL == webInfo.getStatus()) { + return true; + } + // 3. 最后对请求/响应头/体做json转换 + try { + webInfo.setRequestHeader(JacksonUtil.toJsonString(webInfo.getRequestHeader())); + } catch (Throwable e) { + webInfo.setRequestHeader(PinpointConstants.EMPTY_STRING); + } + try { + String requestBody = bodyToString(webInfo.getRequestBody()); + String body = sizeLimit(PinpointConstants.REQUEST_BODY_LENGTH_LIMIT, + requestBody, + PinpointConstants.REQUEST_BODY_LENGTH_LIMIT_MAP, + PinpointConstants.REQUEST_BODY); + webInfo.setRequestBody(body); + } catch (Throwable e) { + webInfo.setRequestBody(PinpointConstants.EMPTY_STRING); + } + try { + webInfo.setResponseHeader(JacksonUtil.toJsonString(webInfo.getResponseHeader())); + } catch (Throwable e) { + webInfo.setResponseHeader(PinpointConstants.EMPTY_STRING); + } + try { + // 响应长度限制 + String responseBody = bodyToString(webInfo.getResponseBody()); + String body = sizeLimit(PinpointConstants.RESPONSE_BODY_LENGTH_LIMIT, + responseBody, + PinpointConstants.RESPONSE_BODY_LENGTH_LIMIT_MAP, + PinpointConstants.RESPONSE_BODY); + webInfo.setResponseBody(body); + } catch (Throwable e) { + webInfo.setResponseBody(PinpointConstants.EMPTY_STRING); + } + return false; + } + + private String bodyToString(Object body) throws JsonProcessingException { + if (body instanceof String) { + return (String) body; + } else { + return JacksonUtil.toJsonString(body); + } + } + + /** + * // 对响应做正常异常判断 + * + * @param webInfo 星舟规范响应示例: + * { + * "STATUS": "0000", + * "MSG": "服务调用成功!", + * "TXID": "TxidError0000!", + * "RSP": { + * "RSP_CODE": "0000", + * "RSP_DESC": "执行成功!", + * "SUB_CODE": "0000", + * "SUB_DESC": "执行成功!", + * "DATA": [ + * "HELLO" + * ], + * "ATTACH": "GET" + * } + * } + */ + private void baseRspCheck(WebInfo webInfo) { + Object responseBody = webInfo.getResponseBody(); + if (null == responseBody) { + return; + } + Class clazz = responseBody.getClass(); + + try { + Field[] declaredFields = clazz.getDeclaredFields(); + if (declaredFields.length == 0) { + return; + } + for (Field declaredField : declaredFields) { + if (responseJudgeSign.equals(declaredField.getName())) { + judgeCodeCheck(declaredField, responseBody, webInfo); + break; + } + } + } catch (Throwable t) { + // 捕获所有异常 + } + + +// try { +// Field judgeSign = clazz.getDeclaredField(responseJudgeSign); +// judgeCodeCheck(judgeSign, responseBody, webInfo); +// } catch (Throwable t) { +// // 大概率是clazz.getDeclaredField(responseJudgeSign)抛出的属性找不到异常,考虑到有可能是父类的属性,再往上找一层 +// try { +// Field judgeSign = clazz.getSuperclass().getDeclaredField(responseJudgeSign); +// judgeCodeCheck(judgeSign, responseBody, webInfo); +// } catch (Throwable e) { +// // 捕获所有异常 +// } +// } + } + + private void judgeCodeCheck(Field judgeSign, Object responseBody, WebInfo webInfo) throws IllegalAccessException { + judgeSign.setAccessible(true); + Object judgeCode = judgeSign.get(responseBody); + if (null != judgeCode && responseJudgeCode.equals(judgeCode.toString())) { + webInfo.setStatus(PinpointConstants.STRATEGY_0); + } else { + webInfo.setStatus(PinpointConstants.STRATEGY_1); + } + } + + /** + * 对报文做长度判断及截取 + * + * @param limit 长度限制 + * @param param 报文 + * @param limitMap 限制话术 + * @param key 报文类别 + */ + private String sizeLimit(Integer limit, String param, Map limitMap, String key) throws JsonProcessingException { + if (limit < param.length()) { + Map map = new HashMap(2); + map.putAll(limitMap); + map.put(key, StringUtils.abbreviate(param, PinpointConstants.BODY_LIMIT_LENGTH)); + return JacksonUtil.toJsonString(map); + } + return param; + } + @Override public void close() { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java index 550227dd286c..f2004c646e0b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageFactory.java @@ -28,15 +28,25 @@ public class BufferedStorageFactory implements StorageFactory { private final DataSender dataSender; private final int ioBufferingBufferSize; - public BufferedStorageFactory(int ioBufferingBufferSize, DataSender dataSender) { + /** + * 报文异常判断相关 + */ + private final boolean responseJudge; + private final String responseJudgeSign; + private final String responseJudgeCode; + + public BufferedStorageFactory(int ioBufferingBufferSize, DataSender dataSender, boolean responseJudge, String responseJudgeSign, String responseJudgeCode) { this.dataSender = Assert.requireNonNull(dataSender, "dataSender"); this.ioBufferingBufferSize = ioBufferingBufferSize; + this.responseJudge = responseJudge; + this.responseJudgeSign = responseJudgeSign; + this.responseJudgeCode = responseJudgeCode; } @Override public Storage createStorage(SpanChunkFactory spanChunkFactory) { - Storage storage = new BufferedStorage(spanChunkFactory, this.dataSender, this.ioBufferingBufferSize); + Storage storage = new BufferedStorage(spanChunkFactory, this.dataSender, this.ioBufferingBufferSize, this.responseJudge, this.responseJudgeSign, this.responseJudgeCode); return storage; } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java index ad4cd09898dc..955dc07d289a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/LogStorageFactory.java @@ -20,6 +20,7 @@ import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; import com.navercorp.pinpoint.profiler.context.SpanEvent; +import com.navercorp.pinpoint.profiler.context.WebInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,5 +56,11 @@ public void flush() { @Override public void close() { } + + @Override + public void sendWebInfo(Span span) { + + } + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java index 569367d16a2e..00d4afbff60b 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/Storage.java @@ -18,6 +18,7 @@ import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanEvent; +import com.navercorp.pinpoint.profiler.context.WebInfo; /** * @author emeroad @@ -40,4 +41,10 @@ public interface Storage { void flush(); void close(); + + /** + * 报文发送 + * @param span + */ + void sendWebInfo(Span span); } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/TraceLogDelegateStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/TraceLogDelegateStorage.java index 647a4f0c6c29..2a68677a9d82 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/TraceLogDelegateStorage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/TraceLogDelegateStorage.java @@ -20,6 +20,7 @@ import com.navercorp.pinpoint.profiler.context.DefaultTrace; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanEvent; +import com.navercorp.pinpoint.profiler.context.WebInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,4 +64,10 @@ public void flush() { public void close() { this.delegate.close(); } + + @Override + public void sendWebInfo(Span span) { + + } + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/thrift/SpanThriftMessageConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/thrift/SpanThriftMessageConverter.java index 215cfd486302..f4e5c7d1f35f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/thrift/SpanThriftMessageConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/thrift/SpanThriftMessageConverter.java @@ -21,24 +21,12 @@ import com.navercorp.pinpoint.common.util.Assert; import com.navercorp.pinpoint.common.util.CollectionUtils; import com.navercorp.pinpoint.common.util.IntStringValue; -import com.navercorp.pinpoint.profiler.context.Annotation; -import com.navercorp.pinpoint.profiler.context.AsyncId; -import com.navercorp.pinpoint.profiler.context.AsyncSpanChunk; -import com.navercorp.pinpoint.profiler.context.LocalAsyncId; -import com.navercorp.pinpoint.profiler.context.Span; -import com.navercorp.pinpoint.profiler.context.SpanChunk; -import com.navercorp.pinpoint.profiler.context.SpanEvent; +import com.navercorp.pinpoint.profiler.context.*; import com.navercorp.pinpoint.profiler.context.compress.SpanProcessor; import com.navercorp.pinpoint.profiler.context.id.Shared; import com.navercorp.pinpoint.profiler.context.id.TraceRoot; import com.navercorp.pinpoint.profiler.context.id.TransactionIdEncoder; -import com.navercorp.pinpoint.thrift.dto.TAnnotation; -import com.navercorp.pinpoint.thrift.dto.TAnnotationValue; -import com.navercorp.pinpoint.thrift.dto.TIntStringValue; -import com.navercorp.pinpoint.thrift.dto.TLocalAsyncId; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; +import com.navercorp.pinpoint.thrift.dto.*; import org.apache.thrift.TBase; import java.nio.ByteBuffer; @@ -79,9 +67,41 @@ public SpanThriftMessageConverter(String applicationName, String agentId, long a final Span span = (Span) message; return buildTSpan(span); } + if (message instanceof SpanWebInfo) { + final SpanWebInfo spanWebInfo = (SpanWebInfo) message; + return buildTSpanWebInfo(spanWebInfo); + } return null; } + private TBase buildTSpanWebInfo(SpanWebInfo spanWebInfo) { + final TSpanWebInfo tSpanWebInfo = new TSpanWebInfo(); + + tSpanWebInfo.setApplicationName(applicationName); + tSpanWebInfo.setAgentId(agentId); + tSpanWebInfo.setAgentStartTime(agentStartTime); + + final TraceRoot traceRoot = spanWebInfo.getTraceRoot(); + final TraceId traceId = traceRoot.getTraceId(); + final ByteBuffer transactionId = transactionIdEncoder.encodeTransactionId(traceId); + tSpanWebInfo.setTransactionId(transactionId); + tSpanWebInfo.setSpanId(traceId.getSpanId()); + tSpanWebInfo.setParentSpanId(traceId.getParentSpanId()); + WebInfo webInfo = spanWebInfo.getWebInfo(); + tSpanWebInfo.setRequestBody(webInfo.getRequestBody().toString()); + tSpanWebInfo.setRequestHeader(webInfo.getRequestHeader().toString()); + tSpanWebInfo.setResponseBody(webInfo.getResponseBody().toString()); + tSpanWebInfo.setResponseHeader(webInfo.getResponseHeader().toString()); + tSpanWebInfo.setRequestUrl(webInfo.getRequestUrl()); + tSpanWebInfo.setStatus(webInfo.getStatus()); + tSpanWebInfo.setWebBodyStrategy(webInfo.getWebBodyStrategy()); + tSpanWebInfo.setRequestMethod(webInfo.getRequestMethod()); + tSpanWebInfo.setStatusCode(webInfo.getStatusCode()); + tSpanWebInfo.setElapsedTime(webInfo.getElapsedTime()); + tSpanWebInfo.setParentApplicationName(webInfo.getParentApplicationName()); + return tSpanWebInfo; + } + @VisibleForTesting TSpan buildTSpan(Span span) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JacksonUtil.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JacksonUtil.java new file mode 100644 index 000000000000..b7907b241f4f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JacksonUtil.java @@ -0,0 +1,36 @@ +package com.navercorp.pinpoint.profiler.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.navercorp.pinpoint.common.PinpointConstants; + +import java.util.Map; + +/** + * @Author: wangj881 + * @Description: + * @Date: create in 2022/12/4 9:18 + */ +public class JacksonUtil { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private JacksonUtil() { + } + + public static String toJsonString(Object object) throws JsonProcessingException { + if (null == object) { + return PinpointConstants.EMPTY_STRING; + } + return OBJECT_MAPPER.writeValueAsString(object); + + } + + public static Map parseObjectToMap(Object object) { + if (null == object) { + return null; + } + return OBJECT_MAPPER.convertValue(object, Map.class); + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java index ae96f0f6d7f4..7b0316f5c839 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/storage/BufferedStorageTest.java @@ -130,6 +130,6 @@ public void testStore_manual_flush() throws Exception { private BufferedStorage newBufferedStorage(int bufferSize) { SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory(internalTraceId); - return new BufferedStorage(spanChunkFactory, countingDataSender, bufferSize); + return new BufferedStorage(spanChunkFactory, countingDataSender, bufferSize, false, "status", "0000"); } } \ No newline at end of file diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanWebInfo.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanWebInfo.java new file mode 100644 index 000000000000..a414016de0dd --- /dev/null +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanWebInfo.java @@ -0,0 +1,2138 @@ +/** + * Autogenerated by Thrift Compiler (0.12.0) + *

+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + * + * @generated + */ +package com.navercorp.pinpoint.thrift.dto; + +@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) +@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2022-12-22") +public class TSpanWebInfo implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSpanWebInfo"); + + private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.BYTE, (short) 1); + private static final org.apache.thrift.protocol.TField AGENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("agentId", org.apache.thrift.protocol.TType.STRING, (short) 2); + private static final org.apache.thrift.protocol.TField APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationName", org.apache.thrift.protocol.TType.STRING, (short) 3); + private static final org.apache.thrift.protocol.TField AGENT_START_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("agentStartTime", org.apache.thrift.protocol.TType.I64, (short) 4); + private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.STRING, (short) 5); + private static final org.apache.thrift.protocol.TField SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("spanId", org.apache.thrift.protocol.TType.I64, (short) 6); + private static final org.apache.thrift.protocol.TField REQUEST_BODY_FIELD_DESC = new org.apache.thrift.protocol.TField("requestBody", org.apache.thrift.protocol.TType.STRING, (short) 7); + private static final org.apache.thrift.protocol.TField REQUEST_URL_FIELD_DESC = new org.apache.thrift.protocol.TField("requestUrl", org.apache.thrift.protocol.TType.STRING, (short) 8); + private static final org.apache.thrift.protocol.TField REQUEST_HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("requestHeader", org.apache.thrift.protocol.TType.STRING, (short) 9); + private static final org.apache.thrift.protocol.TField RESPONSE_BODY_FIELD_DESC = new org.apache.thrift.protocol.TField("responseBody", org.apache.thrift.protocol.TType.STRING, (short) 10); + private static final org.apache.thrift.protocol.TField RESPONSE_HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("responseHeader", org.apache.thrift.protocol.TType.STRING, (short) 11); + private static final org.apache.thrift.protocol.TField PARENT_SPAN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentSpanId", org.apache.thrift.protocol.TType.I64, (short) 12); + private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.BYTE, (short) 13); + private static final org.apache.thrift.protocol.TField WEB_BODY_STRATEGY_FIELD_DESC = new org.apache.thrift.protocol.TField("webBodyStrategy", org.apache.thrift.protocol.TType.BYTE, (short) 14); + private static final org.apache.thrift.protocol.TField REQUEST_METHOD_FIELD_DESC = new org.apache.thrift.protocol.TField("requestMethod", org.apache.thrift.protocol.TType.STRING, (short) 15); + private static final org.apache.thrift.protocol.TField STATUS_CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("statusCode", org.apache.thrift.protocol.TType.I32, (short) 16); + private static final org.apache.thrift.protocol.TField ELAPSED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("elapsedTime", org.apache.thrift.protocol.TType.I32, (short) 17); + private static final org.apache.thrift.protocol.TField PARENT_APPLICATION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("parentApplicationName", org.apache.thrift.protocol.TType.STRING, (short) 18); + + private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TSpanWebInfoStandardSchemeFactory(); + private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TSpanWebInfoTupleSchemeFactory(); + + public byte version; // optional + public @org.apache.thrift.annotation.Nullable + String agentId; // required + public @org.apache.thrift.annotation.Nullable + String applicationName; // required + public long agentStartTime; // required + public @org.apache.thrift.annotation.Nullable + java.nio.ByteBuffer transactionId; // required + public long spanId; // required + public @org.apache.thrift.annotation.Nullable + String requestBody; // required + public @org.apache.thrift.annotation.Nullable + String requestUrl; // required + public @org.apache.thrift.annotation.Nullable + String requestHeader; // required + public @org.apache.thrift.annotation.Nullable + String responseBody; // required + public @org.apache.thrift.annotation.Nullable + String responseHeader; // required + public long parentSpanId; // optional + public byte status; // optional + public byte webBodyStrategy; // optional + public @org.apache.thrift.annotation.Nullable + String requestMethod; // required + public int statusCode; // required + public int elapsedTime; // required + public @org.apache.thrift.annotation.Nullable + String parentApplicationName; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + VERSION((short) 1, "version"), + AGENT_ID((short) 2, "agentId"), + APPLICATION_NAME((short) 3, "applicationName"), + AGENT_START_TIME((short) 4, "agentStartTime"), + TRANSACTION_ID((short) 5, "transactionId"), + SPAN_ID((short) 6, "spanId"), + REQUEST_BODY((short) 7, "requestBody"), + REQUEST_URL((short) 8, "requestUrl"), + REQUEST_HEADER((short) 9, "requestHeader"), + RESPONSE_BODY((short) 10, "responseBody"), + RESPONSE_HEADER((short) 11, "responseHeader"), + PARENT_SPAN_ID((short) 12, "parentSpanId"), + STATUS((short) 13, "status"), + WEB_BODY_STRATEGY((short) 14, "webBodyStrategy"), + REQUEST_METHOD((short) 15, "requestMethod"), + STATUS_CODE((short) 16, "statusCode"), + ELAPSED_TIME((short) 17, "elapsedTime"), + PARENT_APPLICATION_NAME((short) 18, "parentApplicationName"); + + private static final java.util.Map byName = new java.util.HashMap(); + + static { + for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + @org.apache.thrift.annotation.Nullable + public static _Fields findByThriftId(int fieldId) { + switch (fieldId) { + case 1: // VERSION + return VERSION; + case 2: // AGENT_ID + return AGENT_ID; + case 3: // APPLICATION_NAME + return APPLICATION_NAME; + case 4: // AGENT_START_TIME + return AGENT_START_TIME; + case 5: // TRANSACTION_ID + return TRANSACTION_ID; + case 6: // SPAN_ID + return SPAN_ID; + case 7: // REQUEST_BODY + return REQUEST_BODY; + case 8: // REQUEST_URL + return REQUEST_URL; + case 9: // REQUEST_HEADER + return REQUEST_HEADER; + case 10: // RESPONSE_BODY + return RESPONSE_BODY; + case 11: // RESPONSE_HEADER + return RESPONSE_HEADER; + case 12: // PARENT_SPAN_ID + return PARENT_SPAN_ID; + case 13: // STATUS + return STATUS; + case 14: // WEB_BODY_STRATEGY + return WEB_BODY_STRATEGY; + case 15: // REQUEST_METHOD + return REQUEST_METHOD; + case 16: // STATUS_CODE + return STATUS_CODE; + case 17: // ELAPSED_TIME + return ELAPSED_TIME; + case 18: // PARENT_APPLICATION_NAME + return PARENT_APPLICATION_NAME; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + @org.apache.thrift.annotation.Nullable + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __VERSION_ISSET_ID = 0; + private static final int __AGENTSTARTTIME_ISSET_ID = 1; + private static final int __SPANID_ISSET_ID = 2; + private static final int __PARENTSPANID_ISSET_ID = 3; + private static final int __STATUS_ISSET_ID = 4; + private static final int __WEBBODYSTRATEGY_ISSET_ID = 5; + private static final int __STATUSCODE_ISSET_ID = 6; + private static final int __ELAPSEDTIME_ISSET_ID = 7; + private byte __isset_bitfield = 0; + private static final _Fields optionals[] = {_Fields.VERSION, _Fields.PARENT_SPAN_ID, _Fields.STATUS, _Fields.WEB_BODY_STRATEGY}; + public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + + static { + java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); + tmpMap.put(_Fields.AGENT_ID, new org.apache.thrift.meta_data.FieldMetaData("agentId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("applicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AGENT_START_TIME, new org.apache.thrift.meta_data.FieldMetaData("agentStartTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING, true))); + tmpMap.put(_Fields.SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("spanId", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.REQUEST_BODY, new org.apache.thrift.meta_data.FieldMetaData("requestBody", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.REQUEST_URL, new org.apache.thrift.meta_data.FieldMetaData("requestUrl", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.REQUEST_HEADER, new org.apache.thrift.meta_data.FieldMetaData("requestHeader", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.RESPONSE_BODY, new org.apache.thrift.meta_data.FieldMetaData("responseBody", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.RESPONSE_HEADER, new org.apache.thrift.meta_data.FieldMetaData("responseHeader", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.PARENT_SPAN_ID, new org.apache.thrift.meta_data.FieldMetaData("parentSpanId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); + tmpMap.put(_Fields.WEB_BODY_STRATEGY, new org.apache.thrift.meta_data.FieldMetaData("webBodyStrategy", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); + tmpMap.put(_Fields.REQUEST_METHOD, new org.apache.thrift.meta_data.FieldMetaData("requestMethod", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.STATUS_CODE, new org.apache.thrift.meta_data.FieldMetaData("statusCode", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.ELAPSED_TIME, new org.apache.thrift.meta_data.FieldMetaData("elapsedTime", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.PARENT_APPLICATION_NAME, new org.apache.thrift.meta_data.FieldMetaData("parentApplicationName", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanWebInfo.class, metaDataMap); + } + + public TSpanWebInfo() { + this.version = (byte) 1; + + this.parentSpanId = -1L; + + this.status = (byte) 2; + + this.webBodyStrategy = (byte) 2; + + } + + public TSpanWebInfo( + String agentId, + String applicationName, + long agentStartTime, + java.nio.ByteBuffer transactionId, + long spanId, + String requestBody, + String requestUrl, + String requestHeader, + String responseBody, + String responseHeader, + String requestMethod, + int statusCode, + int elapsedTime, + String parentApplicationName) { + this(); + this.agentId = agentId; + this.applicationName = applicationName; + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(transactionId); + this.spanId = spanId; + setSpanIdIsSet(true); + this.requestBody = requestBody; + this.requestUrl = requestUrl; + this.requestHeader = requestHeader; + this.responseBody = responseBody; + this.responseHeader = responseHeader; + this.requestMethod = requestMethod; + this.statusCode = statusCode; + setStatusCodeIsSet(true); + this.elapsedTime = elapsedTime; + setElapsedTimeIsSet(true); + this.parentApplicationName = parentApplicationName; + } + + /** + * Performs a deep copy on other. + */ + public TSpanWebInfo(TSpanWebInfo other) { + __isset_bitfield = other.__isset_bitfield; + this.version = other.version; + if (other.isSetAgentId()) { + this.agentId = other.agentId; + } + if (other.isSetApplicationName()) { + this.applicationName = other.applicationName; + } + this.agentStartTime = other.agentStartTime; + if (other.isSetTransactionId()) { + this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(other.transactionId); + } + this.spanId = other.spanId; + if (other.isSetRequestBody()) { + this.requestBody = other.requestBody; + } + if (other.isSetRequestUrl()) { + this.requestUrl = other.requestUrl; + } + if (other.isSetRequestHeader()) { + this.requestHeader = other.requestHeader; + } + if (other.isSetResponseBody()) { + this.responseBody = other.responseBody; + } + if (other.isSetResponseHeader()) { + this.responseHeader = other.responseHeader; + } + this.parentSpanId = other.parentSpanId; + this.status = other.status; + this.webBodyStrategy = other.webBodyStrategy; + if (other.isSetRequestMethod()) { + this.requestMethod = other.requestMethod; + } + this.statusCode = other.statusCode; + this.elapsedTime = other.elapsedTime; + if (other.isSetParentApplicationName()) { + this.parentApplicationName = other.parentApplicationName; + } + } + + public TSpanWebInfo deepCopy() { + return new TSpanWebInfo(this); + } + + @Override + public void clear() { + this.version = (byte) 1; + + this.agentId = null; + this.applicationName = null; + setAgentStartTimeIsSet(false); + this.agentStartTime = 0; + this.transactionId = null; + setSpanIdIsSet(false); + this.spanId = 0; + this.requestBody = null; + this.requestUrl = null; + this.requestHeader = null; + this.responseBody = null; + this.responseHeader = null; + this.parentSpanId = -1L; + + this.status = (byte) 2; + + this.webBodyStrategy = (byte) 2; + + this.requestMethod = null; + setStatusCodeIsSet(false); + this.statusCode = 0; + setElapsedTimeIsSet(false); + this.elapsedTime = 0; + this.parentApplicationName = null; + } + + public byte getVersion() { + return this.version; + } + + public TSpanWebInfo setVersion(byte version) { + this.version = version; + setVersionIsSet(true); + return this; + } + + public void unsetVersion() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __VERSION_ISSET_ID); + } + + /** Returns true if field version is set (has been assigned a value) and false otherwise */ + public boolean isSetVersion() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __VERSION_ISSET_ID); + } + + public void setVersionIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __VERSION_ISSET_ID, value); + } + + @org.apache.thrift.annotation.Nullable + public String getAgentId() { + return this.agentId; + } + + public TSpanWebInfo setAgentId(@org.apache.thrift.annotation.Nullable String agentId) { + this.agentId = agentId; + return this; + } + + public void unsetAgentId() { + this.agentId = null; + } + + /** Returns true if field agentId is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentId() { + return this.agentId != null; + } + + public void setAgentIdIsSet(boolean value) { + if (!value) { + this.agentId = null; + } + } + + @org.apache.thrift.annotation.Nullable + public String getApplicationName() { + return this.applicationName; + } + + public TSpanWebInfo setApplicationName(@org.apache.thrift.annotation.Nullable String applicationName) { + this.applicationName = applicationName; + return this; + } + + public void unsetApplicationName() { + this.applicationName = null; + } + + /** Returns true if field applicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetApplicationName() { + return this.applicationName != null; + } + + public void setApplicationNameIsSet(boolean value) { + if (!value) { + this.applicationName = null; + } + } + + public long getAgentStartTime() { + return this.agentStartTime; + } + + public TSpanWebInfo setAgentStartTime(long agentStartTime) { + this.agentStartTime = agentStartTime; + setAgentStartTimeIsSet(true); + return this; + } + + public void unsetAgentStartTime() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + /** Returns true if field agentStartTime is set (has been assigned a value) and false otherwise */ + public boolean isSetAgentStartTime() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID); + } + + public void setAgentStartTimeIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __AGENTSTARTTIME_ISSET_ID, value); + } + + public byte[] getTransactionId() { + setTransactionId(org.apache.thrift.TBaseHelper.rightSize(transactionId)); + return transactionId == null ? null : transactionId.array(); + } + + public java.nio.ByteBuffer bufferForTransactionId() { + return org.apache.thrift.TBaseHelper.copyBinary(transactionId); + } + + public TSpanWebInfo setTransactionId(byte[] transactionId) { + this.transactionId = transactionId == null ? (java.nio.ByteBuffer) null : java.nio.ByteBuffer.wrap(transactionId.clone()); + return this; + } + + public TSpanWebInfo setTransactionId(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer transactionId) { + this.transactionId = org.apache.thrift.TBaseHelper.copyBinary(transactionId); + return this; + } + + public void unsetTransactionId() { + this.transactionId = null; + } + + /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ + public boolean isSetTransactionId() { + return this.transactionId != null; + } + + public void setTransactionIdIsSet(boolean value) { + if (!value) { + this.transactionId = null; + } + } + + public long getSpanId() { + return this.spanId; + } + + public TSpanWebInfo setSpanId(long spanId) { + this.spanId = spanId; + setSpanIdIsSet(true); + return this; + } + + public void unsetSpanId() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + /** Returns true if field spanId is set (has been assigned a value) and false otherwise */ + public boolean isSetSpanId() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SPANID_ISSET_ID); + } + + public void setSpanIdIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SPANID_ISSET_ID, value); + } + + @org.apache.thrift.annotation.Nullable + public String getRequestBody() { + return this.requestBody; + } + + public TSpanWebInfo setRequestBody(@org.apache.thrift.annotation.Nullable String requestBody) { + this.requestBody = requestBody; + return this; + } + + public void unsetRequestBody() { + this.requestBody = null; + } + + /** Returns true if field requestBody is set (has been assigned a value) and false otherwise */ + public boolean isSetRequestBody() { + return this.requestBody != null; + } + + public void setRequestBodyIsSet(boolean value) { + if (!value) { + this.requestBody = null; + } + } + + @org.apache.thrift.annotation.Nullable + public String getRequestUrl() { + return this.requestUrl; + } + + public TSpanWebInfo setRequestUrl(@org.apache.thrift.annotation.Nullable String requestUrl) { + this.requestUrl = requestUrl; + return this; + } + + public void unsetRequestUrl() { + this.requestUrl = null; + } + + /** Returns true if field requestUrl is set (has been assigned a value) and false otherwise */ + public boolean isSetRequestUrl() { + return this.requestUrl != null; + } + + public void setRequestUrlIsSet(boolean value) { + if (!value) { + this.requestUrl = null; + } + } + + @org.apache.thrift.annotation.Nullable + public String getRequestHeader() { + return this.requestHeader; + } + + public TSpanWebInfo setRequestHeader(@org.apache.thrift.annotation.Nullable String requestHeader) { + this.requestHeader = requestHeader; + return this; + } + + public void unsetRequestHeader() { + this.requestHeader = null; + } + + /** Returns true if field requestHeader is set (has been assigned a value) and false otherwise */ + public boolean isSetRequestHeader() { + return this.requestHeader != null; + } + + public void setRequestHeaderIsSet(boolean value) { + if (!value) { + this.requestHeader = null; + } + } + + @org.apache.thrift.annotation.Nullable + public String getResponseBody() { + return this.responseBody; + } + + public TSpanWebInfo setResponseBody(@org.apache.thrift.annotation.Nullable String responseBody) { + this.responseBody = responseBody; + return this; + } + + public void unsetResponseBody() { + this.responseBody = null; + } + + /** Returns true if field responseBody is set (has been assigned a value) and false otherwise */ + public boolean isSetResponseBody() { + return this.responseBody != null; + } + + public void setResponseBodyIsSet(boolean value) { + if (!value) { + this.responseBody = null; + } + } + + @org.apache.thrift.annotation.Nullable + public String getResponseHeader() { + return this.responseHeader; + } + + public TSpanWebInfo setResponseHeader(@org.apache.thrift.annotation.Nullable String responseHeader) { + this.responseHeader = responseHeader; + return this; + } + + public void unsetResponseHeader() { + this.responseHeader = null; + } + + /** Returns true if field responseHeader is set (has been assigned a value) and false otherwise */ + public boolean isSetResponseHeader() { + return this.responseHeader != null; + } + + public void setResponseHeaderIsSet(boolean value) { + if (!value) { + this.responseHeader = null; + } + } + + public long getParentSpanId() { + return this.parentSpanId; + } + + public TSpanWebInfo setParentSpanId(long parentSpanId) { + this.parentSpanId = parentSpanId; + setParentSpanIdIsSet(true); + return this; + } + + public void unsetParentSpanId() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); + } + + /** Returns true if field parentSpanId is set (has been assigned a value) and false otherwise */ + public boolean isSetParentSpanId() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __PARENTSPANID_ISSET_ID); + } + + public void setParentSpanIdIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __PARENTSPANID_ISSET_ID, value); + } + + public byte getStatus() { + return this.status; + } + + public TSpanWebInfo setStatus(byte status) { + this.status = status; + setStatusIsSet(true); + return this; + } + + public void unsetStatus() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STATUS_ISSET_ID); + } + + /** Returns true if field status is set (has been assigned a value) and false otherwise */ + public boolean isSetStatus() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STATUS_ISSET_ID); + } + + public void setStatusIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STATUS_ISSET_ID, value); + } + + public byte getWebBodyStrategy() { + return this.webBodyStrategy; + } + + public TSpanWebInfo setWebBodyStrategy(byte webBodyStrategy) { + this.webBodyStrategy = webBodyStrategy; + setWebBodyStrategyIsSet(true); + return this; + } + + public void unsetWebBodyStrategy() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __WEBBODYSTRATEGY_ISSET_ID); + } + + /** Returns true if field webBodyStrategy is set (has been assigned a value) and false otherwise */ + public boolean isSetWebBodyStrategy() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __WEBBODYSTRATEGY_ISSET_ID); + } + + public void setWebBodyStrategyIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __WEBBODYSTRATEGY_ISSET_ID, value); + } + + @org.apache.thrift.annotation.Nullable + public String getRequestMethod() { + return this.requestMethod; + } + + public TSpanWebInfo setRequestMethod(@org.apache.thrift.annotation.Nullable String requestMethod) { + this.requestMethod = requestMethod; + return this; + } + + public void unsetRequestMethod() { + this.requestMethod = null; + } + + /** Returns true if field requestMethod is set (has been assigned a value) and false otherwise */ + public boolean isSetRequestMethod() { + return this.requestMethod != null; + } + + public void setRequestMethodIsSet(boolean value) { + if (!value) { + this.requestMethod = null; + } + } + + public int getStatusCode() { + return this.statusCode; + } + + public TSpanWebInfo setStatusCode(int statusCode) { + this.statusCode = statusCode; + setStatusCodeIsSet(true); + return this; + } + + public void unsetStatusCode() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STATUSCODE_ISSET_ID); + } + + /** Returns true if field statusCode is set (has been assigned a value) and false otherwise */ + public boolean isSetStatusCode() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STATUSCODE_ISSET_ID); + } + + public void setStatusCodeIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STATUSCODE_ISSET_ID, value); + } + + public int getElapsedTime() { + return this.elapsedTime; + } + + public TSpanWebInfo setElapsedTime(int elapsedTime) { + this.elapsedTime = elapsedTime; + setElapsedTimeIsSet(true); + return this; + } + + public void unsetElapsedTime() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ELAPSEDTIME_ISSET_ID); + } + + /** Returns true if field elapsedTime is set (has been assigned a value) and false otherwise */ + public boolean isSetElapsedTime() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ELAPSEDTIME_ISSET_ID); + } + + public void setElapsedTimeIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ELAPSEDTIME_ISSET_ID, value); + } + + @org.apache.thrift.annotation.Nullable + public String getParentApplicationName() { + return this.parentApplicationName; + } + + public TSpanWebInfo setParentApplicationName(@org.apache.thrift.annotation.Nullable String parentApplicationName) { + this.parentApplicationName = parentApplicationName; + return this; + } + + public void unsetParentApplicationName() { + this.parentApplicationName = null; + } + + /** Returns true if field parentApplicationName is set (has been assigned a value) and false otherwise */ + public boolean isSetParentApplicationName() { + return this.parentApplicationName != null; + } + + public void setParentApplicationNameIsSet(boolean value) { + if (!value) { + this.parentApplicationName = null; + } + } + + public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable Object value) { + switch (field) { + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((Byte) value); + } + break; + + case AGENT_ID: + if (value == null) { + unsetAgentId(); + } else { + setAgentId((String) value); + } + break; + + case APPLICATION_NAME: + if (value == null) { + unsetApplicationName(); + } else { + setApplicationName((String) value); + } + break; + + case AGENT_START_TIME: + if (value == null) { + unsetAgentStartTime(); + } else { + setAgentStartTime((Long) value); + } + break; + + case TRANSACTION_ID: + if (value == null) { + unsetTransactionId(); + } else { + if (value instanceof byte[]) { + setTransactionId((byte[]) value); + } else { + setTransactionId((java.nio.ByteBuffer) value); + } + } + break; + + case SPAN_ID: + if (value == null) { + unsetSpanId(); + } else { + setSpanId((Long) value); + } + break; + + case REQUEST_BODY: + if (value == null) { + unsetRequestBody(); + } else { + setRequestBody((String) value); + } + break; + + case REQUEST_URL: + if (value == null) { + unsetRequestUrl(); + } else { + setRequestUrl((String) value); + } + break; + + case REQUEST_HEADER: + if (value == null) { + unsetRequestHeader(); + } else { + setRequestHeader((String) value); + } + break; + + case RESPONSE_BODY: + if (value == null) { + unsetResponseBody(); + } else { + setResponseBody((String) value); + } + break; + + case RESPONSE_HEADER: + if (value == null) { + unsetResponseHeader(); + } else { + setResponseHeader((String) value); + } + break; + + case PARENT_SPAN_ID: + if (value == null) { + unsetParentSpanId(); + } else { + setParentSpanId((Long) value); + } + break; + + case STATUS: + if (value == null) { + unsetStatus(); + } else { + setStatus((Byte) value); + } + break; + + case WEB_BODY_STRATEGY: + if (value == null) { + unsetWebBodyStrategy(); + } else { + setWebBodyStrategy((Byte) value); + } + break; + + case REQUEST_METHOD: + if (value == null) { + unsetRequestMethod(); + } else { + setRequestMethod((String) value); + } + break; + + case STATUS_CODE: + if (value == null) { + unsetStatusCode(); + } else { + setStatusCode((Integer) value); + } + break; + + case ELAPSED_TIME: + if (value == null) { + unsetElapsedTime(); + } else { + setElapsedTime((Integer) value); + } + break; + + case PARENT_APPLICATION_NAME: + if (value == null) { + unsetParentApplicationName(); + } else { + setParentApplicationName((String) value); + } + break; + + } + } + + @org.apache.thrift.annotation.Nullable + public Object getFieldValue(_Fields field) { + switch (field) { + case VERSION: + return getVersion(); + + case AGENT_ID: + return getAgentId(); + + case APPLICATION_NAME: + return getApplicationName(); + + case AGENT_START_TIME: + return getAgentStartTime(); + + case TRANSACTION_ID: + return getTransactionId(); + + case SPAN_ID: + return getSpanId(); + + case REQUEST_BODY: + return getRequestBody(); + + case REQUEST_URL: + return getRequestUrl(); + + case REQUEST_HEADER: + return getRequestHeader(); + + case RESPONSE_BODY: + return getResponseBody(); + + case RESPONSE_HEADER: + return getResponseHeader(); + + case PARENT_SPAN_ID: + return getParentSpanId(); + + case STATUS: + return getStatus(); + + case WEB_BODY_STRATEGY: + return getWebBodyStrategy(); + + case REQUEST_METHOD: + return getRequestMethod(); + + case STATUS_CODE: + return getStatusCode(); + + case ELAPSED_TIME: + return getElapsedTime(); + + case PARENT_APPLICATION_NAME: + return getParentApplicationName(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case VERSION: + return isSetVersion(); + case AGENT_ID: + return isSetAgentId(); + case APPLICATION_NAME: + return isSetApplicationName(); + case AGENT_START_TIME: + return isSetAgentStartTime(); + case TRANSACTION_ID: + return isSetTransactionId(); + case SPAN_ID: + return isSetSpanId(); + case REQUEST_BODY: + return isSetRequestBody(); + case REQUEST_URL: + return isSetRequestUrl(); + case REQUEST_HEADER: + return isSetRequestHeader(); + case RESPONSE_BODY: + return isSetResponseBody(); + case RESPONSE_HEADER: + return isSetResponseHeader(); + case PARENT_SPAN_ID: + return isSetParentSpanId(); + case STATUS: + return isSetStatus(); + case WEB_BODY_STRATEGY: + return isSetWebBodyStrategy(); + case REQUEST_METHOD: + return isSetRequestMethod(); + case STATUS_CODE: + return isSetStatusCode(); + case ELAPSED_TIME: + return isSetElapsedTime(); + case PARENT_APPLICATION_NAME: + return isSetParentApplicationName(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof TSpanWebInfo) + return this.equals((TSpanWebInfo) that); + return false; + } + + public boolean equals(TSpanWebInfo that) { + if (that == null) + return false; + if (this == that) + return true; + + boolean this_present_version = true && this.isSetVersion(); + boolean that_present_version = true && that.isSetVersion(); + if (this_present_version || that_present_version) { + if (!(this_present_version && that_present_version)) + return false; + if (this.version != that.version) + return false; + } + + boolean this_present_agentId = true && this.isSetAgentId(); + boolean that_present_agentId = true && that.isSetAgentId(); + if (this_present_agentId || that_present_agentId) { + if (!(this_present_agentId && that_present_agentId)) + return false; + if (!this.agentId.equals(that.agentId)) + return false; + } + + boolean this_present_applicationName = true && this.isSetApplicationName(); + boolean that_present_applicationName = true && that.isSetApplicationName(); + if (this_present_applicationName || that_present_applicationName) { + if (!(this_present_applicationName && that_present_applicationName)) + return false; + if (!this.applicationName.equals(that.applicationName)) + return false; + } + + boolean this_present_agentStartTime = true; + boolean that_present_agentStartTime = true; + if (this_present_agentStartTime || that_present_agentStartTime) { + if (!(this_present_agentStartTime && that_present_agentStartTime)) + return false; + if (this.agentStartTime != that.agentStartTime) + return false; + } + + boolean this_present_transactionId = true && this.isSetTransactionId(); + boolean that_present_transactionId = true && that.isSetTransactionId(); + if (this_present_transactionId || that_present_transactionId) { + if (!(this_present_transactionId && that_present_transactionId)) + return false; + if (!this.transactionId.equals(that.transactionId)) + return false; + } + + boolean this_present_spanId = true; + boolean that_present_spanId = true; + if (this_present_spanId || that_present_spanId) { + if (!(this_present_spanId && that_present_spanId)) + return false; + if (this.spanId != that.spanId) + return false; + } + + boolean this_present_requestBody = true && this.isSetRequestBody(); + boolean that_present_requestBody = true && that.isSetRequestBody(); + if (this_present_requestBody || that_present_requestBody) { + if (!(this_present_requestBody && that_present_requestBody)) + return false; + if (!this.requestBody.equals(that.requestBody)) + return false; + } + + boolean this_present_requestUrl = true && this.isSetRequestUrl(); + boolean that_present_requestUrl = true && that.isSetRequestUrl(); + if (this_present_requestUrl || that_present_requestUrl) { + if (!(this_present_requestUrl && that_present_requestUrl)) + return false; + if (!this.requestUrl.equals(that.requestUrl)) + return false; + } + + boolean this_present_requestHeader = true && this.isSetRequestHeader(); + boolean that_present_requestHeader = true && that.isSetRequestHeader(); + if (this_present_requestHeader || that_present_requestHeader) { + if (!(this_present_requestHeader && that_present_requestHeader)) + return false; + if (!this.requestHeader.equals(that.requestHeader)) + return false; + } + + boolean this_present_responseBody = true && this.isSetResponseBody(); + boolean that_present_responseBody = true && that.isSetResponseBody(); + if (this_present_responseBody || that_present_responseBody) { + if (!(this_present_responseBody && that_present_responseBody)) + return false; + if (!this.responseBody.equals(that.responseBody)) + return false; + } + + boolean this_present_responseHeader = true && this.isSetResponseHeader(); + boolean that_present_responseHeader = true && that.isSetResponseHeader(); + if (this_present_responseHeader || that_present_responseHeader) { + if (!(this_present_responseHeader && that_present_responseHeader)) + return false; + if (!this.responseHeader.equals(that.responseHeader)) + return false; + } + + boolean this_present_parentSpanId = true && this.isSetParentSpanId(); + boolean that_present_parentSpanId = true && that.isSetParentSpanId(); + if (this_present_parentSpanId || that_present_parentSpanId) { + if (!(this_present_parentSpanId && that_present_parentSpanId)) + return false; + if (this.parentSpanId != that.parentSpanId) + return false; + } + + boolean this_present_status = true && this.isSetStatus(); + boolean that_present_status = true && that.isSetStatus(); + if (this_present_status || that_present_status) { + if (!(this_present_status && that_present_status)) + return false; + if (this.status != that.status) + return false; + } + + boolean this_present_webBodyStrategy = true && this.isSetWebBodyStrategy(); + boolean that_present_webBodyStrategy = true && that.isSetWebBodyStrategy(); + if (this_present_webBodyStrategy || that_present_webBodyStrategy) { + if (!(this_present_webBodyStrategy && that_present_webBodyStrategy)) + return false; + if (this.webBodyStrategy != that.webBodyStrategy) + return false; + } + + boolean this_present_requestMethod = true && this.isSetRequestMethod(); + boolean that_present_requestMethod = true && that.isSetRequestMethod(); + if (this_present_requestMethod || that_present_requestMethod) { + if (!(this_present_requestMethod && that_present_requestMethod)) + return false; + if (!this.requestMethod.equals(that.requestMethod)) + return false; + } + + boolean this_present_statusCode = true; + boolean that_present_statusCode = true; + if (this_present_statusCode || that_present_statusCode) { + if (!(this_present_statusCode && that_present_statusCode)) + return false; + if (this.statusCode != that.statusCode) + return false; + } + + boolean this_present_elapsedTime = true; + boolean that_present_elapsedTime = true; + if (this_present_elapsedTime || that_present_elapsedTime) { + if (!(this_present_elapsedTime && that_present_elapsedTime)) + return false; + if (this.elapsedTime != that.elapsedTime) + return false; + } + + boolean this_present_parentApplicationName = true && this.isSetParentApplicationName(); + boolean that_present_parentApplicationName = true && that.isSetParentApplicationName(); + if (this_present_parentApplicationName || that_present_parentApplicationName) { + if (!(this_present_parentApplicationName && that_present_parentApplicationName)) + return false; + if (!this.parentApplicationName.equals(that.parentApplicationName)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + int hashCode = 1; + + hashCode = hashCode * 8191 + ((isSetVersion()) ? 131071 : 524287); + if (isSetVersion()) + hashCode = hashCode * 8191 + (int) (version); + + hashCode = hashCode * 8191 + ((isSetAgentId()) ? 131071 : 524287); + if (isSetAgentId()) + hashCode = hashCode * 8191 + agentId.hashCode(); + + hashCode = hashCode * 8191 + ((isSetApplicationName()) ? 131071 : 524287); + if (isSetApplicationName()) + hashCode = hashCode * 8191 + applicationName.hashCode(); + + hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(agentStartTime); + + hashCode = hashCode * 8191 + ((isSetTransactionId()) ? 131071 : 524287); + if (isSetTransactionId()) + hashCode = hashCode * 8191 + transactionId.hashCode(); + + hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(spanId); + + hashCode = hashCode * 8191 + ((isSetRequestBody()) ? 131071 : 524287); + if (isSetRequestBody()) + hashCode = hashCode * 8191 + requestBody.hashCode(); + + hashCode = hashCode * 8191 + ((isSetRequestUrl()) ? 131071 : 524287); + if (isSetRequestUrl()) + hashCode = hashCode * 8191 + requestUrl.hashCode(); + + hashCode = hashCode * 8191 + ((isSetRequestHeader()) ? 131071 : 524287); + if (isSetRequestHeader()) + hashCode = hashCode * 8191 + requestHeader.hashCode(); + + hashCode = hashCode * 8191 + ((isSetResponseBody()) ? 131071 : 524287); + if (isSetResponseBody()) + hashCode = hashCode * 8191 + responseBody.hashCode(); + + hashCode = hashCode * 8191 + ((isSetResponseHeader()) ? 131071 : 524287); + if (isSetResponseHeader()) + hashCode = hashCode * 8191 + responseHeader.hashCode(); + + hashCode = hashCode * 8191 + ((isSetParentSpanId()) ? 131071 : 524287); + if (isSetParentSpanId()) + hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(parentSpanId); + + hashCode = hashCode * 8191 + ((isSetStatus()) ? 131071 : 524287); + if (isSetStatus()) + hashCode = hashCode * 8191 + (int) (status); + + hashCode = hashCode * 8191 + ((isSetWebBodyStrategy()) ? 131071 : 524287); + if (isSetWebBodyStrategy()) + hashCode = hashCode * 8191 + (int) (webBodyStrategy); + + hashCode = hashCode * 8191 + ((isSetRequestMethod()) ? 131071 : 524287); + if (isSetRequestMethod()) + hashCode = hashCode * 8191 + requestMethod.hashCode(); + + hashCode = hashCode * 8191 + statusCode; + + hashCode = hashCode * 8191 + elapsedTime; + + hashCode = hashCode * 8191 + ((isSetParentApplicationName()) ? 131071 : 524287); + if (isSetParentApplicationName()) + hashCode = hashCode * 8191 + parentApplicationName.hashCode(); + + return hashCode; + } + + @Override + public int compareTo(TSpanWebInfo other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + + lastComparison = Boolean.valueOf(isSetVersion()).compareTo(other.isSetVersion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersion()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, other.version); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentId()).compareTo(other.isSetAgentId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentId, other.agentId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetApplicationName()).compareTo(other.isSetApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationName, other.applicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetAgentStartTime()).compareTo(other.isSetAgentStartTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetAgentStartTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.agentStartTime, other.agentStartTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(other.isSetTransactionId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTransactionId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, other.transactionId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSpanId()).compareTo(other.isSetSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.spanId, other.spanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRequestBody()).compareTo(other.isSetRequestBody()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRequestBody()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requestBody, other.requestBody); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRequestUrl()).compareTo(other.isSetRequestUrl()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRequestUrl()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requestUrl, other.requestUrl); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRequestHeader()).compareTo(other.isSetRequestHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRequestHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requestHeader, other.requestHeader); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetResponseBody()).compareTo(other.isSetResponseBody()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetResponseBody()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.responseBody, other.responseBody); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetResponseHeader()).compareTo(other.isSetResponseHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetResponseHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.responseHeader, other.responseHeader); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetParentSpanId()).compareTo(other.isSetParentSpanId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetParentSpanId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentSpanId, other.parentSpanId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStatus()).compareTo(other.isSetStatus()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStatus()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, other.status); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetWebBodyStrategy()).compareTo(other.isSetWebBodyStrategy()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetWebBodyStrategy()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.webBodyStrategy, other.webBodyStrategy); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRequestMethod()).compareTo(other.isSetRequestMethod()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRequestMethod()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.requestMethod, other.requestMethod); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStatusCode()).compareTo(other.isSetStatusCode()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStatusCode()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.statusCode, other.statusCode); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetElapsedTime()).compareTo(other.isSetElapsedTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetElapsedTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.elapsedTime, other.elapsedTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetParentApplicationName()).compareTo(other.isSetParentApplicationName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetParentApplicationName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentApplicationName, other.parentApplicationName); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + @org.apache.thrift.annotation.Nullable + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + scheme(iprot).read(iprot, this); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + scheme(oprot).write(oprot, this); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("TSpanWebInfo("); + boolean first = true; + + if (isSetVersion()) { + sb.append("version:"); + sb.append(this.version); + first = false; + } + if (!first) sb.append(", "); + sb.append("agentId:"); + if (this.agentId == null) { + sb.append("null"); + } else { + sb.append(this.agentId); + } + first = false; + if (!first) sb.append(", "); + sb.append("applicationName:"); + if (this.applicationName == null) { + sb.append("null"); + } else { + sb.append(this.applicationName); + } + first = false; + if (!first) sb.append(", "); + sb.append("agentStartTime:"); + sb.append(this.agentStartTime); + first = false; + if (!first) sb.append(", "); + sb.append("transactionId:"); + if (this.transactionId == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.transactionId, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("spanId:"); + sb.append(this.spanId); + first = false; + if (!first) sb.append(", "); + sb.append("requestBody:"); + if (this.requestBody == null) { + sb.append("null"); + } else { + sb.append(this.requestBody); + } + first = false; + if (!first) sb.append(", "); + sb.append("requestUrl:"); + if (this.requestUrl == null) { + sb.append("null"); + } else { + sb.append(this.requestUrl); + } + first = false; + if (!first) sb.append(", "); + sb.append("requestHeader:"); + if (this.requestHeader == null) { + sb.append("null"); + } else { + sb.append(this.requestHeader); + } + first = false; + if (!first) sb.append(", "); + sb.append("responseBody:"); + if (this.responseBody == null) { + sb.append("null"); + } else { + sb.append(this.responseBody); + } + first = false; + if (!first) sb.append(", "); + sb.append("responseHeader:"); + if (this.responseHeader == null) { + sb.append("null"); + } else { + sb.append(this.responseHeader); + } + first = false; + if (isSetParentSpanId()) { + if (!first) sb.append(", "); + sb.append("parentSpanId:"); + sb.append(this.parentSpanId); + first = false; + } + if (isSetStatus()) { + if (!first) sb.append(", "); + sb.append("status:"); + sb.append(this.status); + first = false; + } + if (isSetWebBodyStrategy()) { + if (!first) sb.append(", "); + sb.append("webBodyStrategy:"); + sb.append(this.webBodyStrategy); + first = false; + } + if (!first) sb.append(", "); + sb.append("requestMethod:"); + if (this.requestMethod == null) { + sb.append("null"); + } else { + sb.append(this.requestMethod); + } + first = false; + if (!first) sb.append(", "); + sb.append("statusCode:"); + sb.append(this.statusCode); + first = false; + if (!first) sb.append(", "); + sb.append("elapsedTime:"); + sb.append(this.elapsedTime); + first = false; + if (!first) sb.append(", "); + sb.append("parentApplicationName:"); + if (this.parentApplicationName == null) { + sb.append("null"); + } else { + sb.append(this.parentApplicationName); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // check for sub-struct validity + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bitfield = 0; + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private static class TSpanWebInfoStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { + public TSpanWebInfoStandardScheme getScheme() { + return new TSpanWebInfoStandardScheme(); + } + } + + private static class TSpanWebInfoStandardScheme extends org.apache.thrift.scheme.StandardScheme { + + public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanWebInfo struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField schemeField; + iprot.readStructBegin(); + while (true) { + schemeField = iprot.readFieldBegin(); + if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (schemeField.id) { + case 1: // VERSION + if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) { + struct.version = iprot.readByte(); + struct.setVersionIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 2: // AGENT_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 3: // APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 4: // AGENT_START_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 5: // TRANSACTION_ID + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 6: // SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 7: // REQUEST_BODY + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.requestBody = iprot.readString(); + struct.setRequestBodyIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 8: // REQUEST_URL + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.requestUrl = iprot.readString(); + struct.setRequestUrlIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 9: // REQUEST_HEADER + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.requestHeader = iprot.readString(); + struct.setRequestHeaderIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 10: // RESPONSE_BODY + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.responseBody = iprot.readString(); + struct.setResponseBodyIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 11: // RESPONSE_HEADER + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.responseHeader = iprot.readString(); + struct.setResponseHeaderIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 12: // PARENT_SPAN_ID + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.parentSpanId = iprot.readI64(); + struct.setParentSpanIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 13: // STATUS + if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) { + struct.status = iprot.readByte(); + struct.setStatusIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 14: // WEB_BODY_STRATEGY + if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) { + struct.webBodyStrategy = iprot.readByte(); + struct.setWebBodyStrategyIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 15: // REQUEST_METHOD + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.requestMethod = iprot.readString(); + struct.setRequestMethodIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 16: // STATUS_CODE + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.statusCode = iprot.readI32(); + struct.setStatusCodeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 17: // ELAPSED_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I32) { + struct.elapsedTime = iprot.readI32(); + struct.setElapsedTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 18: // PARENT_APPLICATION_NAME + if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { + struct.parentApplicationName = iprot.readString(); + struct.setParentApplicationNameIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + struct.validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanWebInfo struct) throws org.apache.thrift.TException { + struct.validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (struct.isSetVersion()) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + oprot.writeByte(struct.version); + oprot.writeFieldEnd(); + } + if (struct.agentId != null) { + oprot.writeFieldBegin(AGENT_ID_FIELD_DESC); + oprot.writeString(struct.agentId); + oprot.writeFieldEnd(); + } + if (struct.applicationName != null) { + oprot.writeFieldBegin(APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.applicationName); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(AGENT_START_TIME_FIELD_DESC); + oprot.writeI64(struct.agentStartTime); + oprot.writeFieldEnd(); + if (struct.transactionId != null) { + oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); + oprot.writeBinary(struct.transactionId); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.spanId); + oprot.writeFieldEnd(); + if (struct.requestBody != null) { + oprot.writeFieldBegin(REQUEST_BODY_FIELD_DESC); + oprot.writeString(struct.requestBody); + oprot.writeFieldEnd(); + } + if (struct.requestUrl != null) { + oprot.writeFieldBegin(REQUEST_URL_FIELD_DESC); + oprot.writeString(struct.requestUrl); + oprot.writeFieldEnd(); + } + if (struct.requestHeader != null) { + oprot.writeFieldBegin(REQUEST_HEADER_FIELD_DESC); + oprot.writeString(struct.requestHeader); + oprot.writeFieldEnd(); + } + if (struct.responseBody != null) { + oprot.writeFieldBegin(RESPONSE_BODY_FIELD_DESC); + oprot.writeString(struct.responseBody); + oprot.writeFieldEnd(); + } + if (struct.responseHeader != null) { + oprot.writeFieldBegin(RESPONSE_HEADER_FIELD_DESC); + oprot.writeString(struct.responseHeader); + oprot.writeFieldEnd(); + } + if (struct.isSetParentSpanId()) { + oprot.writeFieldBegin(PARENT_SPAN_ID_FIELD_DESC); + oprot.writeI64(struct.parentSpanId); + oprot.writeFieldEnd(); + } + if (struct.isSetStatus()) { + oprot.writeFieldBegin(STATUS_FIELD_DESC); + oprot.writeByte(struct.status); + oprot.writeFieldEnd(); + } + if (struct.isSetWebBodyStrategy()) { + oprot.writeFieldBegin(WEB_BODY_STRATEGY_FIELD_DESC); + oprot.writeByte(struct.webBodyStrategy); + oprot.writeFieldEnd(); + } + if (struct.requestMethod != null) { + oprot.writeFieldBegin(REQUEST_METHOD_FIELD_DESC); + oprot.writeString(struct.requestMethod); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(STATUS_CODE_FIELD_DESC); + oprot.writeI32(struct.statusCode); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(ELAPSED_TIME_FIELD_DESC); + oprot.writeI32(struct.elapsedTime); + oprot.writeFieldEnd(); + if (struct.parentApplicationName != null) { + oprot.writeFieldBegin(PARENT_APPLICATION_NAME_FIELD_DESC); + oprot.writeString(struct.parentApplicationName); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + } + + private static class TSpanWebInfoTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { + public TSpanWebInfoTupleScheme getScheme() { + return new TSpanWebInfoTupleScheme(); + } + } + + private static class TSpanWebInfoTupleScheme extends org.apache.thrift.scheme.TupleScheme { + + @Override + public void write(org.apache.thrift.protocol.TProtocol prot, TSpanWebInfo struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; + java.util.BitSet optionals = new java.util.BitSet(); + if (struct.isSetVersion()) { + optionals.set(0); + } + if (struct.isSetAgentId()) { + optionals.set(1); + } + if (struct.isSetApplicationName()) { + optionals.set(2); + } + if (struct.isSetAgentStartTime()) { + optionals.set(3); + } + if (struct.isSetTransactionId()) { + optionals.set(4); + } + if (struct.isSetSpanId()) { + optionals.set(5); + } + if (struct.isSetRequestBody()) { + optionals.set(6); + } + if (struct.isSetRequestUrl()) { + optionals.set(7); + } + if (struct.isSetRequestHeader()) { + optionals.set(8); + } + if (struct.isSetResponseBody()) { + optionals.set(9); + } + if (struct.isSetResponseHeader()) { + optionals.set(10); + } + if (struct.isSetParentSpanId()) { + optionals.set(11); + } + if (struct.isSetStatus()) { + optionals.set(12); + } + if (struct.isSetWebBodyStrategy()) { + optionals.set(13); + } + if (struct.isSetRequestMethod()) { + optionals.set(14); + } + if (struct.isSetStatusCode()) { + optionals.set(15); + } + if (struct.isSetElapsedTime()) { + optionals.set(16); + } + if (struct.isSetParentApplicationName()) { + optionals.set(17); + } + oprot.writeBitSet(optionals, 18); + if (struct.isSetVersion()) { + oprot.writeByte(struct.version); + } + if (struct.isSetAgentId()) { + oprot.writeString(struct.agentId); + } + if (struct.isSetApplicationName()) { + oprot.writeString(struct.applicationName); + } + if (struct.isSetAgentStartTime()) { + oprot.writeI64(struct.agentStartTime); + } + if (struct.isSetTransactionId()) { + oprot.writeBinary(struct.transactionId); + } + if (struct.isSetSpanId()) { + oprot.writeI64(struct.spanId); + } + if (struct.isSetRequestBody()) { + oprot.writeString(struct.requestBody); + } + if (struct.isSetRequestUrl()) { + oprot.writeString(struct.requestUrl); + } + if (struct.isSetRequestHeader()) { + oprot.writeString(struct.requestHeader); + } + if (struct.isSetResponseBody()) { + oprot.writeString(struct.responseBody); + } + if (struct.isSetResponseHeader()) { + oprot.writeString(struct.responseHeader); + } + if (struct.isSetParentSpanId()) { + oprot.writeI64(struct.parentSpanId); + } + if (struct.isSetStatus()) { + oprot.writeByte(struct.status); + } + if (struct.isSetWebBodyStrategy()) { + oprot.writeByte(struct.webBodyStrategy); + } + if (struct.isSetRequestMethod()) { + oprot.writeString(struct.requestMethod); + } + if (struct.isSetStatusCode()) { + oprot.writeI32(struct.statusCode); + } + if (struct.isSetElapsedTime()) { + oprot.writeI32(struct.elapsedTime); + } + if (struct.isSetParentApplicationName()) { + oprot.writeString(struct.parentApplicationName); + } + } + + @Override + public void read(org.apache.thrift.protocol.TProtocol prot, TSpanWebInfo struct) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; + java.util.BitSet incoming = iprot.readBitSet(18); + if (incoming.get(0)) { + struct.version = iprot.readByte(); + struct.setVersionIsSet(true); + } + if (incoming.get(1)) { + struct.agentId = iprot.readString(); + struct.setAgentIdIsSet(true); + } + if (incoming.get(2)) { + struct.applicationName = iprot.readString(); + struct.setApplicationNameIsSet(true); + } + if (incoming.get(3)) { + struct.agentStartTime = iprot.readI64(); + struct.setAgentStartTimeIsSet(true); + } + if (incoming.get(4)) { + struct.transactionId = iprot.readBinary(); + struct.setTransactionIdIsSet(true); + } + if (incoming.get(5)) { + struct.spanId = iprot.readI64(); + struct.setSpanIdIsSet(true); + } + if (incoming.get(6)) { + struct.requestBody = iprot.readString(); + struct.setRequestBodyIsSet(true); + } + if (incoming.get(7)) { + struct.requestUrl = iprot.readString(); + struct.setRequestUrlIsSet(true); + } + if (incoming.get(8)) { + struct.requestHeader = iprot.readString(); + struct.setRequestHeaderIsSet(true); + } + if (incoming.get(9)) { + struct.responseBody = iprot.readString(); + struct.setResponseBodyIsSet(true); + } + if (incoming.get(10)) { + struct.responseHeader = iprot.readString(); + struct.setResponseHeaderIsSet(true); + } + if (incoming.get(11)) { + struct.parentSpanId = iprot.readI64(); + struct.setParentSpanIdIsSet(true); + } + if (incoming.get(12)) { + struct.status = iprot.readByte(); + struct.setStatusIsSet(true); + } + if (incoming.get(13)) { + struct.webBodyStrategy = iprot.readByte(); + struct.setWebBodyStrategyIsSet(true); + } + if (incoming.get(14)) { + struct.requestMethod = iprot.readString(); + struct.setRequestMethodIsSet(true); + } + if (incoming.get(15)) { + struct.statusCode = iprot.readI32(); + struct.setStatusCodeIsSet(true); + } + if (incoming.get(16)) { + struct.elapsedTime = iprot.readI32(); + struct.setElapsedTimeIsSet(true); + } + if (incoming.get(17)) { + struct.parentApplicationName = iprot.readString(); + struct.setParentApplicationNameIsSet(true); + } + } + } + + private static S scheme(org.apache.thrift.protocol.TProtocol proto) { + return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); + } +} + diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java index e82f50ca8426..61e74d416bda 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/io/DefaultTBaseLocator.java @@ -19,16 +19,7 @@ import com.navercorp.pinpoint.io.util.BodyFactory; import com.navercorp.pinpoint.io.util.TypeLocator; import com.navercorp.pinpoint.io.util.TypeLocatorBuilder; -import com.navercorp.pinpoint.thrift.dto.TAgentInfo; -import com.navercorp.pinpoint.thrift.dto.TAgentStat; -import com.navercorp.pinpoint.thrift.dto.TAgentStatBatch; -import com.navercorp.pinpoint.thrift.dto.TApiMetaData; -import com.navercorp.pinpoint.thrift.dto.TResult; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; -import com.navercorp.pinpoint.thrift.dto.TSqlMetaData; -import com.navercorp.pinpoint.thrift.dto.TStringMetaData; +import com.navercorp.pinpoint.thrift.dto.*; import org.apache.thrift.TBase; @@ -69,6 +60,8 @@ public class DefaultTBaseLocator { public static final short CHUNK = 400; + public static final short SPAN_WEB_INFO = 410; + private static final TypeLocator> typeLocator = build(); public static TypeLocator>build() { @@ -86,6 +79,13 @@ public static void addBodyFactory(TypeLocatorBuilder> builder) { } }); + builder.addBodyFactory(SPAN_WEB_INFO, new BodyFactory>() { + @Override + public TBase getObject() { + return new TSpanWebInfo(); + } + }); + builder.addBodyFactory(AGENT_INFO, new BodyFactory>() { @Override public TBase getObject() {