From 244969eaa7cb7f8b952400818f796193282fbf88 Mon Sep 17 00:00:00 2001 From: emeroad Date: Fri, 24 Mar 2017 11:56:28 +0900 Subject: [PATCH] [#2853] Optimize trace format of agent - Refactor TraceFormat --- .../receiver/udp/SpanStreamUDPSenderTest.java | 4 +- .../test/MockTraceContextFactory.java | 4 +- .../pinpoint/profiler/context/CallStack.java | 132 +---------- ...ckFactory.java => CallStackFactoryV1.java} | 14 +- .../profiler/context/CallStackFactoryV2.java | 34 +++ .../profiler/context/DefaultCallStack.java | 154 +++++++++++++ .../context/DepthCompressCallStack.java | 45 ++++ ...nkFactory.java => SpanChunkFactoryV1.java} | 37 ++-- .../profiler/context/SpanChunkFactoryV2.java | 104 +++++++++ .../pinpoint/profiler/context/SpanEvent.java | 19 +- .../profiler/context/SpanPostProcessor.java | 26 +++ .../profiler/context/SpanPostProcessorV1.java | 43 ++++ .../profiler/context/SpanPostProcessorV2.java | 47 ++++ .../context/TraceDataFormatVersion.java | 56 +++++ .../context/compress/SpanEventCompressor.java | 28 +++ .../compress/SpanEventCompressorV1.java | 45 ++++ .../compress/SpanEventCompressorV2.java | 91 ++++++++ .../compress/SpanEventSequenceComparator.java | 38 ++++ .../module/ApplicationContextModule.java | 16 +- .../provider/CallStackFactoryProvider.java | 56 +++++ .../provider/SpanChunkFactoryProvider.java | 77 +++++++ .../provider/SpanPostProcessorProvider.java | 54 +++++ .../provider/StorageFactoryProvider.java | 7 +- .../context/storage/BufferedStorage.java | 14 +- .../storage/BufferedStorageFactory.java | 8 +- .../profiler/context/CallStackTest.java | 59 ++--- .../context/DefaultCallStackTest.java | 55 +++++ .../profiler/context/DefaultTraceTest.java | 2 +- .../context/DepthCompressCallStackTest.java | 56 +++++ .../context/MockTraceContextFactory.java | 2 +- .../context/SpanChunkFactoryTest.java | 7 +- .../profiler/context/SpanEventTest.java | 8 +- .../pinpoint/profiler/context/TraceTest.java | 4 +- .../context/storage/BufferedStorageTest.java | 18 +- .../SpanStreamSendDataSerializerTest.java | 4 +- .../SpanChunkStreamSendDataPlanerTest.java | 4 +- .../navercorp/pinpoint/thrift/dto/TSpan.java | 110 ++++++++- .../pinpoint/thrift/dto/TSpanChunk.java | 208 +++++++++++++++++- .../pinpoint/thrift/dto/TraceConstants.java | 16 ++ thrift/src/main/thrift/Trace.thrift | 19 +- 40 files changed, 1489 insertions(+), 236 deletions(-) rename profiler/src/main/java/com/navercorp/pinpoint/profiler/context/{DefaultCallStackFactory.java => CallStackFactoryV1.java} (67%) create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV2.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStack.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStack.java rename profiler/src/main/java/com/navercorp/pinpoint/profiler/context/{DefaultSpanChunkFactory.java => SpanChunkFactoryV1.java} (68%) create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV2.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV1.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV2.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceDataFormatVersion.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV1.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV2.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventSequenceComparator.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/CallStackFactoryProvider.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanChunkFactoryProvider.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanPostProcessorProvider.java create mode 100644 profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackTest.java create mode 100644 profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStackTest.java create mode 100644 thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TraceConstants.java diff --git a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/SpanStreamUDPSenderTest.java b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/SpanStreamUDPSenderTest.java index 43ca68175c72..e24c7ee2e0e9 100644 --- a/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/SpanStreamUDPSenderTest.java +++ b/collector/src/test/java/com/navercorp/pinpoint/collector/receiver/udp/SpanStreamUDPSenderTest.java @@ -21,7 +21,7 @@ import com.navercorp.pinpoint.collector.receiver.AbstractDispatchHandler; import com.navercorp.pinpoint.collector.receiver.DataReceiver; import com.navercorp.pinpoint.common.trace.ServiceType; -import com.navercorp.pinpoint.profiler.context.DefaultSpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV1; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanChunk; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; @@ -152,7 +152,7 @@ private Span createSpan(int spanEventSize) throws InterruptedException { private SpanChunk createSpanChunk(int spanEventSize) throws InterruptedException { - SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory("applicationName", "agentId", 0, ServiceType.STAND_ALONE); + SpanChunkFactory spanChunkFactory = new SpanChunkFactoryV1("applicationName", "agentId", 0, ServiceType.STAND_ALONE); List originalSpanEventList = createSpanEventList(spanEventSize); SpanChunk spanChunk = spanChunkFactory.create(originalSpanEventList); diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java index f9837b323168..ce8f7f3fd646 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java @@ -28,7 +28,7 @@ import com.navercorp.pinpoint.profiler.context.id.AtomicIdGenerator; import com.navercorp.pinpoint.profiler.context.CallStackFactory; import com.navercorp.pinpoint.profiler.context.id.DefaultAsyncIdGenerator; -import com.navercorp.pinpoint.profiler.context.DefaultCallStackFactory; +import com.navercorp.pinpoint.profiler.context.CallStackFactoryV1; import com.navercorp.pinpoint.profiler.context.recorder.DefaultRecorderFactory; import com.navercorp.pinpoint.profiler.context.DefaultServerMetaDataHolder; import com.navercorp.pinpoint.profiler.context.DefaultSpanFactory; @@ -120,7 +120,7 @@ public MockTraceContextFactory(ProfilerConfig profilerConfig) { this.sqlMetaDataService = new DefaultSqlMetaDataService(agentId, agentStartTime, enhancedDataSender, jdbcSqlCacheSize); - CallStackFactory callStackFactory = new DefaultCallStackFactory(64); + CallStackFactory callStackFactory = new CallStackFactoryV1(64); TraceIdFactory traceIdFactory = new DefaultTraceIdFactory(agentId, agentStartTime, idGenerator); SpanFactory spanFactory = new DefaultSpanFactory(applicationName, agentId, agentStartTime, agentServiceType); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStack.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStack.java index b79ee8bf0f3c..344e7b57f84a 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStack.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStack.java @@ -1,11 +1,11 @@ /* - * Copyright 2014 NAVER Corp. + * Copyright 2017 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 + * 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, @@ -16,129 +16,21 @@ package com.navercorp.pinpoint.profiler.context; -import java.util.Arrays; - /** - * @author netspider - * @author emeroad - * @author jaehong.kim + * @author Woonduk Kang(emeroad) */ -public class CallStack { - private static final int STACK_SIZE = 8; - private static final int DEFAULT_INDEX = 0; - - private SpanEvent[] stack = new SpanEvent[STACK_SIZE]; - - private final Span span; - private final int maxDepth; - private int index = DEFAULT_INDEX; - private int overflowIndex = 0; - private short sequence; - private int latestStackIndex = 0; - - public CallStack(Span span) { - this(span, -1); - } - - public CallStack(Span span, int maxDepth) { - this.span = span; - this.maxDepth = maxDepth; - } - - public Span getSpan() { - return span; - } - - public int getIndex() { - if(isOverflow()) { - return index + overflowIndex; - } - - return index; - } - - public int push(final SpanEvent spanEvent) { - if (isOverflow()) { - overflowIndex++; - return index + overflowIndex; - } - - checkExtend(index + 1); - spanEvent.setSequence(sequence++); - stack[index++] = spanEvent; - if(latestStackIndex != index) { - latestStackIndex = index; - spanEvent.setDepth(latestStackIndex); - } - - return index; - } - - private void checkExtend(final int size) { - final SpanEvent[] originalStack = this.stack; - if (size >= originalStack.length) { - final int copyStackSize = originalStack.length << 1; - final SpanEvent[] copyStack = new SpanEvent[copyStackSize]; - System.arraycopy(originalStack, 0, copyStack, 0, originalStack.length); - this.stack = copyStack; - } - } - - public SpanEvent pop() { - if(isOverflow() && overflowIndex > 0) { - overflowIndex--; - return new SpanEvent(span); - } - - final SpanEvent spanEvent = peek(); - if (spanEvent != null) { - stack[index - 1] = null; - index--; - } - - return spanEvent; - } - - public SpanEvent peek() { - if (index == DEFAULT_INDEX) { - return null; - } - - if(isOverflow() && overflowIndex > 0) { - return new SpanEvent(span); - } +public interface CallStack { + int getIndex(); - return stack[index - 1]; - } + int push(SpanEvent spanEvent); - public boolean empty() { - return index == DEFAULT_INDEX; - } + SpanEvent pop(); - public SpanEvent[] copyStackFrame() { - // without synchronization arraycopy, last index is null reference - final SpanEvent[] currentStack = this.stack; - final SpanEvent[] copyStack = new SpanEvent[currentStack.length]; - System.arraycopy(currentStack, 0, copyStack, 0, currentStack.length); - return copyStack; - } + SpanEvent peek(); - public int getMaxDepth() { - return maxDepth; - } + boolean empty(); - boolean isOverflow() { - return maxDepth != -1 && maxDepth < index; - } + SpanEvent[] copyStackFrame(); - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("{stack="); - builder.append(Arrays.toString(stack)); - builder.append(", index="); - builder.append(index); - builder.append("}"); - return builder.toString(); - } -} \ No newline at end of file + int getMaxDepth(); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV1.java similarity index 67% rename from profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackFactory.java rename to profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV1.java index 8521dfa1ed5f..328ef7d46f80 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV1.java @@ -16,27 +16,19 @@ package com.navercorp.pinpoint.profiler.context; -import com.google.inject.Inject; -import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; - /** * @author Woonduk Kang(emeroad) */ -public class DefaultCallStackFactory implements CallStackFactory { +public class CallStackFactoryV1 implements CallStackFactory { private final int maxDepth; - @Inject - public DefaultCallStackFactory(ProfilerConfig profilerConfig) { - this(profilerConfig.getCallStackMaxDepth()); - } - - public DefaultCallStackFactory(int maxDepth) { + public CallStackFactoryV1(int maxDepth) { this.maxDepth = maxDepth; } @Override public CallStack newCallStack(Span span) { - return new CallStack(span, maxDepth); + return new DepthCompressCallStack(span, maxDepth); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV2.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV2.java new file mode 100644 index 000000000000..34a7ded2cded --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/CallStackFactoryV2.java @@ -0,0 +1,34 @@ +/* + * Copyright 2017 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; + +/** + * @author Woonduk Kang(emeroad) + */ +public class CallStackFactoryV2 implements CallStackFactory { + + private final int maxDepth; + + public CallStackFactoryV2(int maxDepth) { + this.maxDepth = maxDepth; + } + + @Override + public CallStack newCallStack(Span span) { + return new DefaultCallStack(span, maxDepth); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStack.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStack.java new file mode 100644 index 000000000000..5f5c30596579 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultCallStack.java @@ -0,0 +1,154 @@ +/* + * Copyright 2017 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.annotations.VisibleForTesting; + +import java.util.Arrays; + +/** + * @author netspider + * @author Woonduk Kang(emeroad) + * @author jaehong.kim + */ +public class DefaultCallStack implements CallStack { + protected static final int STACK_SIZE = 8; + protected static final int DEFAULT_INDEX = 0; + + protected SpanEvent[] stack = new SpanEvent[STACK_SIZE]; + + protected final Span span; + protected final int maxDepth; + protected int index = DEFAULT_INDEX; + protected int overflowIndex = 0; + protected short sequence; + + public DefaultCallStack(Span span) { + this(span, -1); + } + + public DefaultCallStack(Span span, int maxDepth) { + this.span = span; + this.maxDepth = maxDepth; + } + + + @Override + public int getIndex() { + if (isOverflow()) { + return index + overflowIndex; + } + + return index; + } + + @Override + public int push(final SpanEvent spanEvent) { + if (isOverflow()) { + overflowIndex++; + return index + overflowIndex; + } + + checkExtend(index + 1); + spanEvent.setSequence(sequence++); + stack[index++] = spanEvent; + markDepth(spanEvent, index); + return index; + } + + protected void markDepth(SpanEvent spanEvent, int index) { + spanEvent.setDepth(index); + } + + protected void checkExtend(final int size) { + final SpanEvent[] originalStack = this.stack; + if (size >= originalStack.length) { + final int copyStackSize = originalStack.length << 1; + final SpanEvent[] copyStack = new SpanEvent[copyStackSize]; + System.arraycopy(originalStack, 0, copyStack, 0, originalStack.length); + this.stack = copyStack; + } + } + + @Override + public SpanEvent pop() { + if (isOverflow() && overflowIndex > 0) { + overflowIndex--; + return newDummySpanEvent(); + } + + final SpanEvent spanEvent = peek(); + if (spanEvent != null) { + stack[index - 1] = null; + index--; + } + + return spanEvent; + } + + private SpanEvent newDummySpanEvent() { + return new SpanEvent(span); + } + + @Override + public SpanEvent peek() { + if (index == DEFAULT_INDEX) { + return null; + } + + if (isOverflow() && overflowIndex > 0) { + return newDummySpanEvent(); + } + + return stack[index - 1]; + } + + @Override + public boolean empty() { + return index == DEFAULT_INDEX; + } + + @Override + public SpanEvent[] copyStackFrame() { + // without synchronization arraycopy, last index is null reference + final SpanEvent[] currentStack = this.stack; + final SpanEvent[] copyStack = new SpanEvent[currentStack.length]; + System.arraycopy(currentStack, 0, copyStack, 0, currentStack.length); + return copyStack; + } + + @Override + public int getMaxDepth() { + return maxDepth; + } + + @VisibleForTesting + boolean isOverflow() { + return maxDepth != -1 && maxDepth < index; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{stack="); + builder.append(Arrays.toString(stack)); + builder.append(", index="); + builder.append(index); + builder.append("}"); + return builder.toString(); + } +} \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStack.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStack.java new file mode 100644 index 000000000000..846752a43696 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStack.java @@ -0,0 +1,45 @@ +/* + * 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.profiler.context; + +/** + * @author Woonduk Kang(emeroad) + */ +public class DepthCompressCallStack extends DefaultCallStack { + + private int latestStackIndex = 0; + + public DepthCompressCallStack(Span span) { + this(span, -1); + } + + public DepthCompressCallStack(Span span, int maxDepth) { + super(span, maxDepth); + } + + @Override + protected void markDepth(SpanEvent spanEvent, int depth) { + // compact same depth + if (latestStackIndex != index) { + latestStackIndex = index; + spanEvent.setDepth(latestStackIndex); + } + } + + + +} \ 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/SpanChunkFactoryV1.java similarity index 68% rename from profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java rename to profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV1.java index c2589aa2c402..9e471d31a0d6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultSpanChunkFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV1.java @@ -16,27 +16,34 @@ package com.navercorp.pinpoint.profiler.context; -import com.google.inject.Inject; import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.common.util.CollectionUtils; import com.navercorp.pinpoint.profiler.context.module.AgentId; import com.navercorp.pinpoint.profiler.context.module.AgentStartTime; import com.navercorp.pinpoint.profiler.context.module.ApplicationName; import com.navercorp.pinpoint.profiler.context.module.ApplicationServerType; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressor; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressorV1; import java.util.List; /** * @author Woonduk Kang(emeroad) */ -public class DefaultSpanChunkFactory implements SpanChunkFactory { +public class SpanChunkFactoryV1 implements SpanChunkFactory { + +// private static final TraceDataFormatVersion V1 = TraceDataFormatVersion.V1; + private final String applicationName; private final String agentId; private final long agentStartTime; private final ServiceType applicationServiceType; - @Inject - public DefaultSpanChunkFactory(@ApplicationName String applicationName, @AgentId String agentId, @AgentStartTime long agentStartTime, - @ApplicationServerType ServiceType applicationServiceType) { + private final SpanEventCompressor spanEventCompressor = new SpanEventCompressorV1(); + + + public SpanChunkFactoryV1(@ApplicationName String applicationName, @AgentId String agentId, @AgentStartTime long agentStartTime, + @ApplicationServerType ServiceType applicationServiceType) { if (applicationName == null) { throw new NullPointerException("applicationName must not be null"); @@ -55,30 +62,30 @@ public DefaultSpanChunkFactory(@ApplicationName String applicationName, @AgentId } @Override - public SpanChunk create(final List flushData) { - if (flushData == null) { - throw new NullPointerException("flushData must not be null"); - } - // TODO must be equals to or greater than 1 - final int size = flushData.size(); - if (size < 1) { - throw new IllegalArgumentException("flushData.size() < 1 size:" + size); + public SpanChunk create(final List spanEventList) { + if (CollectionUtils.isEmpty(spanEventList)) { + throw new IllegalArgumentException("spanEventList is empty."); } - final SpanEvent first = flushData.get(0); + final SpanEvent first = spanEventList.get(0); if (first == null) { throw new IllegalStateException("first SpanEvent is null"); } final Span parentSpan = first.getSpan(); - final SpanChunk spanChunk = new SpanChunk(flushData); + final SpanChunk spanChunk = new SpanChunk(spanEventList); +// skip default version +// spanChunk.setVersion(V1.getVersion()); + spanChunk.setAgentId(agentId); spanChunk.setApplicationName(applicationName); spanChunk.setAgentStartTime(agentStartTime); spanChunk.setApplicationServiceType(applicationServiceType.getCode()); + spanEventCompressor.compress(spanEventList, parentSpan.getStartTime()); + final byte[] transactionId = parentSpan.getTransactionId(); spanChunk.setTransactionId(transactionId); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV2.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV2.java new file mode 100644 index 000000000000..6d9857defc9f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryV2.java @@ -0,0 +1,104 @@ +/* + * Copyright 2017 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.trace.ServiceType; +import com.navercorp.pinpoint.common.util.CollectionUtils; +import com.navercorp.pinpoint.profiler.context.module.AgentId; +import com.navercorp.pinpoint.profiler.context.module.AgentStartTime; +import com.navercorp.pinpoint.profiler.context.module.ApplicationName; +import com.navercorp.pinpoint.profiler.context.module.ApplicationServerType; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressor; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressorV2; + +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanChunkFactoryV2 implements SpanChunkFactory { + + private static final TraceDataFormatVersion V2 = TraceDataFormatVersion.V2; + + private final String applicationName; + private final String agentId; + private final long agentStartTime; + private final ServiceType applicationServiceType; + + private final SpanEventCompressor spanEventCompressor = new SpanEventCompressorV2(); + + public SpanChunkFactoryV2(@ApplicationName String applicationName, @AgentId String agentId, @AgentStartTime long agentStartTime, + @ApplicationServerType ServiceType applicationServiceType) { + + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (applicationServiceType == null) { + throw new NullPointerException("applicationServiceType must not be null"); + } + + this.applicationName = applicationName; + this.agentId = agentId; + this.agentStartTime = agentStartTime; + this.applicationServiceType = applicationServiceType; + } + + @Override + public SpanChunk create(final List spanEventList) { + if (CollectionUtils.isEmpty(spanEventList)) { + throw new IllegalArgumentException("spanEventList is empty."); + } + + final SpanEvent first = spanEventList.get(0); + if (first == null) { + throw new IllegalStateException("first SpanEvent is null"); + } + + final Span parentSpan = first.getSpan(); + + + final SpanChunk spanChunk = new SpanChunk(spanEventList); + spanChunk.setVersion(V2.getVersion()); + + spanChunk.setAgentId(agentId); + spanChunk.setApplicationName(applicationName); + spanChunk.setAgentStartTime(agentStartTime); + spanChunk.setApplicationServiceType(applicationServiceType.getCode()); + + + final long keyTime = first.getStartTime(); + spanChunk.setKeyTime(keyTime); + // TODO change data compression timing to another thread eg: DataSender thread + spanEventCompressor.compress(spanEventList, keyTime); + + final byte[] transactionId = parentSpan.getTransactionId(); + spanChunk.setTransactionId(transactionId); + + + spanChunk.setSpanId(parentSpan.getSpanId()); + + spanChunk.setEndPoint(parentSpan.getEndPoint()); + + + + return spanChunk; + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEvent.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEvent.java index 0d5c0a4ea107..07479e56c441 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEvent.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanEvent.java @@ -34,6 +34,8 @@ public class SpanEvent extends TSpanEvent implements FrameAttachment { private int stackId; private boolean timeRecording = true; private Object frameObject; + private long startTime; + private long afterTime; public SpanEvent(Span span) { if (span == null) { @@ -69,27 +71,20 @@ void setExceptionInfo(int exceptionClassId, String exceptionMessage) { public void markStartTime() { -// spanEvent.setStartElapsed((int) (startTime - parentSpanStartTime)); - final int startElapsed = (int)(System.currentTimeMillis() - span.getStartTime()); - - // If startElapsed is 0, logic without mark is useless. Don't do that. - // The first SpanEvent of a Span could result in 0. Not likely afterwards. - this.setStartElapsed(startElapsed); + this.startTime = System.currentTimeMillis(); } public long getStartTime() { - return span.getStartTime() + getStartElapsed(); + return startTime; } public void markAfterTime() { - final int endElapsed = (int)(System.currentTimeMillis() - getStartTime()); - if (endElapsed != 0) { - this.setEndElapsed(endElapsed); - } + this.afterTime = System.currentTimeMillis(); + } public long getAfterTime() { - return span.getStartTime() + getStartElapsed() + getEndElapsed(); + return afterTime; } public int getStackId() { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessor.java new file mode 100644 index 000000000000..ff66a822c8e4 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessor.java @@ -0,0 +1,26 @@ +/* + * Copyright 2017 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 java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public interface SpanPostProcessor { + Span postProcess(Span span, List spanEventList); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV1.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV1.java new file mode 100644 index 000000000000..963d418a2d48 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV1.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 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.profiler.context.compress.SpanEventCompressor; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressorV1; + +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanPostProcessorV1 implements SpanPostProcessor { + +// private final byte version = TraceDataFormatConstants.V1; + private final SpanEventCompressor spanEventCompressor = new SpanEventCompressorV1(); + + @Override + public Span postProcess(Span span, List spanEventList) { +// skip default version +// span.setVersion(version); + + long spanStartTime = span.getStartTime(); + spanEventCompressor.compress(spanEventList, spanStartTime); + + span.setSpanEventList((List) spanEventList); + return span; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV2.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV2.java new file mode 100644 index 000000000000..243054bf944e --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/SpanPostProcessorV2.java @@ -0,0 +1,47 @@ +/* + * Copyright 2017 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.profiler.context.compress.SpanEventCompressor; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressorV2; + +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanPostProcessorV2 implements SpanPostProcessor { + + private static final TraceDataFormatVersion V2 = TraceDataFormatVersion.V2; + + // TODO refactor injector + private final SpanEventCompressor spanEventCompressor = new SpanEventCompressorV2(); + + @Override + public Span postProcess(Span span, List spanEventList) { + + span.setVersion(V2.getVersion()); + + long spanStartTime = span.getStartTime(); + + spanEventCompressor.compress(spanEventList, spanStartTime); + + span.setSpanEventList((List)spanEventList); + + return span; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceDataFormatVersion.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceDataFormatVersion.java new file mode 100644 index 000000000000..87d015801997 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/TraceDataFormatVersion.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 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.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.thrift.dto.TraceConstants; + +/** + * @author Woonduk Kang(emeroad) + */ +public enum TraceDataFormatVersion { + + V1(TraceConstants.TRACE_V1), + V2(TraceConstants.TRACE_V2); + + private static final String TRACE_VERSION_NAME = "profiler.trace.dataformat.version"; + + private byte version; + + TraceDataFormatVersion(byte version) { + this.version = version; + } + + public byte getVersion() { + return version; + } + + public static TraceDataFormatVersion getTraceDataFormatVersion(ProfilerConfig profilerConfig) { + if (profilerConfig == null) { + throw new NullPointerException("profilerConfig must not be null"); + } + + final String lowerCaseVersion = profilerConfig.readString(TRACE_VERSION_NAME, "v1").toLowerCase(); + if ("v2".equals(lowerCaseVersion)) { + return V2; + } + if("v1".equals(lowerCaseVersion)) { + return V1; + } + throw new UnsupportedOperationException("unknown profiler.trace.dataformat.version:" + lowerCaseVersion); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressor.java new file mode 100644 index 000000000000..dd4e0f715d65 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressor.java @@ -0,0 +1,28 @@ +/* + * Copyright 2017 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.compress; + +import com.navercorp.pinpoint.profiler.context.SpanEvent; + +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public interface SpanEventCompressor { + void compress(List spanEventList, T context); +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV1.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV1.java new file mode 100644 index 000000000000..47c938ca1759 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV1.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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.compress; + +import com.navercorp.pinpoint.profiler.context.SpanEvent; + +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanEventCompressorV1 implements SpanEventCompressor { + + @Override + public void compress(List spanEventList, final Long keyTime) { + + final long prevKeyTime = keyTime; + for (final SpanEvent spanEvent : spanEventList) { + final long startTime = spanEvent.getStartTime(); + final long startElapsedTime = startTime - prevKeyTime; + spanEvent.setStartElapsed((int) startElapsedTime); + + + final long endElapsedTime = spanEvent.getAfterTime() - startTime; + if (endElapsedTime != 0) { + spanEvent.setEndElapsed((int) endElapsedTime); + } + } + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV2.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV2.java new file mode 100644 index 000000000000..d4444df52d19 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventCompressorV2.java @@ -0,0 +1,91 @@ +/* + * Copyright 2017 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.compress; + +import com.navercorp.pinpoint.profiler.context.SpanEvent; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanEventCompressorV2 implements SpanEventCompressor { + + private final static Comparator SEQUENCE_COMPARATOR = SpanEventSequenceComparator.INSTANCE; + + @Override + public void compress(List spanEventList, final Long keyTime) { + // sort list for data compression + Collections.sort(spanEventList, SEQUENCE_COMPARATOR); + + compressTime(spanEventList, keyTime); + compressDepth(spanEventList); + } + + private void compressTime(List spanEventList, Long keyTime) { + long prevKeyTime = keyTime; + + + final int size = spanEventList.size(); + for (int i = 0; i < size; i++) { + final SpanEvent spanEvent = spanEventList.get(i); + + final long startTime = spanEvent.getStartTime(); + final long startElapsedTime = startTime - prevKeyTime; + spanEvent.setStartElapsed((int) startElapsedTime); + + + final long endElapsedTime = spanEvent.getAfterTime() - startTime; + if (endElapsedTime != 0) { + spanEvent.setEndElapsed((int) endElapsedTime); + } + + // save next KeyFrame; + prevKeyTime = startTime; + } + } + + + /** + * Skip depth to Span or SpanChunk scope + * @param spanEventList + */ + private void compressDepth(List spanEventList) { + boolean first = true; + int prevDepth = 0; + + final int size = spanEventList.size(); + for (int i = 0; i < size; i++) { + final SpanEvent spanEvent = spanEventList.get(i); + + if (first) { + first = false; + prevDepth = spanEvent.getDepth(); + } else { + final int currentDepth = spanEvent.getDepth(); + if (currentDepth == prevDepth) { + // skip + spanEvent.unsetDepth(); + } + prevDepth = currentDepth; + } + + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventSequenceComparator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventSequenceComparator.java new file mode 100644 index 000000000000..1385e7ce9f98 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/SpanEventSequenceComparator.java @@ -0,0 +1,38 @@ +/* + * Copyright 2017 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.compress; + +import com.navercorp.pinpoint.profiler.context.SpanEvent; + +import java.util.Comparator; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanEventSequenceComparator implements Comparator { + + public static final Comparator INSTANCE = new SpanEventSequenceComparator(); + + @Override + public int compare(SpanEvent o1, SpanEvent o2) { + return compareShort(o1.getSequence(), o2.getSequence()); + } + + private static int compareShort(short x, short y) { + return x - y; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java index 6afd5fae622b..c3754fed35bd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java @@ -25,6 +25,11 @@ import com.navercorp.pinpoint.bootstrap.context.ServerMetaDataHolder; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessor; +import com.navercorp.pinpoint.profiler.context.provider.CallStackFactoryProvider; +import com.navercorp.pinpoint.profiler.context.provider.SpanChunkFactoryProvider; +import com.navercorp.pinpoint.profiler.context.provider.SpanPostProcessorProvider; +import com.navercorp.pinpoint.profiler.instrument.InstrumentEngine; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcContext; import com.navercorp.pinpoint.bootstrap.sampler.Sampler; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; @@ -36,8 +41,10 @@ import com.navercorp.pinpoint.profiler.DynamicTransformerRegistry; import com.navercorp.pinpoint.profiler.JvmInformation; import com.navercorp.pinpoint.profiler.context.CallStackFactory; -import com.navercorp.pinpoint.profiler.context.DefaultCallStackFactory; -import com.navercorp.pinpoint.profiler.context.DefaultSpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorRegistryService; +import com.navercorp.pinpoint.profiler.context.monitor.DefaultJdbcContext; +import com.navercorp.pinpoint.profiler.context.monitor.JdbcUrlParsingService; +import com.navercorp.pinpoint.profiler.context.recorder.DefaultRecorderFactory; import com.navercorp.pinpoint.profiler.context.DefaultSpanFactory; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; import com.navercorp.pinpoint.profiler.context.SpanFactory; @@ -216,10 +223,11 @@ protected void configure() { private void bindTraceComponent() { bind(TraceIdFactory.class).to(DefaultTraceIdFactory.class).in(Scopes.SINGLETON); - bind(CallStackFactory.class).to(DefaultCallStackFactory.class).in(Scopes.SINGLETON); + bind(CallStackFactory.class).toProvider(CallStackFactoryProvider.class).in(Scopes.SINGLETON); bind(SpanFactory.class).to(DefaultSpanFactory.class).in(Scopes.SINGLETON); - bind(SpanChunkFactory.class).to(DefaultSpanChunkFactory.class).in(Scopes.SINGLETON); + bind(SpanPostProcessor.class).toProvider(SpanPostProcessorProvider.class).in(Scopes.SINGLETON); + bind(SpanChunkFactory.class).toProvider(SpanChunkFactoryProvider.class).in(Scopes.SINGLETON); bind(RecorderFactory.class).to(DefaultRecorderFactory.class).in(Scopes.SINGLETON); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/CallStackFactoryProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/CallStackFactoryProvider.java new file mode 100644 index 000000000000..e7ccc3a70caf --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/CallStackFactoryProvider.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 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.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.profiler.context.CallStackFactory; +import com.navercorp.pinpoint.profiler.context.CallStackFactoryV1; +import com.navercorp.pinpoint.profiler.context.CallStackFactoryV2; +import com.navercorp.pinpoint.profiler.context.TraceDataFormatVersion; + +/** + * @author Woonduk Kang(emeroad) + */ +public class CallStackFactoryProvider implements Provider { + + private final TraceDataFormatVersion version; + private final int callStackMaxDepth; + + + @Inject + public CallStackFactoryProvider(ProfilerConfig profilerConfig) { + if (profilerConfig == null) { + throw new NullPointerException("profilerConfig must not be null"); + } + this.version = TraceDataFormatVersion.getTraceDataFormatVersion(profilerConfig); + this.callStackMaxDepth = profilerConfig.getCallStackMaxDepth(); + } + + @Override + public CallStackFactory get() { + if (version == TraceDataFormatVersion.V2) { + return new CallStackFactoryV2(callStackMaxDepth); + } + if(version == TraceDataFormatVersion.V1) { + return new CallStackFactoryV1(callStackMaxDepth); + } + throw new UnsupportedOperationException("unknown version :" + version); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanChunkFactoryProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanChunkFactoryProvider.java new file mode 100644 index 000000000000..8d965d68dad2 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanChunkFactoryProvider.java @@ -0,0 +1,77 @@ +/* + * Copyright 2017 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.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV1; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV2; +import com.navercorp.pinpoint.profiler.context.TraceDataFormatVersion; +import com.navercorp.pinpoint.profiler.context.module.AgentId; +import com.navercorp.pinpoint.profiler.context.module.AgentStartTime; +import com.navercorp.pinpoint.profiler.context.module.ApplicationName; +import com.navercorp.pinpoint.profiler.context.module.ApplicationServerType; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanChunkFactoryProvider implements Provider { + + private final String applicationName; + private final String agentId; + private final long agentStartTime; + private final ServiceType applicationServiceType; + private final TraceDataFormatVersion version; + + + @Inject + public SpanChunkFactoryProvider(ProfilerConfig profilerConfig, @ApplicationName String applicationName, @AgentId String agentId, @AgentStartTime long agentStartTime, + @ApplicationServerType ServiceType applicationServiceType) { + + if (applicationName == null) { + throw new NullPointerException("applicationName must not be null"); + } + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + if (applicationServiceType == null) { + throw new NullPointerException("applicationServiceType must not be null"); + } + + this.applicationName = applicationName; + this.agentId = agentId; + this.agentStartTime = agentStartTime; + this.applicationServiceType = applicationServiceType; + + this.version = TraceDataFormatVersion.getTraceDataFormatVersion(profilerConfig); + } + + + @Override + public SpanChunkFactory get() { + if (this.version == TraceDataFormatVersion.V2) { + return new SpanChunkFactoryV2(applicationName, agentId, agentStartTime, applicationServiceType); + } + if (this.version == TraceDataFormatVersion.V1) { + return new SpanChunkFactoryV1(applicationName, agentId, agentStartTime, applicationServiceType); + } + throw new UnsupportedOperationException("unknown version :" + version); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanPostProcessorProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanPostProcessorProvider.java new file mode 100644 index 000000000000..a872c8d3ef7c --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/SpanPostProcessorProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017 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.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessor; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessorV1; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessorV2; +import com.navercorp.pinpoint.profiler.context.TraceDataFormatVersion; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanPostProcessorProvider implements Provider { + + private final TraceDataFormatVersion version; + + @Inject + public SpanPostProcessorProvider(ProfilerConfig profilerConfig) { + if (profilerConfig == null) { + throw new NullPointerException("profilerConfig must not be null"); + } + + this.version = TraceDataFormatVersion.getTraceDataFormatVersion(profilerConfig); + } + + @Override + public SpanPostProcessor get() { + if (version == TraceDataFormatVersion.V2) { + return new SpanPostProcessorV2(); + } + if (version == TraceDataFormatVersion.V1) { + return new SpanPostProcessorV1(); + } + throw new UnsupportedOperationException("unknown version :" + version); + } + +} 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 417b57e9abaf..9abfc9f91094 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 @@ -20,6 +20,7 @@ import com.google.inject.Provider; import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessor; import com.navercorp.pinpoint.profiler.context.module.SpanDataSender; import com.navercorp.pinpoint.profiler.context.storage.BufferedStorageFactory; import com.navercorp.pinpoint.profiler.context.storage.SpanStorageFactory; @@ -33,10 +34,11 @@ public class StorageFactoryProvider implements Provider { private final ProfilerConfig profilerConfig; private final DataSender spanDataSender; + private final SpanPostProcessor spanPostProcessor; private final SpanChunkFactory spanChunkFactory; @Inject - public StorageFactoryProvider(ProfilerConfig profilerConfig, @SpanDataSender DataSender spanDataSender, SpanChunkFactory spanChunkFactory) { + public StorageFactoryProvider(ProfilerConfig profilerConfig, @SpanDataSender DataSender spanDataSender, SpanPostProcessor spanPostProcessor, SpanChunkFactory spanChunkFactory) { if (profilerConfig == null) { throw new NullPointerException("profilerConfig must not be null"); } @@ -49,6 +51,7 @@ public StorageFactoryProvider(ProfilerConfig profilerConfig, @SpanDataSender Dat this.profilerConfig = profilerConfig; this.spanDataSender = spanDataSender; + this.spanPostProcessor = spanPostProcessor; this.spanChunkFactory = spanChunkFactory; } @@ -56,7 +59,7 @@ public StorageFactoryProvider(ProfilerConfig profilerConfig, @SpanDataSender Dat public StorageFactory get() { if (profilerConfig.isIoBufferingEnable()) { int ioBufferingBufferSize = this.profilerConfig.getIoBufferingBufferSize(); - return new BufferedStorageFactory(ioBufferingBufferSize, this.spanDataSender, this.spanChunkFactory); + return new BufferedStorageFactory(ioBufferingBufferSize, this.spanDataSender, this.spanPostProcessor, this.spanChunkFactory); } else { return new SpanStorageFactory(spanDataSender); } 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 9fb81d97bc78..60aa541f2782 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 @@ -40,20 +40,26 @@ public class BufferedStorage implements Storage { private List storage; private final DataSender dataSender; + + private final SpanPostProcessor spanPostProcessor; private final SpanChunkFactory spanChunkFactory; - public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory) { - this(dataSender, spanChunkFactory, DEFAULT_BUFFER_SIZE); + public BufferedStorage(DataSender dataSender, SpanPostProcessor spanPostProcessor, SpanChunkFactory spanChunkFactory) { + this(dataSender, spanPostProcessor, spanChunkFactory, DEFAULT_BUFFER_SIZE); } - public BufferedStorage(DataSender dataSender, SpanChunkFactory spanChunkFactory, int bufferSize) { + public BufferedStorage(DataSender dataSender, SpanPostProcessor spanPostProcessor, SpanChunkFactory spanChunkFactory, int bufferSize) { if (dataSender == null) { throw new NullPointerException("dataSender must not be null"); } + if (spanPostProcessor == null) { + throw new NullPointerException("spanPostProcessor must not be null"); + } if (spanChunkFactory == null) { throw new NullPointerException("spanChunkFactory must not be null"); } this.dataSender = dataSender; + this.spanPostProcessor = spanPostProcessor; this.spanChunkFactory = spanChunkFactory; this.bufferSize = bufferSize; this.storage = allocateBuffer(); @@ -102,7 +108,7 @@ private List clearBuffer() { public void store(Span span) { final List storage = clearBuffer(); if (CollectionUtils.isNotEmpty(storage)) { - span.setSpanEventList((List) storage); + span = spanPostProcessor.postProcess(span, storage); } dataSender.send(span); 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 32e85dcf0635..02bc5b1e2d09 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 @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.profiler.context.storage; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessor; import com.navercorp.pinpoint.profiler.sender.DataSender; /** @@ -26,9 +27,10 @@ public class BufferedStorageFactory implements StorageFactory { private final DataSender dataSender; private final int ioBufferingBufferSize; + private final SpanPostProcessor spanPostProcessor; private final SpanChunkFactory spanChunkFactory; - public BufferedStorageFactory(int ioBufferingBufferSize, DataSender dataSender, SpanChunkFactory spanChunkFactory) { + public BufferedStorageFactory(int ioBufferingBufferSize, DataSender dataSender, SpanPostProcessor spanPostProcessor, SpanChunkFactory spanChunkFactory) { if (dataSender == null) { throw new NullPointerException("dataSender must not be null"); } @@ -38,14 +40,14 @@ public BufferedStorageFactory(int ioBufferingBufferSize, DataSender dataSender, this.dataSender = dataSender; this.ioBufferingBufferSize = ioBufferingBufferSize; - + this.spanPostProcessor = spanPostProcessor; this.spanChunkFactory = spanChunkFactory; } @Override public Storage createStorage() { - BufferedStorage bufferedStorage = new BufferedStorage(this.dataSender, spanChunkFactory, this.ioBufferingBufferSize); + BufferedStorage bufferedStorage = new BufferedStorage(this.dataSender, spanPostProcessor, spanChunkFactory, this.ioBufferingBufferSize); return bufferedStorage; } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java index bb712a908256..f41976e64bad 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/CallStackTest.java @@ -29,17 +29,18 @@ * @author emeroad * @author jaehong.kim */ -public class CallStackTest { +public abstract class CallStackTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); - private Span span; - private SpanEvent spanEvent; - @Before - public void before() { - span = new Span(); - spanEvent = new SpanEvent(span); - } + abstract CallStack newCallStack(); + abstract CallStack newCallStack(int depth); + + + abstract Span getSpan(); + abstract SpanEvent getSpanEvent(); + private SpanEvent createSpanEventStackFrame(Span span) { SpanEvent spanEvent = new SpanEvent(span); @@ -48,24 +49,27 @@ private SpanEvent createSpanEventStackFrame(Span span) { @Test public void testPush() throws Exception { - CallStack callStack = new CallStack(span); + CallStack callStack = newCallStack(); int initialIndex = callStack.getIndex(); assertEquals("initial index", initialIndex, 0); - SpanEvent spanEvent = createSpanEventStackFrame(span); + SpanEvent spanEvent = createSpanEventStackFrame(getSpan()); int index = callStack.push(spanEvent); assertEquals("initial index", index, 1); callStack.pop(); } + + + @Test public void testLargePush() { - CallStack callStack = new CallStack(span); + CallStack callStack = newCallStack(); int initialIndex = callStack.getIndex(); Assert.assertEquals("initial index", initialIndex, 0); final int pushCount = 32; for (int i = 0; i < pushCount; i++) { - int push = callStack.push(spanEvent); + int push = callStack.push(getSpanEvent()); Assert.assertEquals("push index", i + 1, push); int index = callStack.getIndex(); Assert.assertEquals("index", i + 1, index); @@ -78,18 +82,18 @@ public void testLargePush() { @Test public void testPushPop1() { - CallStack callStack = new CallStack(span); + CallStack callStack = newCallStack(); - callStack.push(spanEvent); + callStack.push(getSpanEvent()); callStack.pop(); } @Test public void testPushPop2() { - CallStack callStack = new CallStack(span); + CallStack callStack = newCallStack(); - callStack.push(spanEvent); - callStack.push(spanEvent); + callStack.push(getSpanEvent()); + callStack.push(getSpanEvent()); callStack.pop(); callStack.pop(); @@ -97,10 +101,10 @@ public void testPushPop2() { @Test public void testPop_Fail() { - CallStack callStack = new CallStack(span); + CallStack callStack = newCallStack(); - callStack.push(spanEvent); - callStack.push(spanEvent); + callStack.push(getSpanEvent()); + callStack.push(getSpanEvent()); callStack.pop(); callStack.pop(); @@ -110,17 +114,18 @@ public void testPop_Fail() { @Test public void overflow() { final int maxDepth = 3; - - CallStack callStack = new CallStack(span, maxDepth); + + DefaultCallStack callStack = (DefaultCallStack) newCallStack(maxDepth); assertEquals(maxDepth, callStack.getMaxDepth()); - + for(int i = 0; i < maxDepth; i++) { - assertEquals(i + 1, callStack.push(spanEvent)); + assertEquals(i + 1, callStack.push(getSpanEvent())); } // overflow - int overflowIndex = callStack.push(spanEvent); + int overflowIndex = callStack.push(getSpanEvent()); assertEquals(maxDepth + 1, overflowIndex); assertEquals(maxDepth + 1, callStack.getIndex()); + assertTrue(callStack.isOverflow()); assertNotNull(callStack.peek()); // check inner index value. @@ -128,14 +133,14 @@ public void overflow() { assertNotNull(callStack.pop()); assertEquals(maxDepth, callStack.getIndex()); - + // normal for(int i = maxDepth; i > 0; i--) { assertNotNull(callStack.peek()); assertNotNull(callStack.pop()); assertEquals(i - 1, callStack.getIndex()); } - + // low overflow assertNull(callStack.pop()); assertNull(callStack.peek()); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackTest.java new file mode 100644 index 000000000000..67ab26ca64d2 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultCallStackTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017 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 org.junit.Before; + +/** + * @author emeroad + * @author jaehong.kim + */ +public class DefaultCallStackTest extends CallStackTest { + + private Span span; + private SpanEvent spanEvent; + + @Before + public void before() { + span = new Span(); + spanEvent = new SpanEvent(span); + } + + @Override + public CallStack newCallStack() { + return new DefaultCallStack(span); + } + + @Override + public CallStack newCallStack(int depth) { + return new DefaultCallStack(span, depth); + } + + @Override + public Span getSpan() { + return span; + } + + @Override + public SpanEvent getSpanEvent() { + return spanEvent; + } +} \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java index 79ec5b1e8f81..d5d5640dae7d 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DefaultTraceTest.java @@ -52,7 +52,7 @@ public static void after() throws Exception { @Test public void testPushPop() { - CallStackFactory callStackFactory = new DefaultCallStackFactory(64); + CallStackFactory callStackFactory = new CallStackFactoryV1(64); SpanFactory spanFactory = new DefaultSpanFactory("appName", "agentId", 0, ServiceType.STAND_ALONE); StringMetaDataService stringMetaDataService = mock(StringMetaDataService.class); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStackTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStackTest.java new file mode 100644 index 000000000000..18493b6ca387 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/DepthCompressCallStackTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 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 org.junit.Before; + + +/** + * @author Woonduk Kang(emeroad) + */ +public class DepthCompressCallStackTest extends CallStackTest { + + private Span span; + private SpanEvent spanEvent; + + @Before + public void before() { + span = new Span(); + spanEvent = new SpanEvent(span); + } + + @Override + public CallStack newCallStack() { + return new DepthCompressCallStack(span); + } + + @Override + public CallStack newCallStack(int depth) { + return new DepthCompressCallStack(span, depth); + } + + @Override + public Span getSpan() { + return span; + } + + @Override + public SpanEvent getSpanEvent() { + return spanEvent; + } + +} \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java index 7efde4586a9a..7d14a7c5c3ac 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java @@ -113,7 +113,7 @@ public MockTraceContextFactory(ProfilerConfig profilerConfig) { final int jdbcSqlCacheSize = profilerConfig.getJdbcSqlCacheSize(); this.sqlMetaDataService = new DefaultSqlMetaDataService(agentId, agentStartTime, enhancedDataSender, jdbcSqlCacheSize); - CallStackFactory callStackFactory = new DefaultCallStackFactory(64); + CallStackFactory callStackFactory = new CallStackFactoryV1(64); TraceIdFactory traceIdFactory = new DefaultTraceIdFactory(agentId, agentStartTime, idGenerator); SpanFactory spanFactory = new DefaultSpanFactory(applicationName, agentId, agentStartTime, agentServiceType); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java index fefe26124633..c6568563e3ea 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanChunkFactoryTest.java @@ -16,12 +16,7 @@ package com.navercorp.pinpoint.profiler.context; -import com.navercorp.pinpoint.common.Version; import com.navercorp.pinpoint.common.trace.ServiceType; -import com.navercorp.pinpoint.common.util.JvmUtils; -import com.navercorp.pinpoint.common.util.SystemPropertyKey; -import com.navercorp.pinpoint.profiler.AgentInformation; -import com.navercorp.pinpoint.profiler.DefaultAgentInformation; import org.junit.Assert; import org.junit.Test; @@ -36,7 +31,7 @@ public class SpanChunkFactoryTest { @Test public void create() { - SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory("applicationName", "agentId", 0, ServiceType.STAND_ALONE); + SpanChunkFactory spanChunkFactory = new SpanChunkFactoryV1("applicationName", "agentId", 0, ServiceType.STAND_ALONE); try { spanChunkFactory.create(new ArrayList()); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java index 62f15f7c5109..d0b23072ef32 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/SpanEventTest.java @@ -16,6 +16,8 @@ package com.navercorp.pinpoint.profiler.context; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressor; +import com.navercorp.pinpoint.profiler.context.compress.SpanEventCompressorV1; import org.junit.Assert; import org.junit.Test; @@ -24,12 +26,14 @@ import com.navercorp.pinpoint.profiler.context.id.DefaultTraceId; +import java.util.Arrays; + /** * @author emeroad */ public class SpanEventTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - + private final SpanEventCompressor compressorV1 = new SpanEventCompressorV1(); @Test public void testMarkStartTime() throws Exception { final DefaultTraceId traceId = new DefaultTraceId("agentTime", 0, 0); @@ -47,6 +51,8 @@ public void testMarkStartTime() throws Exception { spanEvent.markAfterTime(); logger.debug("spanEvent:{}", spanEvent); + compressorV1.compress(Arrays.asList(spanEvent), span.getStartTime()); + Assert.assertEquals("startTime", span.getStartTime() + spanEvent.getStartElapsed(), spanEvent.getStartTime()); Assert.assertEquals("endTime", span.getStartTime() + spanEvent.getStartElapsed() + spanEvent.getEndElapsed(), spanEvent.getAfterTime()); } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/TraceTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/TraceTest.java index 37fe7a20d466..559bacb1edb3 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/TraceTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/TraceTest.java @@ -49,7 +49,7 @@ public class TraceTest { public void trace() { TraceId traceId = new DefaultTraceId("agent", 0, 1); - CallStackFactory callStackFactory = new DefaultCallStackFactory(64); + CallStackFactory callStackFactory = new CallStackFactoryV1(64); SpanFactory spanFactory = new DefaultSpanFactory("appName", "agentId", 0, ServiceType.STAND_ALONE); StringMetaDataService stringMetaDataService = mock(StringMetaDataService.class); @@ -77,7 +77,7 @@ public void trace() { public void popEventTest() { TraceId traceId = new DefaultTraceId("agent", 0, 1); - CallStackFactory callStackFactory = new DefaultCallStackFactory(64); + CallStackFactory callStackFactory = new CallStackFactoryV1(64); SpanFactory spanFactory = new DefaultSpanFactory("appName", "agentId", 0, ServiceType.STAND_ALONE); StringMetaDataService stringMetaDataService = mock(StringMetaDataService.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 cdb9f07d4ee4..2b59248aba3d 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 @@ -17,20 +17,24 @@ package com.navercorp.pinpoint.profiler.context.storage; import com.navercorp.pinpoint.common.trace.ServiceType; -import com.navercorp.pinpoint.profiler.context.DefaultSpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV1; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; import com.navercorp.pinpoint.profiler.context.SpanEvent; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessor; +import com.navercorp.pinpoint.profiler.context.SpanPostProcessorV1; import com.navercorp.pinpoint.profiler.sender.CountingDataSender; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; public class BufferedStorageTest { - private final SpanChunkFactory spanChunkFactory = new DefaultSpanChunkFactory("applicationName", "agentId", 0, ServiceType.STAND_ALONE); + private final SpanPostProcessor spanPostProcessor = new SpanPostProcessorV1(); + private final SpanChunkFactory spanChunkFactory = new SpanChunkFactoryV1("applicationName", "agentId", 0, ServiceType.STAND_ALONE); private final CountingDataSender countingDataSender = new CountingDataSender(); @Before @@ -40,7 +44,7 @@ public void before() { @Test public void testStore_Noflush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanPostProcessor, spanChunkFactory, 10); Span span = new Span(); SpanEvent spanEvent = new SpanEvent(span); @@ -52,7 +56,7 @@ public void testStore_Noflush() throws Exception { @Test public void testStore_flush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 1); + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanPostProcessor, spanChunkFactory, 1); Span span = new Span(); SpanEvent spanEvent = new SpanEvent(span); @@ -69,7 +73,7 @@ public void testStore_flush() throws Exception { @Test public void testStore_spanFlush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanPostProcessor, spanChunkFactory, 10); Span span = new Span(); bufferedStorage.store(span); @@ -85,7 +89,7 @@ public void testStore_spanFlush() throws Exception { @Test public void testStore_spanLastFlush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanPostProcessor, spanChunkFactory, 10); Span span = new Span(); SpanEvent spanEvent = new SpanEvent(span); @@ -102,7 +106,7 @@ public void testStore_spanLastFlush() throws Exception { @Test public void testStore_manual_flush() throws Exception { - BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanChunkFactory, 10); + BufferedStorage bufferedStorage = new BufferedStorage(countingDataSender, spanPostProcessor, spanChunkFactory, 10); Span span = new Span(); SpanEvent spanEvent = new SpanEvent(span); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/SpanStreamSendDataSerializerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/SpanStreamSendDataSerializerTest.java index 50cff3e2db8f..4df169d19d41 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/SpanStreamSendDataSerializerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/SpanStreamSendDataSerializerTest.java @@ -17,7 +17,7 @@ package com.navercorp.pinpoint.profiler.sender; import com.navercorp.pinpoint.common.trace.ServiceType; -import com.navercorp.pinpoint.profiler.context.DefaultSpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV1; import com.navercorp.pinpoint.profiler.context.id.DefaultTraceId; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanChunk; @@ -43,7 +43,7 @@ public class SpanStreamSendDataSerializerTest { private final SpanChunkFactory spanChunkFactory - = new DefaultSpanChunkFactory("applicationName", "agentId", 0, ServiceType.STAND_ALONE); + = new SpanChunkFactoryV1("applicationName", "agentId", 0, ServiceType.STAND_ALONE); @Test diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/planer/SpanChunkStreamSendDataPlanerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/planer/SpanChunkStreamSendDataPlanerTest.java index aeb207393af1..1ea71fde05f1 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/planer/SpanChunkStreamSendDataPlanerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sender/planer/SpanChunkStreamSendDataPlanerTest.java @@ -1,7 +1,7 @@ package com.navercorp.pinpoint.profiler.sender.planer; import com.navercorp.pinpoint.common.trace.ServiceType; -import com.navercorp.pinpoint.profiler.context.DefaultSpanChunkFactory; +import com.navercorp.pinpoint.profiler.context.SpanChunkFactoryV1; import com.navercorp.pinpoint.profiler.context.Span; import com.navercorp.pinpoint.profiler.context.SpanChunk; import com.navercorp.pinpoint.profiler.context.SpanChunkFactory; @@ -41,7 +41,7 @@ public static void setUp() { HeaderTBaseSerializerPoolFactory serializerFactory = new HeaderTBaseSerializerPoolFactory(true, 1000, true); objectPool = new ObjectPool(serializerFactory, 16); - spanChunkFactory = new DefaultSpanChunkFactory("applicationName", "agentId", 0, ServiceType.STAND_ALONE); + spanChunkFactory = new SpanChunkFactoryV1("applicationName", "agentId", 0, ServiceType.STAND_ALONE); } @Test diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java index e6601abe39fe..f33a7cf4a378 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpan.java @@ -7,7 +7,7 @@ package com.navercorp.pinpoint.thrift.dto; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-03-16") +@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-03-21") public class TSpan 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("TSpan"); @@ -34,6 +34,7 @@ public class TSpan implements org.apache.thrift.TBase, jav private static final org.apache.thrift.protocol.TField EXCEPTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionInfo", org.apache.thrift.protocol.TType.STRUCT, (short)26); private static final org.apache.thrift.protocol.TField APPLICATION_SERVICE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationServiceType", org.apache.thrift.protocol.TType.I16, (short)30); private static final org.apache.thrift.protocol.TField LOGGING_TRANSACTION_INFO_FIELD_DESC = new org.apache.thrift.protocol.TField("loggingTransactionInfo", org.apache.thrift.protocol.TType.BYTE, (short)31); + 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)32); private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TSpanStandardSchemeFactory(); private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TSpanTupleSchemeFactory(); @@ -61,6 +62,7 @@ public class TSpan implements org.apache.thrift.TBase, jav private TIntStringValue exceptionInfo; // optional private short applicationServiceType; // optional private byte loggingTransactionInfo; // optional + private byte version; // optional /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements org.apache.thrift.TFieldIdEnum { @@ -86,7 +88,8 @@ public enum _Fields implements org.apache.thrift.TFieldIdEnum { API_ID((short)25, "apiId"), EXCEPTION_INFO((short)26, "exceptionInfo"), APPLICATION_SERVICE_TYPE((short)30, "applicationServiceType"), - LOGGING_TRANSACTION_INFO((short)31, "loggingTransactionInfo"); + LOGGING_TRANSACTION_INFO((short)31, "loggingTransactionInfo"), + VERSION((short)32, "version"); private static final java.util.Map byName = new java.util.HashMap(); @@ -147,6 +150,8 @@ public static _Fields findByThriftId(int fieldId) { return APPLICATION_SERVICE_TYPE; case 31: // LOGGING_TRANSACTION_INFO return LOGGING_TRANSACTION_INFO; + case 32: // VERSION + return VERSION; default: return null; } @@ -199,8 +204,9 @@ public java.lang.String getFieldName() { private static final int __APIID_ISSET_ID = 9; private static final int __APPLICATIONSERVICETYPE_ISSET_ID = 10; private static final int __LOGGINGTRANSACTIONINFO_ISSET_ID = 11; + private static final int __VERSION_ISSET_ID = 12; private short __isset_bitfield = 0; - private static final _Fields optionals[] = {_Fields.PARENT_SPAN_ID,_Fields.ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.REMOTE_ADDR,_Fields.ANNOTATIONS,_Fields.FLAG,_Fields.ERR,_Fields.SPAN_EVENT_LIST,_Fields.PARENT_APPLICATION_NAME,_Fields.PARENT_APPLICATION_TYPE,_Fields.ACCEPTOR_HOST,_Fields.API_ID,_Fields.EXCEPTION_INFO,_Fields.APPLICATION_SERVICE_TYPE,_Fields.LOGGING_TRANSACTION_INFO}; + private static final _Fields optionals[] = {_Fields.PARENT_SPAN_ID,_Fields.ELAPSED,_Fields.RPC,_Fields.END_POINT,_Fields.REMOTE_ADDR,_Fields.ANNOTATIONS,_Fields.FLAG,_Fields.ERR,_Fields.SPAN_EVENT_LIST,_Fields.PARENT_APPLICATION_NAME,_Fields.PARENT_APPLICATION_TYPE,_Fields.ACCEPTOR_HOST,_Fields.API_ID,_Fields.EXCEPTION_INFO,_Fields.APPLICATION_SERVICE_TYPE,_Fields.LOGGING_TRANSACTION_INFO,_Fields.VERSION}; 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); @@ -252,6 +258,8 @@ public java.lang.String getFieldName() { new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); tmpMap.put(_Fields.LOGGING_TRANSACTION_INFO, new org.apache.thrift.meta_data.FieldMetaData("loggingTransactionInfo", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE))); + 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))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpan.class, metaDataMap); } @@ -263,6 +271,8 @@ public TSpan() { this.flag = (short)0; + this.version = (byte)1; + } public TSpan( @@ -346,6 +356,7 @@ public TSpan(TSpan other) { } this.applicationServiceType = other.applicationServiceType; this.loggingTransactionInfo = other.loggingTransactionInfo; + this.version = other.version; } public TSpan deepCopy() { @@ -389,6 +400,8 @@ public void clear() { this.applicationServiceType = 0; setLoggingTransactionInfoIsSet(false); this.loggingTransactionInfo = 0; + this.version = (byte)1; + } public java.lang.String getAgentId() { @@ -947,6 +960,28 @@ public void setLoggingTransactionInfoIsSet(boolean value) { __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LOGGINGTRANSACTIONINFO_ISSET_ID, value); } + public byte getVersion() { + return this.version; + } + + public void setVersion(byte version) { + this.version = version; + setVersionIsSet(true); + } + + 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); + } + public void setFieldValue(_Fields field, java.lang.Object value) { switch (field) { case AGENT_ID: @@ -1137,6 +1172,14 @@ public void setFieldValue(_Fields field, java.lang.Object value) { } break; + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((java.lang.Byte)value); + } + break; + } } @@ -1211,6 +1254,9 @@ public java.lang.Object getFieldValue(_Fields field) { case LOGGING_TRANSACTION_INFO: return getLoggingTransactionInfo(); + case VERSION: + return getVersion(); + } throw new java.lang.IllegalStateException(); } @@ -1268,6 +1314,8 @@ public boolean isSet(_Fields field) { return isSetApplicationServiceType(); case LOGGING_TRANSACTION_INFO: return isSetLoggingTransactionInfo(); + case VERSION: + return isSetVersion(); } throw new java.lang.IllegalStateException(); } @@ -1494,6 +1542,15 @@ public boolean equals(TSpan that) { return false; } + 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; + } + return true; } @@ -1585,6 +1642,10 @@ public int hashCode() { if (isSetLoggingTransactionInfo()) hashCode = hashCode * 8191 + (int) (loggingTransactionInfo); + hashCode = hashCode * 8191 + ((isSetVersion()) ? 131071 : 524287); + if (isSetVersion()) + hashCode = hashCode * 8191 + (int) (version); + return hashCode; } @@ -1826,6 +1887,16 @@ public int compareTo(TSpan other) { return lastComparison; } } + lastComparison = java.lang.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; + } + } return 0; } @@ -2013,6 +2084,12 @@ public java.lang.String toString() { sb.append(this.loggingTransactionInfo); first = false; } + if (isSetVersion()) { + if (!first) sb.append(", "); + sb.append("version:"); + sb.append(this.version); + first = false; + } sb.append(")"); return sb.toString(); } @@ -2268,6 +2345,14 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, TSpan struct) throw org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; + case 32: // 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; default: org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } @@ -2418,6 +2503,11 @@ public void write(org.apache.thrift.protocol.TProtocol oprot, TSpan struct) thro oprot.writeByte(struct.loggingTransactionInfo); oprot.writeFieldEnd(); } + if (struct.isSetVersion()) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + oprot.writeByte(struct.version); + oprot.writeFieldEnd(); + } oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -2505,7 +2595,10 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throw if (struct.isSetLoggingTransactionInfo()) { optionals.set(22); } - oprot.writeBitSet(optionals, 23); + if (struct.isSetVersion()) { + optionals.set(23); + } + oprot.writeBitSet(optionals, 24); if (struct.isSetAgentId()) { oprot.writeString(struct.agentId); } @@ -2587,12 +2680,15 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throw if (struct.isSetLoggingTransactionInfo()) { oprot.writeByte(struct.loggingTransactionInfo); } + if (struct.isSetVersion()) { + oprot.writeByte(struct.version); + } } @Override public void read(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws org.apache.thrift.TException { org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; - java.util.BitSet incoming = iprot.readBitSet(23); + java.util.BitSet incoming = iprot.readBitSet(24); if (incoming.get(0)) { struct.agentId = iprot.readString(); struct.setAgentIdIsSet(true); @@ -2706,6 +2802,10 @@ public void read(org.apache.thrift.protocol.TProtocol prot, TSpan struct) throws struct.loggingTransactionInfo = iprot.readByte(); struct.setLoggingTransactionInfoIsSet(true); } + if (incoming.get(23)) { + struct.version = iprot.readByte(); + struct.setVersionIsSet(true); + } } } diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java index 2dbf91325356..3cbe3c9e7579 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TSpanChunk.java @@ -7,7 +7,7 @@ package com.navercorp.pinpoint.thrift.dto; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) -@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-03-17") +@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-03-21") public class TSpanChunk 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("TSpanChunk"); @@ -20,6 +20,8 @@ public class TSpanChunk implements org.apache.thrift.TBase spanEventList; // required private short applicationServiceType; // optional + private long keyTime; // optional + private byte version; // optional /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements org.apache.thrift.TFieldIdEnum { @@ -44,7 +48,9 @@ public enum _Fields implements org.apache.thrift.TFieldIdEnum { SPAN_ID((short)8, "spanId"), END_POINT((short)9, "endPoint"), SPAN_EVENT_LIST((short)10, "spanEventList"), - APPLICATION_SERVICE_TYPE((short)11, "applicationServiceType"); + APPLICATION_SERVICE_TYPE((short)11, "applicationServiceType"), + KEY_TIME((short)12, "keyTime"), + VERSION((short)13, "version"); private static final java.util.Map byName = new java.util.HashMap(); @@ -77,6 +83,10 @@ public static _Fields findByThriftId(int fieldId) { return SPAN_EVENT_LIST; case 11: // APPLICATION_SERVICE_TYPE return APPLICATION_SERVICE_TYPE; + case 12: // KEY_TIME + return KEY_TIME; + case 13: // VERSION + return VERSION; default: return null; } @@ -121,8 +131,10 @@ public java.lang.String getFieldName() { private static final int __SERVICETYPE_ISSET_ID = 1; private static final int __SPANID_ISSET_ID = 2; private static final int __APPLICATIONSERVICETYPE_ISSET_ID = 3; + private static final int __KEYTIME_ISSET_ID = 4; + private static final int __VERSION_ISSET_ID = 5; private byte __isset_bitfield = 0; - private static final _Fields optionals[] = {_Fields.END_POINT,_Fields.APPLICATION_SERVICE_TYPE}; + private static final _Fields optionals[] = {_Fields.END_POINT,_Fields.APPLICATION_SERVICE_TYPE,_Fields.KEY_TIME,_Fields.VERSION}; 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); @@ -145,11 +157,17 @@ public java.lang.String getFieldName() { new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSpanEvent.class)))); tmpMap.put(_Fields.APPLICATION_SERVICE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("applicationServiceType", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.KEY_TIME, new org.apache.thrift.meta_data.FieldMetaData("keyTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + 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))); metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSpanChunk.class, metaDataMap); } public TSpanChunk() { + this.version = (byte)1; + } public TSpanChunk( @@ -202,6 +220,8 @@ public TSpanChunk(TSpanChunk other) { this.spanEventList = __this__spanEventList; } this.applicationServiceType = other.applicationServiceType; + this.keyTime = other.keyTime; + this.version = other.version; } public TSpanChunk deepCopy() { @@ -223,6 +243,10 @@ public void clear() { this.spanEventList = null; setApplicationServiceTypeIsSet(false); this.applicationServiceType = 0; + setKeyTimeIsSet(false); + this.keyTime = 0; + this.version = (byte)1; + } public java.lang.String getAgentId() { @@ -457,6 +481,50 @@ public void setApplicationServiceTypeIsSet(boolean value) { __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __APPLICATIONSERVICETYPE_ISSET_ID, value); } + public long getKeyTime() { + return this.keyTime; + } + + public void setKeyTime(long keyTime) { + this.keyTime = keyTime; + setKeyTimeIsSet(true); + } + + public void unsetKeyTime() { + __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __KEYTIME_ISSET_ID); + } + + /** Returns true if field keyTime is set (has been assigned a value) and false otherwise */ + public boolean isSetKeyTime() { + return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __KEYTIME_ISSET_ID); + } + + public void setKeyTimeIsSet(boolean value) { + __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __KEYTIME_ISSET_ID, value); + } + + public byte getVersion() { + return this.version; + } + + public void setVersion(byte version) { + this.version = version; + setVersionIsSet(true); + } + + 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); + } + public void setFieldValue(_Fields field, java.lang.Object value) { switch (field) { case AGENT_ID: @@ -535,6 +603,22 @@ public void setFieldValue(_Fields field, java.lang.Object value) { } break; + case KEY_TIME: + if (value == null) { + unsetKeyTime(); + } else { + setKeyTime((java.lang.Long)value); + } + break; + + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((java.lang.Byte)value); + } + break; + } } @@ -567,6 +651,12 @@ public java.lang.Object getFieldValue(_Fields field) { case APPLICATION_SERVICE_TYPE: return getApplicationServiceType(); + case KEY_TIME: + return getKeyTime(); + + case VERSION: + return getVersion(); + } throw new java.lang.IllegalStateException(); } @@ -596,6 +686,10 @@ public boolean isSet(_Fields field) { return isSetSpanEventList(); case APPLICATION_SERVICE_TYPE: return isSetApplicationServiceType(); + case KEY_TIME: + return isSetKeyTime(); + case VERSION: + return isSetVersion(); } throw new java.lang.IllegalStateException(); } @@ -696,6 +790,24 @@ public boolean equals(TSpanChunk that) { return false; } + boolean this_present_keyTime = true && this.isSetKeyTime(); + boolean that_present_keyTime = true && that.isSetKeyTime(); + if (this_present_keyTime || that_present_keyTime) { + if (!(this_present_keyTime && that_present_keyTime)) + return false; + if (this.keyTime != that.keyTime) + return false; + } + + 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; + } + return true; } @@ -733,6 +845,14 @@ public int hashCode() { if (isSetApplicationServiceType()) hashCode = hashCode * 8191 + applicationServiceType; + hashCode = hashCode * 8191 + ((isSetKeyTime()) ? 131071 : 524287); + if (isSetKeyTime()) + hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(keyTime); + + hashCode = hashCode * 8191 + ((isSetVersion()) ? 131071 : 524287); + if (isSetVersion()) + hashCode = hashCode * 8191 + (int) (version); + return hashCode; } @@ -834,6 +954,26 @@ public int compareTo(TSpanChunk other) { return lastComparison; } } + lastComparison = java.lang.Boolean.valueOf(isSetKeyTime()).compareTo(other.isSetKeyTime()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKeyTime()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keyTime, other.keyTime); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = java.lang.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; + } + } return 0; } @@ -913,6 +1053,18 @@ public java.lang.String toString() { sb.append(this.applicationServiceType); first = false; } + if (isSetKeyTime()) { + if (!first) sb.append(", "); + sb.append("keyTime:"); + sb.append(this.keyTime); + first = false; + } + if (isSetVersion()) { + if (!first) sb.append(", "); + sb.append("version:"); + sb.append(this.version); + first = false; + } sb.append(")"); return sb.toString(); } @@ -1041,6 +1193,22 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, TSpanChunk struct) org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; + case 12: // KEY_TIME + if (schemeField.type == org.apache.thrift.protocol.TType.I64) { + struct.keyTime = iprot.readI64(); + struct.setKeyTimeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); + } + break; + case 13: // 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; default: org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } @@ -1102,6 +1270,16 @@ public void write(org.apache.thrift.protocol.TProtocol oprot, TSpanChunk struct) oprot.writeI16(struct.applicationServiceType); oprot.writeFieldEnd(); } + if (struct.isSetKeyTime()) { + oprot.writeFieldBegin(KEY_TIME_FIELD_DESC); + oprot.writeI64(struct.keyTime); + oprot.writeFieldEnd(); + } + if (struct.isSetVersion()) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + oprot.writeByte(struct.version); + oprot.writeFieldEnd(); + } oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -1147,7 +1325,13 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) if (struct.isSetApplicationServiceType()) { optionals.set(8); } - oprot.writeBitSet(optionals, 9); + if (struct.isSetKeyTime()) { + optionals.set(9); + } + if (struct.isSetVersion()) { + optionals.set(10); + } + oprot.writeBitSet(optionals, 11); if (struct.isSetAgentId()) { oprot.writeString(struct.agentId); } @@ -1181,12 +1365,18 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) if (struct.isSetApplicationServiceType()) { oprot.writeI16(struct.applicationServiceType); } + if (struct.isSetKeyTime()) { + oprot.writeI64(struct.keyTime); + } + if (struct.isSetVersion()) { + oprot.writeByte(struct.version); + } } @Override public void read(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) throws org.apache.thrift.TException { org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; - java.util.BitSet incoming = iprot.readBitSet(9); + java.util.BitSet incoming = iprot.readBitSet(11); if (incoming.get(0)) { struct.agentId = iprot.readString(); struct.setAgentIdIsSet(true); @@ -1233,6 +1423,14 @@ public void read(org.apache.thrift.protocol.TProtocol prot, TSpanChunk struct) t struct.applicationServiceType = iprot.readI16(); struct.setApplicationServiceTypeIsSet(true); } + if (incoming.get(9)) { + struct.keyTime = iprot.readI64(); + struct.setKeyTimeIsSet(true); + } + if (incoming.get(10)) { + struct.version = iprot.readByte(); + struct.setVersionIsSet(true); + } } } diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TraceConstants.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TraceConstants.java new file mode 100644 index 000000000000..7b1664712cec --- /dev/null +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TraceConstants.java @@ -0,0 +1,16 @@ +/** + * Autogenerated by Thrift Compiler (0.10.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"}) +public class TraceConstants { + + public static final byte TRACE_V1 = (byte)0; + + public static final byte TRACE_V2 = (byte)1; + +} diff --git a/thrift/src/main/thrift/Trace.thrift b/thrift/src/main/thrift/Trace.thrift index 0f0641638b29..390eccf3d622 100644 --- a/thrift/src/main/thrift/Trace.thrift +++ b/thrift/src/main/thrift/Trace.thrift @@ -1,5 +1,8 @@ namespace java com.navercorp.pinpoint.thrift.dto - +// 1.6.x- : version = 0; +// 1.7.x+ : version = 1; +const i8 TRACE_V1 = 0; +const i8 TRACE_V2 = 1; struct TIntStringValue { 1: i32 intValue; @@ -39,7 +42,11 @@ struct TSpanEvent { 7: optional i64 spanId 8: i16 sequence - 9: i32 startElapsed + // 1.6.x- : delta of the span startTime + // 1.7.0+: delta of startTime of previous SpanEvent + // If SpanEvent is the first SpanEvent, startElapsed is span startTime + 9: i32 startElapsed = 0; + 10: optional i32 endElapsed = 0 11: optional string rpc @@ -102,6 +109,8 @@ struct TSpan { 30: optional i16 applicationServiceType; 31: optional i8 loggingTransactionInfo; + + 32: optional i8 version = TRACE_V2; } struct TSpanChunk { @@ -109,6 +118,7 @@ struct TSpanChunk { 2: string applicationName 3: i64 agentStartTime + // @deprecate (1.7.0) 4: i16 serviceType ( deprecated ) // identical to agentId if null @@ -124,6 +134,11 @@ struct TSpanChunk { 10: list spanEventList 11: optional i16 applicationServiceType + + // @since 1.7.0 time for data compression + 12: optional i64 keyTime; + + 13: optional i8 version = TRACE_V2; }