From 6db7cd1a9795096668a96228658219b1599d4c0a Mon Sep 17 00:00:00 2001 From: emeroad Date: Wed, 27 Jul 2016 16:45:01 +0900 Subject: [PATCH] #1819 trace format v2 - refactoring --- .../pinpoint/collector/dao/TraceDao.java | 8 +- .../dao/hbase/DualWriteHbaseTraceDao.java | 12 +- .../hbase/HbaseApplicationTraceIndexDao.java | 2 +- .../collector/dao/hbase/HbaseTraceDao.java | 48 ++- .../collector/dao/hbase/HbaseTraceDaoV2.java | 96 +----- .../collector/handler/SpanChunkHandler.java | 52 ++-- .../collector/handler/SpanHandler.java | 78 ++--- .../applicationContext-collector.xml | 4 +- .../common/server/bo/AnnotationBo.java | 14 +- .../common/server/bo/AnnotationBoDecoder.java | 1 - .../common/server/bo/AnnotationBoList.java | 1 - .../server/bo/AnnotationComparator.java | 16 + .../pinpoint/common/server/bo/BasicSpan.java | 26 ++ .../pinpoint/common/server/bo/Event.java | 29 ++ .../pinpoint/common/server/bo/SpanBo.java | 104 ++----- .../common/server/bo/SpanChunkBo.java | 44 ++- .../common/server/bo/SpanEventBo.java | 151 +-------- .../common/server/bo/SpanEventComparator.java | 34 +++ .../common/server/bo/SpanFactory.java | 287 ++++++++++++++++++ .../bo/filter/EmptySpanEventFilter.java | 17 ++ .../bo/filter/SequenceSpanEventFilter.java | 61 ++++ .../server/bo/filter/SpanEventFilter.java | 29 ++ .../trace/v1/SpanEventEncodingContext.java | 24 ++ .../trace/v1/SpanEventSerializer.java | 16 +- .../trace/v2/SpanChunkSerializerV2.java | 1 - .../bo/serializer/trace/v2/SpanDecoderV0.java | 88 +----- .../trace/v2/SpanDecodingContext.java | 3 - .../bo/serializer/trace/v2/SpanEncoder.java | 35 --- .../bo/serializer/trace/v2/SpanEncoderV0.java | 17 +- .../trace/v2/SpanEncodingContext.java | 2 - .../server/util/EmptyAcceptedTimeService.java | 28 ++ .../common/server}/util/SpanEventUtils.java | 2 +- .../common/server/util/SpanUtils.java | 124 ++++++++ .../common/server/bo/SpanEventBoTest.java | 5 +- .../filter/SequenceSpanEventFilterTest.java | 63 ++++ .../common/server/util/SpanUtilsTest.java | 88 ++++++ .../test/junit4/BasePinpointTest.java | 8 +- .../pinpoint/web/calltree/span/SpanAlign.java | 5 +- .../hbase/HbaseApplicationTraceIndexDao.java | 2 +- .../pinpoint/web/mapper/SpanMapper.java | 17 +- .../pinpoint/web/mapper/SpanMapperV2.java | 10 - .../service/TransactionInfoServiceImpl.java | 12 +- 42 files changed, 1056 insertions(+), 608 deletions(-) create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationComparator.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/BasicSpan.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/Event.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventComparator.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanFactory.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/EmptySpanEventFilter.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilter.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SpanEventFilter.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventEncodingContext.java create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/EmptyAcceptedTimeService.java rename {commons/src/main/java/com/navercorp/pinpoint/common => commons-server/src/main/java/com/navercorp/pinpoint/common/server}/util/SpanEventUtils.java (95%) create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanUtils.java create mode 100644 commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilterTest.java create mode 100644 commons-server/src/test/java/com/navercorp/pinpoint/common/server/util/SpanUtilsTest.java diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TraceDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TraceDao.java index 04324d1dff60..022f2934f066 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TraceDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/TraceDao.java @@ -1,13 +1,13 @@ package com.navercorp.pinpoint.collector.dao; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; +import com.navercorp.pinpoint.common.server.bo.SpanBo; +import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; /** * @author Woonduk Kang(emeroad) */ public interface TraceDao { - void insert(TSpan span); + void insert(SpanBo span); - void insertSpanChunk(TSpanChunk spanChunk); + void insertSpanChunk(SpanChunkBo spanChunk); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/DualWriteHbaseTraceDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/DualWriteHbaseTraceDao.java index 4992a6e44c3d..a37a52afddc1 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/DualWriteHbaseTraceDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/DualWriteHbaseTraceDao.java @@ -1,8 +1,8 @@ package com.navercorp.pinpoint.collector.dao.hbase; import com.navercorp.pinpoint.collector.dao.TraceDao; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; +import com.navercorp.pinpoint.common.server.bo.SpanBo; +import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +29,7 @@ public DualWriteHbaseTraceDao(TraceDao master, TraceDao slave) { } @Override - public void insert(TSpan span) { + public void insert(SpanBo span) { Throwable masterException = null; try { master.insert(span); @@ -45,15 +45,15 @@ public void insert(TSpan span) { } @Override - public void insertSpanChunk(TSpanChunk spanChunk) { + public void insertSpanChunk(SpanChunkBo spanChunkBo) { Throwable masterException = null; try { - master.insertSpanChunk(spanChunk); + master.insertSpanChunk(spanChunkBo); } catch (Throwable e) { masterException = e; } try { - slave.insertSpanChunk(spanChunk); + slave.insertSpanChunk(spanChunkBo); } catch (Throwable e) { logger.warn("slave insertSpanChunk(TSpanChunk) Error:{}", e.getMessage(), e); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDao.java index bc447c902afa..9ab49c4656d3 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseApplicationTraceIndexDao.java @@ -23,7 +23,7 @@ import com.navercorp.pinpoint.common.buffer.AutomaticBuffer; import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.hbase.HbaseOperations2; -import com.navercorp.pinpoint.common.util.SpanUtils; +import com.navercorp.pinpoint.common.server.util.SpanUtils; import com.navercorp.pinpoint.thrift.dto.TSpan; import com.sematext.hbase.wd.AbstractRowKeyDistributor; diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java index 400ebdd4835f..0ead7c54e1dd 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java @@ -17,8 +17,12 @@ package com.navercorp.pinpoint.collector.dao.hbase; import com.navercorp.pinpoint.collector.dao.TracesDao; -import com.navercorp.pinpoint.collector.dao.hbase.filter.SpanEventFilter; + +import com.navercorp.pinpoint.common.server.bo.BasicSpan; +import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; +import com.navercorp.pinpoint.common.server.bo.filter.SpanEventFilter; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.AnnotationSerializer; +import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanEventEncodingContext; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanEventSerializer; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanSerializer; import com.navercorp.pinpoint.common.server.util.AcceptedTimeService; @@ -26,10 +30,7 @@ import com.navercorp.pinpoint.common.server.bo.SpanEventBo; import static com.navercorp.pinpoint.common.hbase.HBaseTables.*; import com.navercorp.pinpoint.common.hbase.HbaseOperations2; -import com.navercorp.pinpoint.common.util.SpanUtils; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; +import com.navercorp.pinpoint.common.server.util.SpanUtils; import com.sematext.hbase.wd.AbstractRowKeyDistributor; import org.apache.commons.collections.CollectionUtils; import org.apache.hadoop.hbase.client.Put; @@ -72,24 +73,22 @@ public class HbaseTraceDao implements TracesDao { private AbstractRowKeyDistributor rowKeyDistributor; @Override - public void insert(final TSpan span) { - if (span == null) { + public void insert(final SpanBo spanBo) { + if (spanBo == null) { throw new NullPointerException("span must not be null"); } - final SpanBo spanBo = new SpanBo(span); - long acceptedTime = acceptedTimeService.getAcceptedTime(); - spanBo.setCollectorAcceptTime(acceptedTime); + long acceptedTime = spanBo.getCollectorAcceptTime(); - final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(span)); + final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanBo)); final Put put = new Put(rowKey, acceptedTime); this.spanSerializer.serialize(spanBo, put, null); this.annotationSerializer.serialize(spanBo, put, null); - addNestedSpanEvent(put, span); + addNestedSpanEvent(put, spanBo); boolean success = hbaseTemplate.asyncPut(TRACES, put); if (!success) { @@ -101,34 +100,32 @@ private byte[] getDistributeRowKey(byte[] transactionId) { return rowKeyDistributor.getDistributedKey(transactionId); } - private void addNestedSpanEvent(Put put, TSpan span) { - final List spanEventBoList = span.getSpanEventList(); + private void addNestedSpanEvent(Put put, SpanBo span) { + final List spanEventBoList = span.getSpanEventBoList(); if (CollectionUtils.isEmpty(spanEventBoList)) { return; } - for (TSpanEvent spanEvent : spanEventBoList) { - final SpanEventBo spanEventBo = new SpanEventBo(span, spanEvent); - addColumn(put, spanEventBo); + for (SpanEventBo spanEvent : spanEventBoList) { + addColumn(put, span, spanEvent); } } @Override - public void insertSpanChunk(TSpanChunk spanChunk) { - final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunk)); + public void insertSpanChunk(SpanChunkBo spanChunkBo) { + final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunkBo)); final long acceptedTime = acceptedTimeService.getAcceptedTime(); final Put put = new Put(rowKey, acceptedTime); - final List spanEventBoList = spanChunk.getSpanEventList(); + final List spanEventBoList = spanChunkBo.getSpanEventBoList(); if (CollectionUtils.isEmpty(spanEventBoList)) { return; } - for (TSpanEvent spanEvent : spanEventBoList) { - final SpanEventBo spanEventBo = new SpanEventBo(spanChunk, spanEvent); - addColumn(put, spanEventBo); + for (SpanEventBo spanEventBo : spanEventBoList) { + addColumn(put, spanChunkBo, spanEventBo); } if (!put.isEmpty()) { @@ -139,11 +136,12 @@ public void insertSpanChunk(TSpanChunk spanChunk) { } } - private void addColumn(Put put, SpanEventBo spanEventBo) { + private void addColumn(Put put, BasicSpan basicSpan, SpanEventBo spanEventBo) { if (!spanEventFilter.filter(spanEventBo)) { return; } - this.spanEventSerializer.serialize(spanEventBo, put, null); + SpanEventEncodingContext spanEventEncodingContext = new SpanEventEncodingContext(basicSpan.getSpanId(), spanEventBo); + this.spanEventSerializer.serialize(spanEventEncodingContext, put, null); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDaoV2.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDaoV2.java index 55f8f2994401..0aff0ddee406 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDaoV2.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDaoV2.java @@ -1,20 +1,13 @@ package com.navercorp.pinpoint.collector.dao.hbase; import com.navercorp.pinpoint.collector.dao.TraceDao; -import com.navercorp.pinpoint.collector.dao.hbase.filter.SpanEventFilter; import com.navercorp.pinpoint.common.hbase.HbaseOperations2; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; import com.navercorp.pinpoint.common.server.bo.SpanEventBo; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanChunkSerializerV2; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanSerializerV2; -import com.navercorp.pinpoint.common.server.util.AcceptedTimeService; -import com.navercorp.pinpoint.common.util.SpanUtils; -import com.navercorp.pinpoint.common.util.TransactionId; -import com.navercorp.pinpoint.common.util.TransactionIdUtils; -import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; +import com.navercorp.pinpoint.common.server.util.SpanUtils; import com.sematext.hbase.wd.AbstractRowKeyDistributor; import org.apache.commons.collections.CollectionUtils; import org.apache.hadoop.hbase.client.Put; @@ -24,8 +17,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import static com.navercorp.pinpoint.common.hbase.HBaseTables.TRACE_V2; @@ -41,11 +32,6 @@ public class HbaseTraceDaoV2 implements TraceDao { @Autowired private HbaseOperations2 hbaseTemplate; - @Autowired - private AcceptedTimeService acceptedTimeService; - - @Autowired - private SpanEventFilter spanEventFilter; @Autowired private SpanSerializerV2 spanSerializer; @@ -59,19 +45,15 @@ public class HbaseTraceDaoV2 implements TraceDao { @Override - public void insert(final TSpan span) { - if (span == null) { - throw new NullPointerException("span must not be null"); + public void insert(final SpanBo spanBo) { + if (spanBo == null) { + throw new NullPointerException("spanBo must not be null"); } - final SpanBo spanBo = new SpanBo(span); - List spanEventBoList = buildSpanEventList(span); - spanBo.addSpanEventBoList(spanEventBoList); - long acceptedTime = acceptedTimeService.getAcceptedTime(); - spanBo.setCollectorAcceptTime(acceptedTime); + long acceptedTime = spanBo.getCollectorAcceptTime(); - final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(span)); + final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanBo)); final Put put = new Put(rowKey, acceptedTime); this.spanSerializer.serialize(spanBo, put, null); @@ -84,41 +66,7 @@ public void insert(final TSpan span) { } - private List buildSpanEventList(TSpan span) { - final List spanEventList = span.getSpanEventList(); - if (CollectionUtils.isEmpty(spanEventList)) { - return Collections.emptyList(); - } - - List spanEventBoList = new ArrayList<>(spanEventList.size()); - for (TSpanEvent spanEvent : spanEventList) { - final SpanEventBo spanEventBo = new SpanEventBo(span, spanEvent); - if (!spanEventFilter.filter(spanEventBo)) { - continue; - } - spanEventBoList.add(spanEventBo); - } - - - return spanEventBoList; - } - - private List buildSpanEventBoList(TSpanChunk tSpanChunk) { - List spanEventList = tSpanChunk.getSpanEventList(); - if (CollectionUtils.isEmpty(spanEventList)) { - return new ArrayList<>(); - } - List spanEventBoList = new ArrayList<>(spanEventList.size()); - for (TSpanEvent tSpanEvent : spanEventList) { - SpanEventBo spanEventBo = new SpanEventBo(tSpanChunk, tSpanEvent); - if (!spanEventFilter.filter(spanEventBo)) { - continue; - } - spanEventBoList.add(spanEventBo); - } - return spanEventBoList; - } private byte[] getDistributeRowKey(byte[] transactionId) { byte[] distributedKey = rowKeyDistributor.getDistributedKey(transactionId); @@ -128,14 +76,14 @@ private byte[] getDistributeRowKey(byte[] transactionId) { @Override - public void insertSpanChunk(TSpanChunk spanChunk) { - SpanChunkBo spanChunkBo = buildSpanChunkBo(spanChunk); + public void insertSpanChunk(SpanChunkBo spanChunkBo) { - final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunk)); - final long acceptedTime = acceptedTimeService.getAcceptedTime(); + final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunkBo)); + + final long acceptedTime = spanChunkBo.getCollectorAcceptTime(); final Put put = new Put(rowKey, acceptedTime); - final List spanEventBoList = spanChunk.getSpanEventList(); + final List spanEventBoList = spanChunkBo.getSpanEventBoList(); if (CollectionUtils.isEmpty(spanEventBoList)) { return; } @@ -150,28 +98,6 @@ public void insertSpanChunk(TSpanChunk spanChunk) { } } - public SpanChunkBo buildSpanChunkBo(TSpanChunk tSpanChunk) { - SpanChunkBo spanChunkBo = new SpanChunkBo(); - spanChunkBo.setAgentId(tSpanChunk.getAgentId()); - spanChunkBo.setApplicationId(tSpanChunk.getApplicationName()); - spanChunkBo.setAgentStartTime(tSpanChunk.getAgentStartTime()); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpanChunk.getTransactionId()); - final String traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - spanChunkBo.setTraceAgentId(spanChunkBo.getAgentId()); - } else { - spanChunkBo.setTraceAgentId(traceAgentId); - } - spanChunkBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); - spanChunkBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); - - spanChunkBo.setSpanId(tSpanChunk.getSpanId()); - - List spanEventBoList = buildSpanEventBoList(tSpanChunk); - spanChunkBo.addSpanEventBoList(spanEventBoList); - return spanChunkBo; - } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java index a87a1c8a0432..c75d9211b731 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanChunkHandler.java @@ -19,6 +19,9 @@ import java.util.List; import com.navercorp.pinpoint.collector.dao.TraceDao; +import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; +import com.navercorp.pinpoint.common.server.bo.SpanFactory; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; import com.navercorp.pinpoint.common.trace.ServiceType; @@ -27,9 +30,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import com.navercorp.pinpoint.common.util.SpanEventUtils; import com.navercorp.pinpoint.thrift.dto.TSpanChunk; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -52,30 +53,25 @@ public class SpanChunkHandler implements SimpleHandler { @Autowired private ServiceTypeRegistryService registry; + @Autowired + private SpanFactory spanFactory; + @Override public void handleSimple(TBase tbase) { - if (!(tbase instanceof TSpanChunk)) { - throw new IllegalArgumentException("unexpected tbase:" + tbase + " expected:" + this.getClass().getName()); - } - try { - TSpanChunk spanChunk = (TSpanChunk) tbase; - - if (logger.isDebugEnabled()) { - logger.debug("Received SpanChunk={}", spanChunk); - } + final SpanChunkBo spanChunkBo = newSpanChunkBo(tbase); - traceDao.insertSpanChunk(spanChunk); + traceDao.insertSpanChunk(spanChunkBo); - final ServiceType applicationServiceType = getApplicationServiceType(spanChunk); - List spanEventList = spanChunk.getSpanEventList(); + final ServiceType applicationServiceType = getApplicationServiceType(spanChunkBo); + List spanEventList = spanChunkBo.getSpanEventBoList(); if (spanEventList != null) { if (logger.isDebugEnabled()) { logger.debug("SpanChunk Size:{}", spanEventList.size()); } // TODO need to batch update later. - for (TSpanEvent spanEvent : spanEventList) { + for (SpanEventBo spanEvent : spanEventList) { final ServiceType spanEventType = registry.findServiceType(spanEvent.getServiceType()); if (!spanEventType.isRecordStatistics()) { @@ -84,26 +80,38 @@ public void handleSimple(TBase tbase) { // if terminal update statistics final int elapsed = spanEvent.getEndElapsed(); - final boolean hasException = SpanEventUtils.hasException(spanEvent); + final boolean hasException = spanEvent.hasException(); /** * save information to draw a server map based on statistics */ // save the information of caller (the spanevent that span called) - statisticsHandler.updateCaller(spanChunk.getApplicationName(), applicationServiceType, spanChunk.getAgentId(), spanEvent.getDestinationId(), spanEventType, spanEvent.getEndPoint(), elapsed, hasException); + statisticsHandler.updateCaller(spanChunkBo.getApplicationId(), applicationServiceType, spanChunkBo.getAgentId(), spanEvent.getDestinationId(), spanEventType, spanEvent.getEndPoint(), elapsed, hasException); // save the information of callee (the span that called spanevent) - statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEventType, spanChunk.getApplicationName(), applicationServiceType, spanChunk.getEndPoint(), elapsed, hasException); + statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEventType, spanChunkBo.getApplicationId(), applicationServiceType, spanChunkBo.getEndPoint(), elapsed, hasException); } } } catch (Exception e) { logger.warn("SpanChunk handle error Caused:{}", e.getMessage(), e); } } - - private ServiceType getApplicationServiceType(TSpanChunk spanChunk) { - // Check if applicationServiceType is set. If not, use span's service type. - final short applicationServiceTypeCode = spanChunk.isSetApplicationServiceType() ? spanChunk.getApplicationServiceType() : spanChunk.getServiceType(); + + private SpanChunkBo newSpanChunkBo(TBase tbase) { + if (!(tbase instanceof TSpanChunk)) { + throw new IllegalArgumentException("unexpected tbase:" + tbase + " expected:" + this.getClass().getName()); + } + + final TSpanChunk tSpanChunk = (TSpanChunk) tbase; + if (logger.isDebugEnabled()) { + logger.debug("Received SpanChunk={}", tbase); + } + + return this.spanFactory.buildSpanChunkBo(tSpanChunk); + } + + private ServiceType getApplicationServiceType(SpanChunkBo spanChunk) { + final short applicationServiceTypeCode = spanChunk.getApplicationServiceType();; return registry.findServiceType(applicationServiceTypeCode); } } \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanHandler.java index b7705c74dbda..08c4f168ab5a 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/SpanHandler.java @@ -19,6 +19,9 @@ import java.util.List; import com.navercorp.pinpoint.collector.dao.TraceDao; +import com.navercorp.pinpoint.common.server.bo.SpanBo; +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; +import com.navercorp.pinpoint.common.server.bo.SpanFactory; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; import com.navercorp.pinpoint.common.trace.ServiceType; @@ -30,9 +33,7 @@ import com.navercorp.pinpoint.collector.dao.ApplicationTraceIndexDao; import com.navercorp.pinpoint.collector.dao.HostApplicationMapDao; -import com.navercorp.pinpoint.common.util.SpanEventUtils; import com.navercorp.pinpoint.thrift.dto.TSpan; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -62,6 +63,9 @@ public class SpanHandler implements SimpleHandler { @Autowired private ServiceTypeRegistryService registry; + @Autowired + private SpanFactory spanFactory; + public void handleSimple(TBase tbase) { if (!(tbase instanceof TSpan)) { @@ -69,52 +73,56 @@ public void handleSimple(TBase tbase) { } try { - final TSpan span = (TSpan) tbase; + final TSpan tSpan = (TSpan) tbase; if (logger.isDebugEnabled()) { - logger.debug("Received SPAN={}", span); + logger.debug("Received SPAN={}", tSpan); } - traceDao.insert(span); - applicationTraceIndexDao.insert(span); + + final SpanBo spanBo = spanFactory.buildSpanBo(tSpan); + + traceDao.insert(spanBo); + applicationTraceIndexDao.insert(tSpan); // insert statistics info for server map - insertAcceptorHost(span); - insertSpanStat(span); - insertSpanEventStat(span); + insertAcceptorHost(spanBo); + insertSpanStat(spanBo); + insertSpanEventStat(spanBo); } catch (Exception e) { logger.warn("Span handle error. Caused:{}. Span:{}",e.getMessage(), tbase, e); } } - private void insertSpanStat(TSpan span) { + + private void insertSpanStat(SpanBo span) { final ServiceType applicationServiceType = getApplicationServiceType(span); final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); - // TODO consider to change span.isSetErr(); - final boolean isError = span.getErr() != 0; + + final boolean isError = span.getErrCode() != 0; int bugCheck = 0; if (span.getParentSpanId() == -1) { if (spanServiceType.isQueue()) { // create virtual queue node - statisticsHandler.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationName(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); + statisticsHandler.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); - statisticsHandler.updateCallee(span.getApplicationName(), applicationServiceType, span.getAcceptorHost(), spanServiceType, span.getAgentId(), span.getElapsed(), isError); + statisticsHandler.updateCallee(span.getApplicationId(), applicationServiceType, span.getAcceptorHost(), spanServiceType, span.getAgentId(), span.getElapsed(), isError); } else { // create virtual user - statisticsHandler.updateCaller(span.getApplicationName(), ServiceType.USER, span.getAgentId(), span.getApplicationName(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); + statisticsHandler.updateCaller(span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); // update the span information of the current node (self) - statisticsHandler.updateCallee(span.getApplicationName(), applicationServiceType, span.getApplicationName(), ServiceType.USER, span.getAgentId(), span.getElapsed(), isError); + statisticsHandler.updateCallee(span.getApplicationId(), applicationServiceType, span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getElapsed(), isError); } bugCheck++; } // save statistics info only when parentApplicationContext exists // when drawing server map based on statistics info, you must know the application name of the previous node. - if (span.getParentApplicationName() != null) { - String parentApplicationName = span.getParentApplicationName(); + if (span.getParentApplicationId() != null) { + String parentApplicationName = span.getParentApplicationId(); logger.debug("Received parent application name. {}", parentApplicationName); - ServiceType parentApplicationType = registry.findServiceType(span.getParentApplicationType()); + ServiceType parentApplicationType = registry.findServiceType(span.getParentApplicationServiceType()); // create virtual queue node if current' span's service type is a queue AND : // 1. parent node's application service type is not a queue (it may have come from a queue that is traced) @@ -124,14 +132,14 @@ private void insertSpanStat(TSpan span) { // emulate virtual queue node's accept Span and record it's acceptor host hostApplicationMapDao.insert(span.getRemoteAddr(), span.getAcceptorHost(), spanServiceType.getCode(), parentApplicationName, parentApplicationType.getCode()); // emulate virtual queue node's send SpanEvent - statisticsHandler.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationName(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); + statisticsHandler.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); parentApplicationName = span.getAcceptorHost(); parentApplicationType = spanServiceType; } } - statisticsHandler.updateCallee(span.getApplicationName(), applicationServiceType, parentApplicationName, parentApplicationType, span.getAgentId(), span.getElapsed(), isError); + statisticsHandler.updateCallee(span.getApplicationId(), applicationServiceType, parentApplicationName, parentApplicationType, span.getAgentId(), span.getElapsed(), isError); bugCheck++; } @@ -140,16 +148,16 @@ private void insertSpanStat(TSpan span) { // it is odd to record reversely, because of already recording the caller data at previous node. // the data may be different due to timeout or network error. - statisticsHandler.updateResponseTime(span.getApplicationName(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); + statisticsHandler.updateResponseTime(span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); if (bugCheck != 1) { logger.warn("ambiguous span found(bug). span:{}", span); } } - private void insertSpanEventStat(TSpan span) { + private void insertSpanEventStat(SpanBo span) { - final List spanEventList = span.getSpanEventList(); + final List spanEventList = span.getSpanEventBoList(); if (CollectionUtils.isEmpty(spanEventList)) { return; } @@ -158,7 +166,7 @@ private void insertSpanEventStat(TSpan span) { logger.debug("handle spanEvent size:{}", spanEventList.size()); // TODO need to batch update later. - for (TSpanEvent spanEvent : spanEventList) { + for (SpanEventBo spanEvent : spanEventList) { final ServiceType spanEventType = registry.findServiceType(spanEvent.getServiceType()); if (!spanEventType.isRecordStatistics()) { continue; @@ -166,31 +174,31 @@ private void insertSpanEventStat(TSpan span) { // if terminal update statistics final int elapsed = spanEvent.getEndElapsed(); - final boolean hasException = SpanEventUtils.hasException(spanEvent); + final boolean hasException = spanEvent.hasException(); /** * save information to draw a server map based on statistics */ // save the information of caller (the spanevent that called span) - statisticsHandler.updateCaller(span.getApplicationName(), applicationServiceType, span.getAgentId(), spanEvent.getDestinationId(), spanEventType, spanEvent.getEndPoint(), elapsed, hasException); + statisticsHandler.updateCaller(span.getApplicationId(), applicationServiceType, span.getAgentId(), spanEvent.getDestinationId(), spanEventType, spanEvent.getEndPoint(), elapsed, hasException); // save the information of callee (the span that spanevent called) - statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEventType, span.getApplicationName(), applicationServiceType, span.getEndPoint(), elapsed, hasException); + statisticsHandler.updateCallee(spanEvent.getDestinationId(), spanEventType, span.getApplicationId(), applicationServiceType, span.getEndPoint(), elapsed, hasException); } } - private void insertAcceptorHost(TSpan span) { + private void insertAcceptorHost(SpanBo span) { // save host application map // acceptor host is set at profiler module only when the span is not the kind of root span final String acceptorHost = span.getAcceptorHost(); if (acceptorHost == null) { return; } - final String spanApplicationName = span.getApplicationName(); + final String spanApplicationName = span.getApplicationId(); final short applicationServiceTypeCode = getApplicationServiceType(span).getCode(); - final String parentApplicationName = span.getParentApplicationName(); - final short parentServiceType = span.getParentApplicationType(); + final String parentApplicationName = span.getParentApplicationId(); + final short parentServiceType = span.getParentApplicationServiceType(); final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); if (spanServiceType.isQueue()) { @@ -200,9 +208,9 @@ private void insertAcceptorHost(TSpan span) { } } - private ServiceType getApplicationServiceType(TSpan span) { - // Check if applicationServiceType is set. If not, use span's service type. - final short applicationServiceTypeCode = span.isSetApplicationServiceType() ? span.getApplicationServiceType() : span.getServiceType(); + private ServiceType getApplicationServiceType(SpanBo span) { + // Check if applicationServiceType is set. If not, use span's service type. + final short applicationServiceTypeCode = span.getApplicationServiceType(); return registry.findServiceType(applicationServiceTypeCode); } } diff --git a/collector/src/main/resources/applicationContext-collector.xml b/collector/src/main/resources/applicationContext-collector.xml index 10a968e15705..407b895c3dcb 100644 --- a/collector/src/main/resources/applicationContext-collector.xml +++ b/collector/src/main/resources/applicationContext-collector.xml @@ -22,7 +22,7 @@ com.navercorp.pinpoint.collector.util, com.navercorp.pinpoint.collector.config, com.navercorp.pinpoint.common.server.util, - com.navercorp.pinpoint.common.server.bo.serializer" /> + com.navercorp.pinpoint.common.server.bo" /> @@ -288,7 +288,7 @@ - + \ No newline at end of file diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBo.java index 2ee638b579ed..fa0bae3c9771 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBo.java @@ -18,17 +18,15 @@ import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.util.AnnotationTranscoder; -import com.navercorp.pinpoint.thrift.dto.TAnnotation; /** * @author emeroad */ public class AnnotationBo { + @Deprecated private static final AnnotationTranscoder transcoder = new AnnotationTranscoder(); - private static final int VERSION_SIZE = 1; - private byte version = 0; private long spanId; @@ -42,16 +40,6 @@ public class AnnotationBo { public AnnotationBo() { } - public AnnotationBo(TAnnotation annotation) { - if (annotation == null) { - throw new NullPointerException("annotation must not be null"); - } - this.key = annotation.getKey(); - Object value = transcoder.getMappingValue(annotation); - this.valueType = transcoder.getTypeCode(value); - this.byteValue = transcoder.encode(value, this.valueType); - } - @Deprecated public long getSpanId() { return spanId; diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java index af8397fa2d2f..7dd1d0a37da7 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java @@ -4,7 +4,6 @@ import com.navercorp.pinpoint.common.util.AnnotationTranscoder; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java index 066372563b07..5d8e3acec4f4 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java @@ -19,7 +19,6 @@ import com.navercorp.pinpoint.common.buffer.Buffer; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationComparator.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationComparator.java new file mode 100644 index 000000000000..7b6c5584c071 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationComparator.java @@ -0,0 +1,16 @@ +package com.navercorp.pinpoint.common.server.bo; + +import java.util.Comparator; + +/** + * @author Woonduk Kang(emeroad) + */ +public class AnnotationComparator implements Comparator { + + public static final AnnotationComparator INSTANCE = new AnnotationComparator(); + + @Override + public int compare(AnnotationBo o1, AnnotationBo o2) { + return Integer.compare(o1.getKey(), o2.getKey()); + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/BasicSpan.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/BasicSpan.java new file mode 100644 index 000000000000..b4c8be380029 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/BasicSpan.java @@ -0,0 +1,26 @@ +package com.navercorp.pinpoint.common.server.bo; + +/** + * @author Woonduk Kang(emeroad) + */ +public interface BasicSpan { + + String getAgentId(); + void setAgentId(String agentId); + + String getApplicationId(); + void setApplicationId(String applicationId); + + long getAgentStartTime(); + void setAgentStartTime(long agentStartTime); + + long getSpanId(); + void setSpanId(long spanId); + + String getTraceAgentId(); + long getTraceAgentStartTime(); + long getTraceTransactionSequence(); + + +// List getSpanEventBoList(); +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/Event.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/Event.java new file mode 100644 index 000000000000..397c9146d76c --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/Event.java @@ -0,0 +1,29 @@ +/* + * 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.common.server.bo; + +import java.util.List; + +/** + * @author emeroad + */ +public interface Event { + + short getServiceType(); + + List getAnnotationBoList(); +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java index 733f8e1ca5d0..91452d989a13 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java @@ -17,24 +17,17 @@ package com.navercorp.pinpoint.common.server.bo; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import com.navercorp.pinpoint.common.buffer.AutomaticBuffer; import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.buffer.OffsetFixedBuffer; -import com.navercorp.pinpoint.common.util.TransactionId; import com.navercorp.pinpoint.common.util.TransactionIdUtils; -import com.navercorp.pinpoint.thrift.dto.TAnnotation; -import com.navercorp.pinpoint.thrift.dto.TIntStringValue; -import com.navercorp.pinpoint.thrift.dto.TSpan; /** * @author emeroad */ -public class SpanBo implements Span { - - private static final int VERSION_SIZE = 1; +public class SpanBo implements Event, BasicSpan { // version 0 means that the type of prefix's size is int private byte version = 0; @@ -50,6 +43,9 @@ public class SpanBo implements Span { private long spanId; private long parentSpanId; + private String parentApplicationId; + private short parentApplicationServiceType; + private long startTime; private int elapsed; @@ -78,73 +74,8 @@ public class SpanBo implements Span { private byte loggingTransactionInfo; //optional - public SpanBo(TSpan span) { - if (span == null) { - throw new NullPointerException("span must not be null"); - } - this.agentId = span.getAgentId(); - this.applicationId = span.getApplicationName(); - this.agentStartTime = span.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(span.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = span.getSpanId(); - this.parentSpanId = span.getParentSpanId(); - - this.startTime = span.getStartTime(); - this.elapsed = span.getElapsed(); - - this.rpc = span.getRpc(); - - this.serviceType = span.getServiceType(); - this.endPoint = span.getEndPoint(); - this.flag = span.getFlag(); - this.apiId = span.getApiId(); - - this.errCode = span.getErr(); - - this.acceptorHost = span.getAcceptorHost(); - this.remoteAddr = span.getRemoteAddr(); - - this.loggingTransactionInfo = span.getLoggingTransactionInfo(); - - // FIXME (2015.03) Legacy - applicationServiceType added in v1.1.0 - // applicationServiceType is not saved for older versions where applicationServiceType does not exist. - if (span.isSetApplicationServiceType()) { - this.applicationServiceType = span.getApplicationServiceType(); - } - // FIXME span.errCode contains error of span and spanEvent - // because exceptionInfo is the error information of span itself, exceptionInfo can be null even if errCode is not 0 - final TIntStringValue exceptionInfo = span.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - this.annotationBoList = buildAnnotationList(span.getAnnotations()); - } - - public SpanBo(String traceAgentId, long traceAgentStartTime, long traceTransactionSequence, long startTime, int elapsed, long spanId) { - if (traceAgentId == null) { - throw new NullPointerException("traceAgentId must not be null"); - } - this.traceAgentId = traceAgentId; - this.traceAgentStartTime = traceAgentStartTime; - this.traceTransactionSequence = traceTransactionSequence; - - this.startTime = startTime; - this.elapsed = elapsed; - - this.spanId = spanId; - } public SpanBo() { } @@ -296,17 +227,6 @@ public List getAnnotationBoList() { return annotationBoList; } - private List buildAnnotationList(List anoList) { - if (anoList == null) { - return Collections.emptyList(); - } - List boList = new ArrayList<>(anoList.size()); - for (TAnnotation ano : anoList) { - final AnnotationBo annotationBo = new AnnotationBo(ano); - boList.add(annotationBo); - } - return boList; - } public void setAnnotationBoList(List anoList) { if (anoList == null) { @@ -421,6 +341,22 @@ public short getApplicationServiceType() { } } + public String getParentApplicationId() { + return parentApplicationId; + } + + public void setParentApplicationId(String parentApplicationId) { + this.parentApplicationId = parentApplicationId; + } + + public short getParentApplicationServiceType() { + return parentApplicationServiceType; + } + + public void setParentApplicationServiceType(short parentApplicationServiceType) { + this.parentApplicationServiceType = parentApplicationServiceType; + } + /** * @see com.navercorp.pinpoint.common.trace.LoggingInfo * @return loggingInfo key diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanChunkBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanChunkBo.java index 077d4c2709ab..a3a1f1915391 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanChunkBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanChunkBo.java @@ -1,15 +1,12 @@ package com.navercorp.pinpoint.common.server.bo; -import com.navercorp.pinpoint.thrift.dto.TSpanEvent; - -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; /** * @author Woonduk Kang(emeroad) */ -public class SpanChunkBo { +public class SpanChunkBo implements BasicSpan { private byte version = 0; @@ -22,10 +19,17 @@ public class SpanChunkBo { private long traceTransactionSequence; private long spanId; + private String endPoint; + + private short serviceType; + private Short applicationServiceType; private List spanEventBoList = new ArrayList<>(); + private long collectorAcceptTime; + + public SpanChunkBo() { } @@ -93,6 +97,14 @@ public void setSpanId(long spanId) { this.spanId = spanId; } + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + public long getCollectorAcceptTime() { return collectorAcceptTime; } @@ -101,6 +113,30 @@ public void setCollectorAcceptTime(long collectorAcceptTime) { this.collectorAcceptTime = collectorAcceptTime; } + public void setApplicationServiceType(Short applicationServiceType) { + this.applicationServiceType = applicationServiceType; + } + + public short getServiceType() { + return serviceType; + } + + public void setServiceType(short serviceType) { + this.serviceType = serviceType; + } + + public boolean hasApplicationServiceType() { + return applicationServiceType != null; + } + + public short getApplicationServiceType() { + if (hasApplicationServiceType()) { + return this.applicationServiceType; + } else { + return this.serviceType; + } + } + public List getSpanEventBoList() { return spanEventBoList; } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java index b5e102ccf5d9..73a70569f781 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java @@ -16,22 +16,18 @@ package com.navercorp.pinpoint.common.server.bo; -import java.util.ArrayList; import java.util.List; import com.navercorp.pinpoint.common.buffer.AutomaticBuffer; import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.buffer.OffsetFixedBuffer; -import com.navercorp.pinpoint.common.util.TransactionId; -import com.navercorp.pinpoint.common.util.TransactionIdUtils; -import com.navercorp.pinpoint.thrift.dto.*; /** * @author emeroad * @author jaehong.kim */ -public class SpanEventBo implements Span { - private static final int VERSION_SIZE = 1; +public class SpanEventBo implements Event { + // version 0 means that the type of prefix's size is int private byte version = 0; @@ -76,136 +72,6 @@ public class SpanEventBo implements Span { public SpanEventBo() { } - public SpanEventBo(TSpan tSpan, TSpanEvent tSpanEvent) { - if (tSpan == null) { - throw new NullPointerException("tSpan must not be null"); - } - if (tSpanEvent == null) { - throw new NullPointerException("tSpanEvent must not be null"); - } - - this.agentId = tSpan.getAgentId(); - this.applicationId = tSpan.getApplicationName(); - this.agentStartTime = tSpan.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpan.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = tSpan.getSpanId(); - this.sequence = tSpanEvent.getSequence(); - - this.startElapsed = tSpanEvent.getStartElapsed(); - this.endElapsed = tSpanEvent.getEndElapsed(); - - this.rpc = tSpanEvent.getRpc(); - this.serviceType = tSpanEvent.getServiceType(); - - - this.destinationId = tSpanEvent.getDestinationId(); - - this.endPoint = tSpanEvent.getEndPoint(); - this.apiId = tSpanEvent.getApiId(); - - if (tSpanEvent.isSetDepth()) { - this.depth = tSpanEvent.getDepth(); - } - - if (tSpanEvent.isSetNextSpanId()) { - this.nextSpanId = tSpanEvent.getNextSpanId(); - } - - this.annotationBoList = buildAnnotationList(tSpanEvent.getAnnotations()); - - final TIntStringValue exceptionInfo = tSpanEvent.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - - if (tSpanEvent.isSetAsyncId()) { - this.asyncId = tSpanEvent.getAsyncId(); - } - - if (tSpanEvent.isSetNextAsyncId()) { - this.nextAsyncId = tSpanEvent.getNextAsyncId(); - } - - if (tSpanEvent.isSetAsyncSequence()) { - this.asyncSequence = tSpanEvent.getAsyncSequence(); - } - } - - public SpanEventBo(TSpanChunk spanChunk, TSpanEvent spanEvent) { - if (spanChunk == null) { - throw new NullPointerException("spanChunk must not be null"); - } - if (spanEvent == null) { - throw new NullPointerException("spanEvent must not be null"); - } - - this.agentId = spanChunk.getAgentId(); - this.applicationId = spanChunk.getApplicationName(); - this.agentStartTime = spanChunk.getAgentStartTime(); - - final TransactionId transactionId = TransactionIdUtils.parseTransactionId(spanChunk.getTransactionId()); - this.traceAgentId = transactionId.getAgentId(); - if (traceAgentId == null) { - traceAgentId = this.agentId; - } - this.traceAgentStartTime = transactionId.getAgentStartTime(); - this.traceTransactionSequence = transactionId.getTransactionSequence(); - - this.spanId = spanChunk.getSpanId(); - this.sequence = spanEvent.getSequence(); - - this.startElapsed = spanEvent.getStartElapsed(); - this.endElapsed = spanEvent.getEndElapsed(); - - this.rpc = spanEvent.getRpc(); - this.serviceType = spanEvent.getServiceType(); - - this.destinationId = spanEvent.getDestinationId(); - - this.endPoint = spanEvent.getEndPoint(); - this.apiId = spanEvent.getApiId(); - - if (spanEvent.isSetDepth()) { - this.depth = spanEvent.getDepth(); - } - - if (spanEvent.isSetNextSpanId()) { - this.nextSpanId = spanEvent.getNextSpanId(); - } - - this.annotationBoList = buildAnnotationList(spanEvent.getAnnotations()); - - final TIntStringValue exceptionInfo = spanEvent.getExceptionInfo(); - if (exceptionInfo != null) { - this.hasException = true; - this.exceptionId = exceptionInfo.getIntValue(); - this.exceptionMessage = exceptionInfo.getStringValue(); - } - - if(spanEvent.isSetAsyncId()) { - this.asyncId = spanEvent.getAsyncId(); - } - - if (spanEvent.isSetNextAsyncId()) { - this.nextAsyncId = spanEvent.getNextAsyncId(); - } - - if (spanEvent.isSetAsyncSequence()) { - this.asyncSequence = spanEvent.getAsyncSequence(); - } - } - - public byte getVersion() { return version; @@ -263,10 +129,12 @@ public void setTraceTransactionSequence(long traceTransactionSequence) { this.traceTransactionSequence = traceTransactionSequence; } + @Deprecated public void setSpanId(long spanId) { this.spanId = spanId; } + @Deprecated public long getSpanId() { return this.spanId; } @@ -356,17 +224,6 @@ public void setNextSpanId(long nextSpanId) { this.nextSpanId = nextSpanId; } - private List buildAnnotationList(List annotationList) { - if (annotationList == null) { - return new ArrayList<>(); - } - List boList = new ArrayList(annotationList.size()); - for (TAnnotation annotation : annotationList) { - AnnotationBo annotationBo = new AnnotationBo(annotation); - boList.add(annotationBo); - } - return boList; - } public void setAnnotationBoList(List annotationList) { if (annotationList == null) { diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventComparator.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventComparator.java new file mode 100644 index 000000000000..472aab660dbc --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventComparator.java @@ -0,0 +1,34 @@ +package com.navercorp.pinpoint.common.server.bo; + +import java.util.Comparator; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanEventComparator implements Comparator { + + public static final SpanEventComparator INSTANCE = new SpanEventComparator(); + + @Override + public int compare(SpanEventBo o1, SpanEventBo o2) { + final int sequenceCompare = Short.compare(o1.getSequence(), o2.getSequence()); + if (sequenceCompare != 0) { + return sequenceCompare; + } + final int asyncId1 = o1.getAsyncId(); + final int asyncId2 = o2.getAsyncId(); + final int asyncIdCompare = Integer.compare(asyncId1, asyncId2); + if (asyncIdCompare != 0) { +// bug Comparison method violates its general contract! +// TODO temporary fix +// if (asyncId1 == -1) { +// return -1; +// } +// if (asyncId2 == -1) { +// return -1; +// } + return asyncIdCompare; + } + return Integer.compare(o1.getAsyncSequence(), o2.getAsyncSequence()); + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanFactory.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanFactory.java new file mode 100644 index 000000000000..cb10caeff5a0 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanFactory.java @@ -0,0 +1,287 @@ +package com.navercorp.pinpoint.common.server.bo; + + + +import com.navercorp.pinpoint.common.server.bo.filter.EmptySpanEventFilter; +import com.navercorp.pinpoint.common.server.bo.filter.SpanEventFilter; +import com.navercorp.pinpoint.common.server.util.AcceptedTimeService; +import com.navercorp.pinpoint.common.server.util.EmptyAcceptedTimeService; +import com.navercorp.pinpoint.common.util.AnnotationTranscoder; +import com.navercorp.pinpoint.common.util.TransactionId; +import com.navercorp.pinpoint.common.util.TransactionIdUtils; +import com.navercorp.pinpoint.thrift.dto.TAnnotation; +import com.navercorp.pinpoint.thrift.dto.TIntStringValue; +import com.navercorp.pinpoint.thrift.dto.TSpan; +import com.navercorp.pinpoint.thrift.dto.TSpanChunk; +import com.navercorp.pinpoint.thrift.dto.TSpanEvent; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +@Component +public class SpanFactory { + + + private SpanEventFilter spanEventFilter = new EmptySpanEventFilter(); + + private AcceptedTimeService acceptedTimeService = new EmptyAcceptedTimeService(); + + private static final AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + public SpanFactory() { + } + + @Autowired + public void setSpanEventFilter(SpanEventFilter spanEventFilter) { + this.spanEventFilter = spanEventFilter; + } + + @Autowired + public void setAcceptedTimeService(AcceptedTimeService acceptedTimeService) { + this.acceptedTimeService = acceptedTimeService; + } + + public SpanBo buildSpanBo(TSpan tSpan) { + + final SpanBo spanBo = newSpanBo(tSpan); + + List spanEventList = tSpan.getSpanEventList(); + List spanEventBoList = buildSpanEventBoList(spanBo, spanEventList); + spanBo.addSpanEventBoList(spanEventBoList); + + long acceptedTime = acceptedTimeService.getAcceptedTime(); + spanBo.setCollectorAcceptTime(acceptedTime); + + return spanBo; + } + + public SpanBo newSpanBo(TSpan tSpan) { + final SpanBo spanBo = new SpanBo(); + spanBo.setAgentId(tSpan.getAgentId()); + spanBo.setApplicationId(tSpan.getApplicationName()); + spanBo.setAgentStartTime(tSpan.getAgentStartTime()); + + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpan.getTransactionId()); + final String traceAgentId = transactionId.getAgentId(); + if (traceAgentId == null) { + spanBo.setTraceAgentId(spanBo.getAgentId()); + } else { + spanBo.setTraceAgentId(traceAgentId); + } + spanBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); + spanBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); + + spanBo.setSpanId(tSpan.getSpanId()); + spanBo.setParentSpanId(tSpan.getParentSpanId()); + + spanBo.setStartTime(tSpan.getStartTime()); + spanBo.setElapsed(tSpan.getElapsed()); + + spanBo.setRpc(tSpan.getRpc()); + + spanBo.setServiceType(tSpan.getServiceType()); + spanBo.setEndPoint(tSpan.getEndPoint()); + spanBo.setFlag(tSpan.getFlag()); + spanBo.setApiId(tSpan.getApiId()); + + spanBo.setErrCode(tSpan.getErr()); + + spanBo.setAcceptorHost(tSpan.getAcceptorHost()); + spanBo.setRemoteAddr(tSpan.getRemoteAddr()); + + spanBo.setLoggingTransactionInfo(tSpan.getLoggingTransactionInfo()); + + // FIXME (2015.03) Legacy - applicationServiceType added in v1.1.0 + // applicationServiceType is not saved for older versions where applicationServiceType does not exist. + if (tSpan.isSetApplicationServiceType()) { + spanBo.setApplicationServiceType(tSpan.getApplicationServiceType()); + } else { + spanBo.setApplicationServiceType(tSpan.getServiceType()); + } + + spanBo.setParentApplicationId(tSpan.getParentApplicationName()); + spanBo.setParentApplicationServiceType(tSpan.getParentApplicationType()); + + // FIXME span.errCode contains error of span and spanEvent + // because exceptionInfo is the error information of span itself, exceptionInfo can be null even if errCode is not 0 + final TIntStringValue exceptionInfo = tSpan.getExceptionInfo(); + if (exceptionInfo != null) { + spanBo.setExceptionInfo(exceptionInfo.getIntValue(), exceptionInfo.getStringValue()); + } + + List annotationBoList = buildAnnotationList(tSpan.getAnnotations()); + spanBo.setAnnotationBoList(annotationBoList); + + return spanBo; + } + + + + private SpanEventBo newSpanEventBo(BasicSpan basicSpan, TSpanEvent tSpanEvent) { + if (basicSpan == null) { + throw new NullPointerException("basicSpan must not be null"); + } + if (tSpanEvent == null) { + throw new NullPointerException("tSpanEvent must not be null"); + } + + final SpanEventBo spanEvent = new SpanEventBo(); + spanEvent.setAgentId(basicSpan.getAgentId()); + spanEvent.setApplicationId(basicSpan.getApplicationId()); + spanEvent.setAgentStartTime(basicSpan.getAgentStartTime()); +// spanEvent.setSpanId(basicSpan.getSpanId()); + + spanEvent.setTraceAgentId(basicSpan.getTraceAgentId()); + spanEvent.setTraceAgentStartTime(basicSpan.getTraceAgentStartTime()); + spanEvent.setTraceTransactionSequence(basicSpan.getTraceTransactionSequence()); + + + bind(spanEvent, tSpanEvent); + return spanEvent; + } + + private void bind(SpanEventBo spanEvent, TSpanEvent tSpanEvent) { + if (spanEvent.getTraceAgentId() == null) { + spanEvent.setTraceAgentId(spanEvent.getAgentId()); + } + + spanEvent.setSequence(tSpanEvent.getSequence()); + + spanEvent.setStartElapsed(tSpanEvent.getStartElapsed()); + spanEvent.setEndElapsed(tSpanEvent.getEndElapsed()); + + spanEvent.setRpc(tSpanEvent.getRpc()); + spanEvent.setServiceType(tSpanEvent.getServiceType()); + + + spanEvent.setDestinationId(tSpanEvent.getDestinationId()); + + spanEvent.setEndPoint(tSpanEvent.getEndPoint()); + spanEvent.setApiId(tSpanEvent.getApiId()); + + if (tSpanEvent.isSetDepth()) { + spanEvent.setDepth(tSpanEvent.getDepth()); + } + + if (tSpanEvent.isSetNextSpanId()) { + spanEvent.setNextSpanId(tSpanEvent.getNextSpanId()); + } + + List annotationList = buildAnnotationList(tSpanEvent.getAnnotations()); + spanEvent.setAnnotationBoList(annotationList); + + final TIntStringValue exceptionInfo = tSpanEvent.getExceptionInfo(); + if (exceptionInfo != null) { + spanEvent.setExceptionInfo(exceptionInfo.getIntValue(), exceptionInfo.getStringValue()); + } + + if (tSpanEvent.isSetAsyncId()) { + spanEvent.setAsyncId(tSpanEvent.getAsyncId()); + } + + if (tSpanEvent.isSetNextAsyncId()) { + spanEvent.setNextAsyncId(tSpanEvent.getNextAsyncId()); + } + + if (tSpanEvent.isSetAsyncSequence()) { + spanEvent.setAsyncSequence(tSpanEvent.getAsyncSequence()); + } + } + + + + public SpanChunkBo buildSpanChunkBo(TSpanChunk tSpanChunk) { + final SpanChunkBo spanChunkBo = new SpanChunkBo(); + spanChunkBo.setAgentId(tSpanChunk.getAgentId()); + spanChunkBo.setApplicationId(tSpanChunk.getApplicationName()); + spanChunkBo.setAgentStartTime(tSpanChunk.getAgentStartTime()); + spanChunkBo.setServiceType(tSpanChunk.getServiceType()); + if (tSpanChunk.isSetApplicationServiceType()) { + spanChunkBo.setApplicationServiceType(tSpanChunk.getApplicationServiceType()); + } else { + spanChunkBo.setApplicationServiceType(tSpanChunk.getServiceType()); + } + + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(tSpanChunk.getTransactionId()); + final String traceAgentId = transactionId.getAgentId(); + if (traceAgentId == null) { + spanChunkBo.setTraceAgentId(spanChunkBo.getAgentId()); + } else { + spanChunkBo.setTraceAgentId(traceAgentId); + } + + + spanChunkBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); + spanChunkBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); + + spanChunkBo.setSpanId(tSpanChunk.getSpanId()); + spanChunkBo.setEndPoint(tSpanChunk.getEndPoint()); + + List spanEventList = tSpanChunk.getSpanEventList(); + List spanEventBoList = buildSpanEventBoList(spanChunkBo, spanEventList); + spanChunkBo.addSpanEventBoList(spanEventBoList); + return spanChunkBo; + } + + + private List buildSpanEventBoList(BasicSpan basicSpan, List spanEventList) { + if (CollectionUtils.isEmpty(spanEventList)) { + return new ArrayList<>(); + } + List spanEventBoList = new ArrayList<>(spanEventList.size()); + for (TSpanEvent tSpanEvent : spanEventList) { + final SpanEventBo spanEventBo = newSpanEventBo(basicSpan, tSpanEvent); + if (!spanEventFilter.filter(spanEventBo)) { + continue; + } + spanEventBoList.add(spanEventBo); + } + + Collections.sort(spanEventBoList, SpanEventComparator.INSTANCE); + return spanEventBoList; + } + + private List buildAnnotationList(List tAnnotationList) { + if (tAnnotationList == null) { + return new ArrayList<>(); + } + List boList = new ArrayList<>(tAnnotationList.size()); + for (TAnnotation tAnnotation : tAnnotationList) { + final AnnotationBo annotationBo = newAnnotationBo(tAnnotation); + boList.add(annotationBo); + } + + Collections.sort(boList, AnnotationComparator.INSTANCE); + return boList; + } + + public SpanEventBo buildSpanEventBo(TSpan tSpan, TSpanEvent tSpanEvent) { + SpanBo spanBo = newSpanBo(tSpan); + return newSpanEventBo(spanBo, tSpanEvent); + } + + private AnnotationBo newAnnotationBo(TAnnotation tAnnotation) { + if (tAnnotation == null) { + throw new NullPointerException("annotation must not be null"); + } + AnnotationBo annotationBo = new AnnotationBo(); + + annotationBo.setKey(tAnnotation.getKey()); + + Object value = transcoder.getMappingValue(tAnnotation); + byte typeCode = transcoder.getTypeCode(value); + byte[] encodeObject = transcoder.encode(value, typeCode); + + annotationBo.setValueType(typeCode); + annotationBo.setByteValue(encodeObject); + + return annotationBo; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/EmptySpanEventFilter.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/EmptySpanEventFilter.java new file mode 100644 index 000000000000..8330f207153e --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/EmptySpanEventFilter.java @@ -0,0 +1,17 @@ +package com.navercorp.pinpoint.common.server.bo.filter; + +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; + +/** + * @author Woonduk Kang(emeroad) + */ +public class EmptySpanEventFilter implements SpanEventFilter { + + public EmptySpanEventFilter() { + } + + @Override + public boolean filter(SpanEventBo spanEventBo) { + return ACCEPT; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilter.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilter.java new file mode 100644 index 000000000000..0a1e815f7d15 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilter.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.common.server.bo.filter; + +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author Woonduk Kang(emeroad) + */ +public class SequenceSpanEventFilter implements SpanEventFilter { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final int MAX_SEQUENCE = Short.MAX_VALUE; + public static final int DEFAULT_SEQUENCE_LIMIT = 1024*10; + + private final int sequenceLimit; + + public SequenceSpanEventFilter() { + this(DEFAULT_SEQUENCE_LIMIT); + } + + public SequenceSpanEventFilter(int sequenceLimit) { + if (sequenceLimit > MAX_SEQUENCE) { + throw new IllegalArgumentException(sequenceLimit + " > MAX_SEQUENCE"); + } + this.sequenceLimit = sequenceLimit; + } + + @Override + public boolean filter(SpanEventBo spanEventBo) { + if (spanEventBo == null) { + return REJECT; + } + final int sequence = spanEventBo.getSequence(); + if (sequence > sequenceLimit) { + if (logger.isDebugEnabled()) { + logger.debug("discard spanEvent:{}", spanEventBo); + } + return REJECT; + } + return ACCEPT; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SpanEventFilter.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SpanEventFilter.java new file mode 100644 index 000000000000..f218b6caae36 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/filter/SpanEventFilter.java @@ -0,0 +1,29 @@ +/* + * Copyright 2016 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.common.server.bo.filter; + +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; + +/** + * @author Woonduk Kang(emeroad) + */ +public interface SpanEventFilter { + boolean ACCEPT = true; + boolean REJECT = false; + + boolean filter(SpanEventBo spanEventBo); +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventEncodingContext.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventEncodingContext.java new file mode 100644 index 000000000000..60296f67b7a6 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventEncodingContext.java @@ -0,0 +1,24 @@ +package com.navercorp.pinpoint.common.server.bo.serializer.trace.v1; + +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SpanEventEncodingContext { + private final long spanId; + private final SpanEventBo spanEventBo; + + public SpanEventEncodingContext(long spanId, SpanEventBo spanEventBo) { + this.spanId = spanId; + this.spanEventBo = spanEventBo; + } + + public long getSpanId() { + return spanId; + } + + public SpanEventBo getSpanEventBo() { + return spanEventBo; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventSerializer.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventSerializer.java index 58811f059ddf..775cd3afae2c 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventSerializer.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v1/SpanEventSerializer.java @@ -19,7 +19,7 @@ * @author Woonduk Kang(emeroad) */ @Component -public class SpanEventSerializer implements HbaseSerializer { +public class SpanEventSerializer implements HbaseSerializer { private AnnotationSerializer annotationSerializer; @@ -29,11 +29,11 @@ public void setAnnotationSerializer(AnnotationSerializer annotationSerializer) { } @Override - public void serialize(SpanEventBo spanEventBo, Put put, SerializationContext context) { + public void serialize(SpanEventEncodingContext spanEventEncodingContext, Put put, SerializationContext context) { - ByteBuffer rowId = writeQualifier(spanEventBo); + ByteBuffer rowId = writeQualifier(spanEventEncodingContext); - final ByteBuffer value = writeValue(spanEventBo); + final ByteBuffer value = writeValue(spanEventEncodingContext); final long acceptedTime = put.getTimeStamp(); @@ -41,16 +41,18 @@ public void serialize(SpanEventBo spanEventBo, Put put, SerializationContext con } - private ByteBuffer writeQualifier(SpanEventBo spanEventBo) { + private ByteBuffer writeQualifier(SpanEventEncodingContext spanEventEncodingContext) { + SpanEventBo spanEventBo = spanEventEncodingContext.getSpanEventBo(); final Buffer rowId = new AutomaticBuffer(); - rowId.putLong(spanEventBo.getSpanId()); + rowId.putLong(spanEventEncodingContext.getSpanId()); rowId.putShort(spanEventBo.getSequence()); rowId.putInt(spanEventBo.getAsyncId()); rowId.putShort(spanEventBo.getAsyncSequence()); return rowId.wrapByteBuffer(); } - public ByteBuffer writeValue(SpanEventBo spanEventBo) { + public ByteBuffer writeValue(SpanEventEncodingContext spanEventEncodingContext) { + SpanEventBo spanEventBo = spanEventEncodingContext.getSpanEventBo(); final Buffer buffer = new AutomaticBuffer(512); buffer.putByte(spanEventBo.getVersion()); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanChunkSerializerV2.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanChunkSerializerV2.java index 7a658f35f8f4..46e9ab422349 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanChunkSerializerV2.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanChunkSerializerV2.java @@ -4,7 +4,6 @@ import com.navercorp.pinpoint.common.server.bo.serializer.HbaseSerializer; import com.navercorp.pinpoint.common.server.bo.serializer.SerializationContext; import org.apache.hadoop.hbase.client.Put; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.nio.ByteBuffer; diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecoderV0.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecoderV0.java index 22945009a3b0..3db978b4df11 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecoderV0.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecoderV0.java @@ -2,6 +2,7 @@ import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.server.bo.AnnotationBo; +import com.navercorp.pinpoint.common.server.bo.BasicSpan; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; import com.navercorp.pinpoint.common.server.bo.SpanEventBo; @@ -57,8 +58,7 @@ private SpanChunkBo readSpanChunk(Buffer qualifier, Buffer columnValue, SpanDeco spanChunk.setCollectorAcceptTime(decodingContext.getCollectorAcceptedTime()); - SpanAdaptor spanAdaptor = new SpanChunkBoAdaptor(spanChunk); - SpanEventBo firstSpanEvent = readQualifier(spanAdaptor, qualifier); + SpanEventBo firstSpanEvent = readQualifier(spanChunk, qualifier); readSpanChunkValue(columnValue, spanChunk, firstSpanEvent, decodingContext); @@ -75,8 +75,7 @@ private SpanBo readSpan(Buffer qualifier, Buffer columnValue, SpanDecodingContex span.setTraceTransactionSequence(transactionId.getTransactionSequence()); span.setCollectorAcceptTime(decodingContext.getCollectorAcceptedTime()); - SpanAdaptor spanAdaptor = new SpanBoAdaptor(span); - SpanEventBo firstSpanEvent = readQualifier(spanAdaptor, qualifier); + SpanEventBo firstSpanEvent = readQualifier(span, qualifier); readSpanValue(columnValue, span, firstSpanEvent, decodingContext); @@ -384,18 +383,18 @@ private AnnotationBo readDeltaAnnotationBo(Buffer buffer, AnnotationBo prev) { } - private SpanEventBo readQualifier(SpanAdaptor span, Buffer buffer) { + private SpanEventBo readQualifier(BasicSpan basicSpan, Buffer buffer) { String applicationId = buffer.readPrefixedString(); - span.setApplicationId(applicationId); + basicSpan.setApplicationId(applicationId); String agentId = buffer.readPrefixedString(); - span.setAgentId(agentId); + basicSpan.setAgentId(agentId); long agentStartTime = buffer.readVLong(); - span.setAgentStartTime(agentStartTime); + basicSpan.setAgentStartTime(agentStartTime); long spanId = buffer.readLong(); - span.setSpanId(spanId); + basicSpan.setSpanId(spanId); int firstSpanEventSequence = buffer.readSVInt(); if (firstSpanEventSequence == -1) { @@ -427,76 +426,5 @@ public void next(SpanDecodingContext decodingContext) { } - // resolve type miss match - private interface SpanAdaptor { - void setApplicationId(String applicationId); - void setAgentId(String agentId); - - void setAgentStartTime(long agentStartTime); - - void setSpanId(long spanId); - } - - private static class SpanBoAdaptor implements SpanAdaptor { - private SpanBo spanBo; - - private SpanBoAdaptor(SpanBo spanBo) { - if (spanBo == null) { - throw new NullPointerException("spanBo must not be null"); - } - this.spanBo = spanBo; - } - - @Override - public void setApplicationId(String applicationId) { - this.spanBo.setApplicationId(applicationId); - } - - @Override - public void setAgentId(String agentId) { - this.spanBo.setAgentId(agentId); - } - - @Override - public void setAgentStartTime(long agentStartTime) { - this.spanBo.setAgentStartTime(agentStartTime); - } - - @Override - public void setSpanId(long spanId) { - this.spanBo.setSpanId(spanId); - } - } - - private static class SpanChunkBoAdaptor implements SpanAdaptor { - private SpanChunkBo spanChunkBo; - - private SpanChunkBoAdaptor(SpanChunkBo spanChunkBo) { - if (spanChunkBo == null) { - throw new NullPointerException("spanChunkBo must not be null"); - } - this.spanChunkBo = spanChunkBo; - } - - @Override - public void setApplicationId(String applicationId) { - this.spanChunkBo.setApplicationId(applicationId); - } - - @Override - public void setAgentId(String agentId) { - this.spanChunkBo.setAgentId(agentId); - } - - @Override - public void setAgentStartTime(long agentStartTime) { - this.spanChunkBo.setAgentStartTime(agentStartTime); - } - - @Override - public void setSpanId(long spanId) { - this.spanChunkBo.setSpanId(spanId); - } - } } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecodingContext.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecodingContext.java index 39270dd5f9d5..e3d2b5d29276 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecodingContext.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanDecodingContext.java @@ -2,9 +2,6 @@ import com.navercorp.pinpoint.common.util.TransactionId; -import java.util.ArrayList; -import java.util.List; - /** * @author Woonduk Kang(emeroad) */ diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoder.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoder.java index c641eb9a9eaa..745c347b7676 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoder.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoder.java @@ -1,12 +1,9 @@ package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2; -import com.navercorp.pinpoint.common.server.bo.AnnotationBo; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; -import com.navercorp.pinpoint.common.server.bo.SpanEventBo; import java.nio.ByteBuffer; -import java.util.Comparator; /** * @author Woonduk Kang(emeroad) @@ -20,38 +17,6 @@ public interface SpanEncoder { byte TYPE_PASSIVE_SPAN = 4; byte TYPE_INDEX = 7; - Comparator SPAN_EVENT_SEQUENCE_COMPARATOR = new Comparator() { - @Override - public int compare(SpanEventBo o1, SpanEventBo o2) { - final int sequenceCompare = Short.compare(o1.getSequence(), o2.getSequence()); - if (sequenceCompare != 0) { - return sequenceCompare; - } - final int asyncId1 = o1.getAsyncId(); - final int asyncId2 = o2.getAsyncId(); - final int asyncIdCompare = Integer.compare(asyncId1, asyncId2); - if (asyncIdCompare != 0) { -// bug Comparison method violates its general contract! -// TODO temporary fix -// if (asyncId1 == -1) { -// return -1; -// } -// if (asyncId2 == -1) { -// return -1; -// } - return asyncIdCompare; - } - return Integer.compare(o1.getAsyncSequence(), o2.getAsyncSequence()); - } - }; - - Comparator ANNOTATION_COMPARATOR = new Comparator() { - @Override - public int compare(AnnotationBo o1, AnnotationBo o2) { - return Integer.compare(o1.getKey(), o2.getKey()); - } - }; - ByteBuffer encodeSpanQualifier(SpanEncodingContext encodingContext); ByteBuffer encodeSpanColumnValue(SpanEncodingContext encodingContext); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoderV0.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoderV0.java index c2a367d63016..05bd0a5e7813 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoderV0.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncoderV0.java @@ -13,7 +13,6 @@ import org.springframework.stereotype.Component; import java.nio.ByteBuffer; -import java.util.Collections; import java.util.List; /** @@ -76,16 +75,13 @@ private SpanEventBo getFirstSpanEvent(List spanEventBoList) { if (CollectionUtils.isEmpty(spanEventBoList)) { return null; } - // TODO duplicated sort - sortSpanEvent(spanEventBoList); + return spanEventBoList.get(0); } @Override public ByteBuffer encodeSpanChunkColumnValue(SpanEncodingContext encodingContext) { final SpanChunkBo spanChunkBo = encodingContext.getValue(); - // TODO duplicated sort - sortSpanEvent(spanChunkBo.getSpanEventBoList()); final Buffer buffer = new AutomaticBuffer(256); @@ -121,8 +117,6 @@ private void writeSpanEventList(Buffer buffer, List spanEventBoList public ByteBuffer encodeSpanColumnValue(SpanEncodingContext encodingContext) { final SpanBo span = encodingContext.getValue(); - sortSpanEvent(span.getSpanEventBoList()); - final SpanBitFiled bitField = SpanBitFiled.build(span); final Buffer buffer = new AutomaticBuffer(256); @@ -200,14 +194,6 @@ public ByteBuffer encodeSpanColumnValue(SpanEncodingContext encodingCont return buffer.wrapByteBuffer(); } - private void sortSpanEvent(List spanEventBoList) { - - if (CollectionUtils.isEmpty(spanEventBoList)) { - return; - } - Collections.sort(spanEventBoList, SPAN_EVENT_SEQUENCE_COMPARATOR); - } - public void writeFirstSpanEvent(Buffer buffer, SpanEventBo spanEventBo, SpanEncodingContext encodingContext) { final SpanEventBitField bitField = SpanEventBitField.buildFirst(spanEventBo); @@ -355,7 +341,6 @@ private void writeAnnotationList(Buffer buffer, List annotationBoL if (CollectionUtils.isEmpty(annotationBoList)) { return; } - Collections.sort(annotationBoList, ANNOTATION_COMPARATOR); buffer.putVInt(annotationBoList.size()); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncodingContext.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncodingContext.java index 14b3387c38fd..fc79552bbd5e 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncodingContext.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/trace/v2/SpanEncodingContext.java @@ -1,7 +1,5 @@ package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2; -import com.navercorp.pinpoint.common.server.bo.AnnotationBo; -import com.navercorp.pinpoint.common.server.bo.SpanBo; /** * @author Woonduk Kang(emeroad) diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/EmptyAcceptedTimeService.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/EmptyAcceptedTimeService.java new file mode 100644 index 000000000000..1ceb4b94beb0 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/EmptyAcceptedTimeService.java @@ -0,0 +1,28 @@ +package com.navercorp.pinpoint.common.server.util; + +/** + * @author Woonduk Kang(emeroad) + */ +public class EmptyAcceptedTimeService implements AcceptedTimeService{ + private final long acceptedTime; + + public EmptyAcceptedTimeService() { + this(0); + } + + public EmptyAcceptedTimeService(long acceptedTime) { + this.acceptedTime = acceptedTime; + } + + public void accept() { + + } + + public void accept(long time) { + + } + + public long getAcceptedTime() { + return acceptedTime; + } +} diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanEventUtils.java similarity index 95% rename from commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java rename to commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanEventUtils.java index 8a7461372135..7d1b505d408c 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/SpanEventUtils.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanEventUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.navercorp.pinpoint.common.util; +package com.navercorp.pinpoint.common.server.util; import com.navercorp.pinpoint.thrift.dto.TSpanEvent; diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanUtils.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanUtils.java new file mode 100644 index 000000000000..699244433216 --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/SpanUtils.java @@ -0,0 +1,124 @@ +/* + * 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.common.server.util; + +import static com.navercorp.pinpoint.common.PinpointConstants.*; + +import com.navercorp.pinpoint.common.buffer.AutomaticBuffer; +import com.navercorp.pinpoint.common.buffer.Buffer; +import com.navercorp.pinpoint.common.server.bo.SpanBo; +import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; +import com.navercorp.pinpoint.common.util.BytesUtils; +import com.navercorp.pinpoint.common.util.RowKeyUtils; +import com.navercorp.pinpoint.common.util.TimeUtils; +import com.navercorp.pinpoint.common.util.TransactionId; +import com.navercorp.pinpoint.common.util.TransactionIdUtils; +import com.navercorp.pinpoint.thrift.dto.TSpan; +import com.navercorp.pinpoint.thrift.dto.TSpanChunk; + +/** + * @author emeroad + */ +public final class SpanUtils { + private SpanUtils() { + } + + @Deprecated + public static byte[] getAgentIdTraceIndexRowKey(String agentId, long timestamp) { + if (agentId == null) { + throw new IllegalArgumentException("agentId must not null"); + } + final byte[] bAgentId = BytesUtils.toBytes(agentId); + return RowKeyUtils.concatFixedByteAndLong(bAgentId, AGENT_NAME_MAX_LEN, TimeUtils.reverseTimeMillis(timestamp)); + } + + public static byte[] getApplicationTraceIndexRowKey(String applicationName, long timestamp) { + if (applicationName == null) { + throw new IllegalArgumentException("agentId must not null"); + } + final byte[] bApplicationName = BytesUtils.toBytes(applicationName); + return RowKeyUtils.concatFixedByteAndLong(bApplicationName, AGENT_NAME_MAX_LEN, TimeUtils.reverseTimeMillis(timestamp)); + } + + public static byte[] getTraceIndexRowKey(byte[] agentId, long timestamp) { + if (agentId == null) { + throw new NullPointerException("agentId must not be null"); + } + return RowKeyUtils.concatFixedByteAndLong(agentId, AGENT_NAME_MAX_LEN, TimeUtils.reverseTimeMillis(timestamp)); + } + + public static byte[] getVarTransactionId(TSpan span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + final byte[] transactionIdBytes = span.getTransactionId(); + TransactionId transactionId = TransactionIdUtils.parseTransactionId(transactionIdBytes); + String agentId = transactionId.getAgentId(); + if (agentId == null) { + agentId = span.getAgentId(); + } + + final Buffer buffer= new AutomaticBuffer(32); + buffer.putPrefixedString(agentId); + buffer.putSVLong(transactionId.getAgentStartTime()); + buffer.putVLong(transactionId.getTransactionSequence()); + return buffer.getBuffer(); + } + + public static byte[] getTransactionId(TSpan span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + final byte[] transactionIdBytes = span.getTransactionId(); + TransactionId transactionId = TransactionIdUtils.parseTransactionId(transactionIdBytes); + String agentId = transactionId.getAgentId(); + if (agentId == null) { + agentId = span.getAgentId(); + } + return BytesUtils.stringLongLongToBytes(agentId, AGENT_NAME_MAX_LEN, transactionId.getAgentStartTime(), transactionId.getTransactionSequence()); + + } + + public static byte[] getTransactionId(SpanBo span) { + if (span == null) { + throw new NullPointerException("span must not be null"); + } + + return BytesUtils.stringLongLongToBytes(span.getTraceAgentId(), AGENT_NAME_MAX_LEN, span.getAgentStartTime(), span.getTraceTransactionSequence()); + } + + public static byte[] getTransactionId(TSpanChunk spanChunk) { + if (spanChunk == null) { + throw new NullPointerException("spanChunk must not be null"); + } + final byte[] transactionIdBytes = spanChunk.getTransactionId(); + final TransactionId transactionId = TransactionIdUtils.parseTransactionId(transactionIdBytes); + String agentId = transactionId.getAgentId(); + if (agentId == null) { + agentId = spanChunk.getAgentId(); + } + return BytesUtils.stringLongLongToBytes(agentId, AGENT_NAME_MAX_LEN, transactionId.getAgentStartTime(), transactionId.getTransactionSequence()); + } + + public static byte[] getTransactionId(SpanChunkBo spanChunkBo) { + if (spanChunkBo == null) { + throw new NullPointerException("span must not be null"); + } + + return BytesUtils.stringLongLongToBytes(spanChunkBo.getTraceAgentId(), AGENT_NAME_MAX_LEN, spanChunkBo.getAgentStartTime(), spanChunkBo.getTraceTransactionSequence()); + } +} diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java index a3130a63823a..d6f7d1a21f30 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.common.server.bo; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.AnnotationSerializer; +import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanEventEncodingContext; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanEventSerializer; import com.navercorp.pinpoint.common.trace.ServiceType; @@ -57,12 +58,12 @@ public void testSerialize() throws Exception { spanEventBo.setRpc("rpc"); spanEventBo.setServiceType(ServiceType.STAND_ALONE.getCode()); - spanEventBo.setSpanId(12); spanEventBo.setStartElapsed(100); spanEventBo.setNextAsyncId(1000); ByteBuffer deprecatedBytes = ByteBuffer.wrap(spanEventBo.writeValue()); - ByteBuffer bytes = serializer.writeValue(spanEventBo); + SpanEventEncodingContext spanEventEncodingContext = new SpanEventEncodingContext(12, spanEventBo); + ByteBuffer bytes = serializer.writeValue(spanEventEncodingContext); Assert.assertEquals(bytes, deprecatedBytes); SpanEventBo newSpanEventBo = new SpanEventBo(); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilterTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilterTest.java new file mode 100644 index 000000000000..7684b8c860c0 --- /dev/null +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/filter/SequenceSpanEventFilterTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 NAVER Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.navercorp.pinpoint.common.server.bo.filter; + +import com.navercorp.pinpoint.common.server.bo.SpanEventBo; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Woonduk Kang(emeroad) + */ +public class SequenceSpanEventFilterTest { + + @Test + public void testFilter_accept() throws Exception { + SpanEventFilter filter = new SequenceSpanEventFilter(100); + + final SpanEventBo spanEventBo = new SpanEventBo(); + spanEventBo.setSequence((short)11); + + Assert.assertEquals(filter.filter(spanEventBo), SpanEventFilter.ACCEPT); + + } + + + @Test + public void testFilter_reject() throws Exception { + SpanEventFilter filter = new SequenceSpanEventFilter(10); + + final SpanEventBo spanEventBo = new SpanEventBo(); + spanEventBo.setSequence((short)11); + + Assert.assertEquals(filter.filter(spanEventBo), SpanEventFilter.REJECT); + + } + + @Test + public void testFilter_max() throws Exception { + new SequenceSpanEventFilter(Short.MAX_VALUE); + + try { + new SequenceSpanEventFilter(Short.MAX_VALUE + 1); + Assert.fail(); + } catch (Exception e) { + } + + } + +} \ No newline at end of file diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/util/SpanUtilsTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/util/SpanUtilsTest.java new file mode 100644 index 000000000000..0e3eebd77162 --- /dev/null +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/util/SpanUtilsTest.java @@ -0,0 +1,88 @@ +/* + * 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.common.server.util; + +import java.util.Arrays; + +import com.google.common.primitives.Longs; +import com.navercorp.pinpoint.common.PinpointConstants; +import com.navercorp.pinpoint.common.util.BytesUtils; +import com.navercorp.pinpoint.common.util.TimeUtils; +import com.navercorp.pinpoint.thrift.dto.TSpan; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author emeroad + */ +public class SpanUtilsTest { + @Test + public void testGetTraceIndexRowKeyWhiteSpace() throws Exception { + String agentId = "test test"; + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey1() throws Exception { + String agentId = "test"; + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey2() throws Exception { + String agentId = ""; + for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN; i++) { + agentId += "1"; + } + + long time = System.currentTimeMillis(); + check(agentId, time); + } + + @Test + public void testGetTraceIndexRowKey3() throws Exception { + String agentId = ""; + for (int i = 0; i < PinpointConstants.AGENT_NAME_MAX_LEN + 1; i++) { + agentId += "1"; + } + + long time = System.currentTimeMillis(); + try { + check(agentId, time); + Assert.fail("error"); + } catch (IndexOutOfBoundsException ignore) { + } + } + + private void check(String agentId0, long l1) { + TSpan span = new TSpan(); + span.setAgentId(agentId0); + span.setStartTime(l1); + + byte[] traceIndexRowKey = SpanUtils.getAgentIdTraceIndexRowKey(span.getAgentId(), span.getStartTime()); + + String agentId = BytesUtils.toString(traceIndexRowKey, 0, PinpointConstants.AGENT_NAME_MAX_LEN).trim(); + Assert.assertEquals(agentId0, agentId); + + long time = Longs.fromByteArray(Arrays.copyOfRange(traceIndexRowKey, PinpointConstants.AGENT_NAME_MAX_LEN, PinpointConstants.AGENT_NAME_MAX_LEN + 8)); + time = TimeUtils.recoveryTimeMillis(time); + Assert.assertEquals(time, l1); + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/test/junit4/BasePinpointTest.java b/profiler/src/main/java/com/navercorp/pinpoint/test/junit4/BasePinpointTest.java index 7975a75dc3f1..5e4c05f27854 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/test/junit4/BasePinpointTest.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/test/junit4/BasePinpointTest.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import com.navercorp.pinpoint.common.server.bo.SpanFactory; import com.navercorp.pinpoint.profiler.sender.DataSender; import com.navercorp.pinpoint.test.ListenableDataSender; import com.navercorp.pinpoint.test.MockAgent; @@ -45,13 +46,15 @@ public abstract class BasePinpointTest { private volatile TBaseRecorder> tBaseRecorder; private volatile ServerMetaDataHolder serverMetaDataHolder; private final TestableServerMetaDataListener listener = new TestableServerMetaDataListener(); + private final SpanFactory spanFactory = new SpanFactory(); protected List getCurrentSpanEvents() { List spanEvents = new ArrayList(); for (TBase span : this.tBaseRecorder) { if (span instanceof SpanEvent) { SpanEvent spanEvent = (SpanEvent)span; - spanEvents.add(new SpanEventBo(spanEvent.getSpan(), spanEvent)); + SpanEventBo spanEventBo = spanFactory.buildSpanEventBo(spanEvent.getSpan(), spanEvent); + spanEvents.add(spanEventBo); } } return spanEvents; @@ -61,7 +64,8 @@ protected List getCurrentRootSpans() { List rootSpans = new ArrayList(); for (TBase span : this.tBaseRecorder) { if (span instanceof Span) { - rootSpans.add(new SpanBo((Span)span)); + SpanBo spanBo = spanFactory.buildSpanBo((Span) span); + rootSpans.add(spanBo); } } return rootSpans; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java index 95df97625238..b76a57edbce0 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/calltree/span/SpanAlign.java @@ -176,10 +176,7 @@ public String getTransactionId() { } public long getSpanId() { - if (isSpan()) { - return spanBo.getSpanId(); - } - return spanEventBo.getSpanId(); + return spanBo.getSpanId(); } public boolean hasException() { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java index 18d105878189..011fdf2ed29b 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/HbaseApplicationTraceIndexDao.java @@ -25,7 +25,7 @@ import com.navercorp.pinpoint.common.hbase.RowMapper; import com.navercorp.pinpoint.common.util.BytesUtils; import com.navercorp.pinpoint.common.util.DateUtils; -import com.navercorp.pinpoint.common.util.SpanUtils; +import com.navercorp.pinpoint.common.server.util.SpanUtils; import com.navercorp.pinpoint.common.util.TimeUtils; import com.navercorp.pinpoint.rpc.util.ListUtils; import com.navercorp.pinpoint.web.dao.ApplicationTraceIndexDao; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java index 635770eea8c8..bde8a6ab7bb6 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java @@ -16,6 +16,8 @@ package com.navercorp.pinpoint.web.mapper; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Lists; import com.navercorp.pinpoint.common.buffer.Buffer; import com.navercorp.pinpoint.common.buffer.OffsetFixedBuffer; import com.navercorp.pinpoint.common.server.bo.AnnotationBo; @@ -67,7 +69,7 @@ public List mapRow(Result result, int rowNum) throws Exception { final Cell[] rawCells = result.rawCells(); List spanList = new ArrayList<>(); Map spanMap = new HashMap<>(); - List spanEventBoList = new ArrayList<>(); + LinkedHashMultimap spanEventBoListMap = LinkedHashMultimap.create(); for (Cell cell : rawCells) { // only if family name is "span" if (CellUtil.matchingFamily(cell, HBaseTables.TRACES_CF_SPAN)) { @@ -93,7 +95,7 @@ public List mapRow(Result result, int rowNum) throws Exception { // qualifier : spanId(long) + sequence(short) + asyncId(int) final Buffer qualifier = new OffsetFixedBuffer(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); - long spanId = qualifier.readLong(); + Long spanId = qualifier.readLong(); short sequence = qualifier.readShort(); int asyncId = -1; @@ -104,7 +106,6 @@ public List mapRow(Result result, int rowNum) throws Exception { if (qualifier.hasRemaining()) { asyncSequence = qualifier.readShort(); } - spanEventBo.setSpanId(spanId); spanEventBo.setSequence(sequence); spanEventBo.setAsyncId(asyncId); spanEventBo.setAsyncSequence(asyncSequence); @@ -113,17 +114,17 @@ public List mapRow(Result result, int rowNum) throws Exception { if (logger.isDebugEnabled()) { logger.debug("read spanEvent :{}", spanEventBo); } - spanEventBoList.add(spanEventBo); + spanEventBoListMap.put(spanId, spanEventBo); } } - for (SpanEventBo spanEventBo : spanEventBoList) { - final Long spanId = spanEventBo.getSpanId(); + for (Map.Entry spanBoEntry : spanEventBoListMap.entries()) { + final Long spanId = spanBoEntry.getKey(); SpanBo spanBo = spanMap.get(spanId); if (spanBo != null) { - spanBo.addSpanEvent(spanEventBo); + spanBo.addSpanEventBoList(Lists.newArrayList(spanBoEntry.getValue())); } else { if (logger.isInfoEnabled()) { - logger.info("Span not exist spanId:{} spanEvent:{}", spanEventBo); + logger.info("Span not exist spanId:{} spanEvent:{}", spanBoEntry.getKey(), spanBoEntry.getValue()); } } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapperV2.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapperV2.java index af96660cf2e6..1a353910e558 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapperV2.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapperV2.java @@ -30,10 +30,8 @@ import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanDecoder; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanDecoderV0; import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanDecodingContext; -import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanEncoder; import com.navercorp.pinpoint.common.util.BytesUtils; import com.navercorp.pinpoint.common.util.TransactionId; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; @@ -156,19 +154,11 @@ private List buildSpanBoList(List out) { return spanBoList; } - private void sortSpanEvent(List spanEventBoList) { - if (CollectionUtils.isEmpty(spanEventBoList)) { - return; - } - Collections.sort(spanEventBoList, SpanEncoder.SPAN_EVENT_SEQUENCE_COMPARATOR); - } private void bindAgentInfo(List spanBoList) { // TODO workaround. fix class dependency for (SpanBo spanBo : spanBoList) { - List spanEventBoList = spanBo.getSpanEventBoList(); - sortSpanEvent(spanEventBoList); for (SpanEventBo spanEventBo : spanEventBoList) { spanEventBo.setAgentId(spanBo.getAgentId()); spanEventBo.setApplicationId(spanBo.getApplicationId()); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java index 9f9a237dfae0..1b5666daae0a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java @@ -21,7 +21,7 @@ import java.util.Objects; import com.navercorp.pinpoint.common.server.bo.AnnotationBo; -import com.navercorp.pinpoint.common.server.bo.Span; +import com.navercorp.pinpoint.common.server.bo.Event; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.SpanEventBo; import com.navercorp.pinpoint.common.service.AnnotationKeyRegistryService; @@ -282,22 +282,22 @@ private String getRpcArgument(SpanBo spanBo) { return getDisplayArgument(spanBo); } - private String getDisplayArgument(Span span) { - AnnotationBo displayArgument = getDisplayArgument0(span); + private String getDisplayArgument(Event event) { + AnnotationBo displayArgument = getDisplayArgument0(event); if (displayArgument == null) { return ""; } return Objects.toString(displayArgument.getValue(), ""); } - private AnnotationBo getDisplayArgument0(Span span) { + private AnnotationBo getDisplayArgument0(Event event) { // TODO needs a more generalized implementation for Arcus - List list = span.getAnnotationBoList(); + List list = event.getAnnotationBoList(); if (list == null) { return null; } - final AnnotationKeyMatcher matcher = annotationKeyMatcherService.findAnnotationKeyMatcher(span.getServiceType()); + final AnnotationKeyMatcher matcher = annotationKeyMatcherService.findAnnotationKeyMatcher(event.getServiceType()); if (matcher == null) { return null; }