mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-09 04:46:06 +10:00
committed by
HyunGil Jeong
parent
586542ccf8
commit
69fbc4853c
@@ -0,0 +1,13 @@
|
||||
package com.navercorp.pinpoint.collector.dao;
|
||||
|
||||
import com.navercorp.pinpoint.thrift.dto.TSpan;
|
||||
import com.navercorp.pinpoint.thrift.dto.TSpanChunk;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public interface TraceDao {
|
||||
void insert(TSpan span);
|
||||
|
||||
void insertSpanChunk(TSpanChunk spanChunk);
|
||||
}
|
||||
@@ -22,8 +22,7 @@ import com.navercorp.pinpoint.thrift.dto.TSpanChunk;
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public interface TracesDao {
|
||||
void insert(TSpan span);
|
||||
@Deprecated
|
||||
public interface TracesDao extends TraceDao {
|
||||
|
||||
void insertSpanChunk(TSpanChunk spanChunk);
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* usage for development env
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class DualWriteHbaseTraceDao implements TraceDao {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final TraceDao master;
|
||||
private final TraceDao slave;
|
||||
|
||||
public DualWriteHbaseTraceDao(TraceDao master, TraceDao slave) {
|
||||
if (master == null) {
|
||||
throw new NullPointerException("master must not be null");
|
||||
}
|
||||
if (slave == null) {
|
||||
throw new NullPointerException("slave must not be null");
|
||||
}
|
||||
this.master = master;
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(TSpan span) {
|
||||
Throwable masterException = null;
|
||||
try {
|
||||
master.insert(span);
|
||||
} catch (Throwable e) {
|
||||
masterException = e;
|
||||
}
|
||||
try {
|
||||
slave.insert(span);
|
||||
} catch (Throwable e) {
|
||||
logger.warn("slave insert(TSpan) Error:{}", e.getMessage(), e);
|
||||
}
|
||||
rethrowRuntimeException(masterException);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertSpanChunk(TSpanChunk spanChunk) {
|
||||
Throwable masterException = null;
|
||||
try {
|
||||
master.insertSpanChunk(spanChunk);
|
||||
} catch (Throwable e) {
|
||||
masterException = e;
|
||||
}
|
||||
try {
|
||||
slave.insertSpanChunk(spanChunk);
|
||||
} catch (Throwable e) {
|
||||
logger.warn("slave insertSpanChunk(TSpanChunk) Error:{}", e.getMessage(), e);
|
||||
}
|
||||
rethrowRuntimeException(masterException);
|
||||
}
|
||||
|
||||
private void rethrowRuntimeException(Throwable exception) {
|
||||
if (exception != null) {
|
||||
this.<RuntimeException>rethrowException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Exception> void rethrowException(final Throwable exception) throws T {
|
||||
throw (T) exception;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -18,9 +18,9 @@ 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.serializer.AnnotationSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.SpanEventSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.SpanSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.AnnotationSerializer;
|
||||
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;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanEventBo;
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.navercorp.pinpoint.collector.dao.hbase;
|
||||
|
||||
import com.navercorp.pinpoint.collector.dao.TraceDao;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Repository
|
||||
public class HbaseTraceDaoFactory implements FactoryBean<TraceDao> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDao")
|
||||
private TraceDao v1;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoV2")
|
||||
private TraceDao v2;
|
||||
|
||||
@Value("#{pinpoint_collector_properties['collector.experimental.span.format.compatibility.version'] ?: 'v1'}")
|
||||
private String mode = "v1";
|
||||
|
||||
@Override
|
||||
public TraceDao getObject() throws Exception {
|
||||
|
||||
logger.info("TraceDao Compatibility {}", mode);
|
||||
|
||||
if (mode.equalsIgnoreCase("v1")) {
|
||||
return v1;
|
||||
}
|
||||
else if (mode.equalsIgnoreCase("v2")) {
|
||||
return v2;
|
||||
}
|
||||
else if(mode.equalsIgnoreCase("dualWrite")) {
|
||||
return new DualWriteHbaseTraceDao(v1, v2);
|
||||
}
|
||||
|
||||
return v1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return TraceDao.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
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.sematext.hbase.wd.AbstractRowKeyDistributor;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.hadoop.hbase.client.Put;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Repository
|
||||
public class HbaseTraceDaoV2 implements TraceDao {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private HbaseOperations2 hbaseTemplate;
|
||||
|
||||
@Autowired
|
||||
private AcceptedTimeService acceptedTimeService;
|
||||
|
||||
@Autowired
|
||||
private SpanEventFilter spanEventFilter;
|
||||
|
||||
@Autowired
|
||||
private SpanSerializerV2 spanSerializer;
|
||||
|
||||
@Autowired
|
||||
private SpanChunkSerializerV2 spanChunkSerializer;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("traceV2Distributor")
|
||||
private AbstractRowKeyDistributor rowKeyDistributor;
|
||||
|
||||
|
||||
@Override
|
||||
public void insert(final TSpan span) {
|
||||
if (span == null) {
|
||||
throw new NullPointerException("span must not be null");
|
||||
}
|
||||
|
||||
final SpanBo spanBo = new SpanBo(span);
|
||||
List<SpanEventBo> spanEventBoList = buildSpanEventList(span);
|
||||
spanBo.addSpanEventBoList(spanEventBoList);
|
||||
|
||||
long acceptedTime = acceptedTimeService.getAcceptedTime();
|
||||
spanBo.setCollectorAcceptTime(acceptedTime);
|
||||
|
||||
final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(span));
|
||||
final Put put = new Put(rowKey, acceptedTime);
|
||||
|
||||
this.spanSerializer.serialize(spanBo, put, null);
|
||||
|
||||
|
||||
boolean success = hbaseTemplate.asyncPut(TRACE_V2, put);
|
||||
if (!success) {
|
||||
hbaseTemplate.put(TRACE_V2, put);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<SpanEventBo> buildSpanEventList(TSpan span) {
|
||||
final List<TSpanEvent> spanEventList = span.getSpanEventList();
|
||||
if (CollectionUtils.isEmpty(spanEventList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<SpanEventBo> 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<SpanEventBo> buildSpanEventBoList(TSpanChunk tSpanChunk) {
|
||||
List<TSpanEvent> spanEventList = tSpanChunk.getSpanEventList();
|
||||
if (CollectionUtils.isEmpty(spanEventList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<SpanEventBo> 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);
|
||||
return distributedKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void insertSpanChunk(TSpanChunk spanChunk) {
|
||||
SpanChunkBo spanChunkBo = buildSpanChunkBo(spanChunk);
|
||||
|
||||
final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunk));
|
||||
final long acceptedTime = acceptedTimeService.getAcceptedTime();
|
||||
final Put put = new Put(rowKey, acceptedTime);
|
||||
|
||||
final List<TSpanEvent> spanEventBoList = spanChunk.getSpanEventList();
|
||||
if (CollectionUtils.isEmpty(spanEventBoList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.spanChunkSerializer.serialize(spanChunkBo, put, null);
|
||||
|
||||
if (!put.isEmpty()) {
|
||||
boolean success = hbaseTemplate.asyncPut(TRACE_V2, put);
|
||||
if (!success) {
|
||||
hbaseTemplate.put(TRACE_V2, put);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<SpanEventBo> spanEventBoList = buildSpanEventBoList(tSpanChunk);
|
||||
spanChunkBo.addSpanEventBoList(spanEventBoList);
|
||||
return spanChunkBo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+7
-3
@@ -18,6 +18,7 @@ package com.navercorp.pinpoint.collector.handler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.navercorp.pinpoint.collector.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService;
|
||||
import com.navercorp.pinpoint.common.trace.ServiceType;
|
||||
|
||||
@@ -26,11 +27,11 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.navercorp.pinpoint.collector.dao.TracesDao;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,8 @@ public class SpanChunkHandler implements SimpleHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private TracesDao traceDao;
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Autowired
|
||||
private StatisticsHandler statisticsHandler;
|
||||
@@ -69,7 +71,9 @@ public class SpanChunkHandler implements SimpleHandler {
|
||||
final ServiceType applicationServiceType = getApplicationServiceType(spanChunk);
|
||||
List<TSpanEvent> spanEventList = spanChunk.getSpanEventList();
|
||||
if (spanEventList != null) {
|
||||
logger.debug("SpanChunk Size:{}", spanEventList.size());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SpanChunk Size:{}", spanEventList.size());
|
||||
}
|
||||
// TODO need to batch update later.
|
||||
for (TSpanEvent spanEvent : spanEventList) {
|
||||
final ServiceType spanEventType = registry.findServiceType(spanEvent.getServiceType());
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.navercorp.pinpoint.collector.handler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.navercorp.pinpoint.collector.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService;
|
||||
import com.navercorp.pinpoint.common.trace.ServiceType;
|
||||
|
||||
@@ -29,11 +30,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.navercorp.pinpoint.collector.dao.ApplicationTraceIndexDao;
|
||||
import com.navercorp.pinpoint.collector.dao.HostApplicationMapDao;
|
||||
import com.navercorp.pinpoint.collector.dao.TracesDao;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -46,7 +47,8 @@ public class SpanHandler implements SimpleHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private TracesDao traceDao;
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Autowired
|
||||
private ApplicationTraceIndexDao applicationTraceIndexDao;
|
||||
|
||||
@@ -85,6 +85,18 @@
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="traceV2Distributor" class="com.sematext.hbase.wd.RowKeyDistributorByHashPrefix">
|
||||
<constructor-arg ref="traceV2Hasher"/>
|
||||
</bean>
|
||||
|
||||
<bean id="traceV2Hasher" class="com.navercorp.pinpoint.common.hbase.distributor.RangeOneByteSimpleHash">
|
||||
<constructor-arg type="int" value="32"/>
|
||||
<constructor-arg type="int" value="40"/>
|
||||
<constructor-arg type="int" value="256"/>
|
||||
</bean>
|
||||
|
||||
|
||||
|
||||
<bean id="agentStatRowKeyDistributor" class="com.sematext.hbase.wd.RowKeyDistributorByHashPrefix">
|
||||
<constructor-arg ref="agentStatRangeHasher"/>
|
||||
</bean>
|
||||
|
||||
@@ -73,3 +73,7 @@ cluster.listen.port=
|
||||
#collector.admin.api.jmx.active=
|
||||
|
||||
collector.spanEvent.sequence.limit=10000
|
||||
|
||||
# span.binary format compatibility = v1 or v2 (WARNING : experimental feature)
|
||||
# experimental feature span format v2 : https://github.com/naver/pinpoint/issues/1819
|
||||
collector.experimental.span.format.compatibility.version=v1
|
||||
@@ -59,10 +59,17 @@ public final class HBaseTables {
|
||||
public static final byte[] AGENT_STAT_COL_ACTIVE_TRACE_HISTOGRAM = Bytes.toBytes("aH"); // qualifier for active trace histogram
|
||||
public static final int AGENT_STAT_ROW_DISTRIBUTE_SIZE = 1; // agent statistics hash size
|
||||
|
||||
@Deprecated
|
||||
public static final TableName TRACES = TableName.valueOf("Traces");
|
||||
@Deprecated
|
||||
public static final byte[] TRACES_CF_SPAN = Bytes.toBytes("S"); //Span
|
||||
@Deprecated
|
||||
public static final byte[] TRACES_CF_ANNOTATION = Bytes.toBytes("A"); //Annotation
|
||||
public static final byte[] TRACES_CF_TERMINALSPAN = Bytes.toBytes("T"); //TerminalSpan
|
||||
@Deprecated
|
||||
public static final byte[] TRACES_CF_TERMINALSPAN = Bytes.toBytes("T"); //SpanEvent
|
||||
|
||||
public static final TableName TRACE_V2 = TableName.valueOf("TraceV2");
|
||||
public static final byte[] TRACE_V2_CF_SPAN = Bytes.toBytes("S"); //Span
|
||||
|
||||
public static final TableName APPLICATION_INDEX = TableName.valueOf("ApplicationIndex");
|
||||
public static final byte[] APPLICATION_INDEX_CF_AGENTS = Bytes.toBytes("Agents");
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<properties>
|
||||
<jdk.version>1.7</jdk.version>
|
||||
<jdk.home>${env.JAVA_7_HOME}</jdk.home>
|
||||
<sniffer.artifactid>java17</sniffer.artifactid>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
+3
-14
@@ -52,10 +52,12 @@ public class AnnotationBo {
|
||||
this.byteValue = transcoder.encode(value, this.valueType);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long getSpanId() {
|
||||
return spanId;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSpanId(long spanId) {
|
||||
this.spanId = spanId;
|
||||
}
|
||||
@@ -136,20 +138,7 @@ public class AnnotationBo {
|
||||
buffer.putPrefixedBytes(this.byteValue);
|
||||
}
|
||||
|
||||
// public int getBufferSize() {
|
||||
// // int key; // required 4+string.length
|
||||
// // int valueTypeCode; // required 4
|
||||
// // ByteBuffer value; // optional 4 + buf.length
|
||||
// int size = 0;
|
||||
// size += 1 + 4 + 4 + 4;
|
||||
// size += 4;
|
||||
// if (this.getByteValue() != null) {
|
||||
// size += this.getByteValue().length;
|
||||
// }
|
||||
// return size;
|
||||
// }
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void readValue(Buffer buffer) {
|
||||
this.version = buffer.readByte();
|
||||
this.key = buffer.readSVInt();
|
||||
|
||||
@@ -58,11 +58,11 @@ public class SpanBo implements Span {
|
||||
private String endPoint;
|
||||
private int apiId;
|
||||
|
||||
private List<AnnotationBo> annotationBoList;
|
||||
private List<AnnotationBo> annotationBoList = new ArrayList<>();
|
||||
private short flag; // optional
|
||||
private int errCode;
|
||||
|
||||
private List<SpanEventBo> spanEventBoList;
|
||||
private List<SpanEventBo> spanEventBoList = new ArrayList<>();
|
||||
|
||||
private long collectorAcceptTime;
|
||||
|
||||
@@ -251,7 +251,12 @@ public class SpanBo implements Span {
|
||||
return spanId;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSpanID(long spanId) {
|
||||
this.setSpanId(spanId);
|
||||
}
|
||||
|
||||
public void setSpanId(long spanId) {
|
||||
this.spanId = spanId;
|
||||
}
|
||||
|
||||
@@ -310,9 +315,17 @@ public class SpanBo implements Span {
|
||||
this.annotationBoList = anoList;
|
||||
}
|
||||
|
||||
public void addSpanEvent(SpanEventBo spanEventBo) {
|
||||
public void addSpanEventBoList(List<SpanEventBo> spanEventBoList) {
|
||||
if (spanEventBoList == null) {
|
||||
spanEventBoList = new ArrayList<>();
|
||||
return;
|
||||
}
|
||||
this.spanEventBoList.addAll(spanEventBoList);
|
||||
}
|
||||
|
||||
|
||||
public void addSpanEvent(SpanEventBo spanEventBo) {
|
||||
if (spanEventBo == null) {
|
||||
return;
|
||||
}
|
||||
spanEventBoList.add(spanEventBo);
|
||||
}
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
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 {
|
||||
|
||||
private byte version = 0;
|
||||
|
||||
private String agentId;
|
||||
private String applicationId;
|
||||
private long agentStartTime;
|
||||
|
||||
private String traceAgentId;
|
||||
private long traceAgentStartTime;
|
||||
private long traceTransactionSequence;
|
||||
|
||||
private long spanId;
|
||||
|
||||
private List<SpanEventBo> spanEventBoList = new ArrayList<>();
|
||||
private long collectorAcceptTime;
|
||||
|
||||
public SpanChunkBo() {
|
||||
}
|
||||
|
||||
public byte getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(byte version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public void setAgentId(String agentId) {
|
||||
this.agentId = agentId;
|
||||
}
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public long getAgentStartTime() {
|
||||
return agentStartTime;
|
||||
}
|
||||
|
||||
public void setAgentStartTime(long agentStartTime) {
|
||||
this.agentStartTime = agentStartTime;
|
||||
}
|
||||
|
||||
public String getTraceAgentId() {
|
||||
return traceAgentId;
|
||||
}
|
||||
|
||||
public void setTraceAgentId(String traceAgentId) {
|
||||
this.traceAgentId = traceAgentId;
|
||||
}
|
||||
|
||||
public long getTraceAgentStartTime() {
|
||||
return traceAgentStartTime;
|
||||
}
|
||||
|
||||
public void setTraceAgentStartTime(long traceAgentStartTime) {
|
||||
this.traceAgentStartTime = traceAgentStartTime;
|
||||
}
|
||||
|
||||
public long getTraceTransactionSequence() {
|
||||
return traceTransactionSequence;
|
||||
}
|
||||
|
||||
public void setTraceTransactionSequence(long traceTransactionSequence) {
|
||||
this.traceTransactionSequence = traceTransactionSequence;
|
||||
}
|
||||
|
||||
public long getSpanId() {
|
||||
return spanId;
|
||||
}
|
||||
|
||||
public void setSpanId(long spanId) {
|
||||
this.spanId = spanId;
|
||||
}
|
||||
|
||||
public long getCollectorAcceptTime() {
|
||||
return collectorAcceptTime;
|
||||
}
|
||||
|
||||
public void setCollectorAcceptTime(long collectorAcceptTime) {
|
||||
this.collectorAcceptTime = collectorAcceptTime;
|
||||
}
|
||||
|
||||
public List<SpanEventBo> getSpanEventBoList() {
|
||||
return spanEventBoList;
|
||||
}
|
||||
|
||||
public void addSpanEventBoList(List<SpanEventBo> spanEventBoList) {
|
||||
if (spanEventBoList == null) {
|
||||
return;
|
||||
}
|
||||
this.spanEventBoList.addAll(spanEventBoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SpanChunkBo{" +
|
||||
"version=" + version +
|
||||
", agentId='" + agentId + '\'' +
|
||||
", applicationId='" + applicationId + '\'' +
|
||||
", agentStartTime=" + agentStartTime +
|
||||
", traceAgentId='" + traceAgentId + '\'' +
|
||||
", traceAgentStartTime=" + traceAgentStartTime +
|
||||
", traceTransactionSequence=" + traceTransactionSequence +
|
||||
", spanId=" + spanId +
|
||||
", spanEventBoList=" + spanEventBoList +
|
||||
", collectorAcceptTime=" + collectorAcceptTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+15
-12
@@ -119,7 +119,7 @@ public class SpanEventBo implements Span {
|
||||
this.nextSpanId = tSpanEvent.getNextSpanId();
|
||||
}
|
||||
|
||||
setAnnotationList(tSpanEvent.getAnnotations());
|
||||
this.annotationBoList = buildAnnotationList(tSpanEvent.getAnnotations());
|
||||
|
||||
final TIntStringValue exceptionInfo = tSpanEvent.getExceptionInfo();
|
||||
if (exceptionInfo != null) {
|
||||
@@ -183,7 +183,7 @@ public class SpanEventBo implements Span {
|
||||
this.nextSpanId = spanEvent.getNextSpanId();
|
||||
}
|
||||
|
||||
setAnnotationList(spanEvent.getAnnotations());
|
||||
this.annotationBoList = buildAnnotationList(spanEvent.getAnnotations());
|
||||
|
||||
final TIntStringValue exceptionInfo = spanEvent.getExceptionInfo();
|
||||
if (exceptionInfo != null) {
|
||||
@@ -356,22 +356,23 @@ public class SpanEventBo implements Span {
|
||||
this.nextSpanId = nextSpanId;
|
||||
}
|
||||
|
||||
public void setAnnotationList(List<TAnnotation> annotations) {
|
||||
if (annotations == null) {
|
||||
return;
|
||||
private List<AnnotationBo> buildAnnotationList(List<TAnnotation> annotationList) {
|
||||
if (annotationList == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<AnnotationBo> boList = new ArrayList<AnnotationBo>(annotations.size());
|
||||
for (TAnnotation ano : annotations) {
|
||||
boList.add(new AnnotationBo(ano));
|
||||
List<AnnotationBo> boList = new ArrayList<AnnotationBo>(annotationList.size());
|
||||
for (TAnnotation annotation : annotationList) {
|
||||
AnnotationBo annotationBo = new AnnotationBo(annotation);
|
||||
boList.add(annotationBo);
|
||||
}
|
||||
this.annotationBoList = boList;
|
||||
return boList;
|
||||
}
|
||||
|
||||
public void setAnnotationBoList(List<AnnotationBo> anoList) {
|
||||
if (anoList == null) {
|
||||
public void setAnnotationBoList(List<AnnotationBo> annotationList) {
|
||||
if (annotationList == null) {
|
||||
return;
|
||||
}
|
||||
this.annotationBoList = anoList;
|
||||
this.annotationBoList = annotationList;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
@@ -574,6 +575,8 @@ public class SpanEventBo implements Span {
|
||||
builder.append(asyncId);
|
||||
builder.append(", nextAsyncId=");
|
||||
builder.append(nextAsyncId);
|
||||
builder.append(", asyncSequence=");
|
||||
builder.append(asyncSequence);
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,9 +1,11 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer;
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v1;
|
||||
|
||||
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
import com.navercorp.pinpoint.common.server.bo.AnnotationBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.HbaseSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.SerializationContext;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.hadoop.hbase.client.Put;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer;
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v1;
|
||||
|
||||
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
import com.navercorp.pinpoint.common.server.bo.AnnotationBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanEventBo;
|
||||
import com.navercorp.pinpoint.common.server.util.AcceptedTimeService;
|
||||
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;
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer;
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v1;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
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.apache.hadoop.hbase.util.Bytes;
|
||||
import org.springframework.stereotype.Component;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanChunkBo;
|
||||
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.stereotype.Component;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.navercorp.pinpoint.common.hbase.HBaseTables.TRACE_V2_CF_SPAN;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Component
|
||||
public class SpanChunkSerializerV2 implements HbaseSerializer<SpanChunkBo, Put> {
|
||||
|
||||
private final SpanEncoder spanEncoder = new SpanEncoder();
|
||||
|
||||
@Override
|
||||
public void serialize(SpanChunkBo spanChunkBo, Put put, SerializationContext context) {
|
||||
|
||||
SpanEncodingContext<SpanChunkBo> encodingContext = new SpanEncodingContext<>(spanChunkBo);
|
||||
|
||||
ByteBuffer qualifier = spanEncoder.encodeSpanChunkQualifier(encodingContext);
|
||||
ByteBuffer columnValue = spanEncoder.encodeSpanChunkColumnValue(encodingContext);
|
||||
|
||||
long acceptedTime = put.getTimeStamp();
|
||||
put.addColumn(TRACE_V2_CF_SPAN, qualifier, acceptedTime, columnValue);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+505
@@ -0,0 +1,505 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
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 com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanBitFiled;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanEventBitField;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanEventQualifierBitField;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.StartElapsedTimeEncodingStrategy;
|
||||
import com.navercorp.pinpoint.common.util.AnnotationTranscoder;
|
||||
import com.navercorp.pinpoint.common.util.TransactionId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanDecoder {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private static final AnnotationTranscoder transcoder = new AnnotationTranscoder();
|
||||
|
||||
public static final Object UNKNOWN = new Object();
|
||||
|
||||
public void decode(Buffer qualifier, Buffer columnValue, SpanDecodingContext decodingContext, List<Object> out) {
|
||||
final byte type = qualifier.readByte();
|
||||
|
||||
if (SpanEncoder.TYPE_SPAN == type) {
|
||||
|
||||
SpanBo span = readSpan(qualifier, columnValue, decodingContext);
|
||||
out.add(span);
|
||||
|
||||
} else if (SpanEncoder.TYPE_SPAN_CHUNK == type) {
|
||||
|
||||
SpanChunkBo spanChunk = readSpanChunk(qualifier, columnValue, decodingContext);
|
||||
out.add(spanChunk);
|
||||
|
||||
} else {
|
||||
logger.warn("Unknown span type {}", type);
|
||||
out.add(UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
private SpanChunkBo readSpanChunk(Buffer qualifier, Buffer columnValue, SpanDecodingContext decodingContext) {
|
||||
final SpanChunkBo spanChunk = new SpanChunkBo();
|
||||
|
||||
final TransactionId transactionId = decodingContext.getTransactionId();
|
||||
|
||||
spanChunk.setTraceAgentStartTime(transactionId.getAgentStartTime());
|
||||
spanChunk.setTraceTransactionSequence(transactionId.getTransactionSequence());
|
||||
spanChunk.setCollectorAcceptTime(decodingContext.getCollectorAcceptedTime());
|
||||
|
||||
|
||||
SpanAdaptor spanAdaptor = new SpanChunkBoAdaptor(spanChunk);
|
||||
SpanEventBo firstSpanEvent = readQualifier(spanAdaptor, qualifier);
|
||||
|
||||
readSpanChunkValue(columnValue, spanChunk, firstSpanEvent, decodingContext);
|
||||
|
||||
return spanChunk;
|
||||
}
|
||||
|
||||
|
||||
private SpanBo readSpan(Buffer qualifier, Buffer columnValue, SpanDecodingContext decodingContext) {
|
||||
final SpanBo span = new SpanBo();
|
||||
|
||||
final TransactionId transactionId = decodingContext.getTransactionId();
|
||||
span.setTraceAgentId(transactionId.getAgentId());
|
||||
span.setTraceAgentStartTime(transactionId.getAgentStartTime());
|
||||
span.setTraceTransactionSequence(transactionId.getTransactionSequence());
|
||||
span.setCollectorAcceptTime(decodingContext.getCollectorAcceptedTime());
|
||||
|
||||
SpanAdaptor spanAdaptor = new SpanBoAdaptor(span);
|
||||
SpanEventBo firstSpanEvent = readQualifier(spanAdaptor, qualifier);
|
||||
|
||||
readSpanValue(columnValue, span, firstSpanEvent, decodingContext);
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
private void readSpanChunkValue(Buffer buffer, SpanChunkBo spanChunk, SpanEventBo firstSpanEvent, SpanDecodingContext decodingContext) {
|
||||
final byte version = buffer.readByte();
|
||||
if (version != 0) {
|
||||
throw new IllegalStateException("unknown version :" + version);
|
||||
}
|
||||
spanChunk.setVersion(version);
|
||||
|
||||
List<SpanEventBo> spanEventBoList = readSpanEvent(buffer, firstSpanEvent, decodingContext);
|
||||
spanChunk.addSpanEventBoList(spanEventBoList);
|
||||
}
|
||||
|
||||
public void readSpanValue(Buffer buffer, SpanBo span, SpanEventBo firstSpanEvent, SpanDecodingContext decodingContext) {
|
||||
|
||||
final byte version = buffer.readByte();
|
||||
if (version != 0) {
|
||||
throw new IllegalStateException("unknown version :" + version);
|
||||
}
|
||||
span.setVersion(version);
|
||||
|
||||
final SpanBitFiled bitFiled = new SpanBitFiled(buffer.readByte());
|
||||
|
||||
final short serviceType = buffer.readShort();
|
||||
span.setServiceType(serviceType);
|
||||
|
||||
switch (bitFiled.getApplicationServiceTypeEncodingStrategy()) {
|
||||
case PREV_EQUALS:
|
||||
span.setApplicationServiceType(serviceType);
|
||||
break;
|
||||
case RAW:
|
||||
span.setApplicationServiceType(buffer.readShort());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("applicationServiceType");
|
||||
}
|
||||
|
||||
if (!bitFiled.isRoot()) {
|
||||
span.setParentSpanId(buffer.readLong());
|
||||
} else {
|
||||
span.setParentSpanId(-1);
|
||||
}
|
||||
|
||||
final int startTimeDelta = buffer.readVInt();
|
||||
final long startTime = startTimeDelta + span.getCollectorAcceptTime();
|
||||
span.setStartTime(startTime);
|
||||
span.setElapsed(buffer.readVInt());
|
||||
|
||||
span.setRpc(buffer.readPrefixedString());
|
||||
|
||||
span.setEndPoint(buffer.readPrefixedString());
|
||||
span.setRemoteAddr(buffer.readPrefixedString());
|
||||
span.setApiId(buffer.readSVInt());
|
||||
|
||||
if (bitFiled.isSetErrorCode()) {
|
||||
span.setErrCode(buffer.readInt());
|
||||
}
|
||||
if (bitFiled.isSetHasException()) {
|
||||
int exceptionId = buffer.readSVInt();
|
||||
String exceptionMessage = buffer.readPrefixedString();
|
||||
span.setExceptionInfo(exceptionId, exceptionMessage);
|
||||
}
|
||||
|
||||
if (bitFiled.isSetFlag()) {
|
||||
span.setFlag(buffer.readShort());
|
||||
}
|
||||
|
||||
if (bitFiled.isSetLoggingTransactionInfo()) {
|
||||
span.setLoggingTransactionInfo(buffer.readByte());
|
||||
}
|
||||
|
||||
span.setAcceptorHost(buffer.readPrefixedString());
|
||||
|
||||
|
||||
if (bitFiled.isSetAnnotation()) {
|
||||
List<AnnotationBo> annotationBoList = readAnnotationList(buffer, decodingContext);
|
||||
span.setAnnotationBoList(annotationBoList);
|
||||
}
|
||||
|
||||
List<SpanEventBo> spanEventBoList = readSpanEvent(buffer, firstSpanEvent, decodingContext);
|
||||
span.addSpanEventBoList(spanEventBoList);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<SpanEventBo> readSpanEvent(Buffer buffer, SpanEventBo firstSpanEvent, SpanDecodingContext decodingContext) {
|
||||
final int spanEventSize = buffer.readVInt();
|
||||
if (spanEventSize <= 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
final List<SpanEventBo> spanEventBoList = new ArrayList<>();
|
||||
SpanEventBo prev = null;
|
||||
for (int i = 0; i < spanEventSize; i++) {
|
||||
SpanEventBo spanEvent;
|
||||
if (i == 0) {
|
||||
spanEvent = readFirstSpanEvent(buffer, firstSpanEvent, decodingContext);
|
||||
} else {
|
||||
spanEvent = readNextSpanEvent(buffer, prev, decodingContext);
|
||||
}
|
||||
prev = spanEvent;
|
||||
spanEventBoList.add(spanEvent);
|
||||
}
|
||||
|
||||
return spanEventBoList;
|
||||
}
|
||||
|
||||
private SpanEventBo readNextSpanEvent(final Buffer buffer, final SpanEventBo prev, SpanDecodingContext decodingContext) {
|
||||
final SpanEventBo spanEventBo = new SpanEventBo();
|
||||
|
||||
final SpanEventBitField bitField = new SpanEventBitField(buffer.readShort());
|
||||
|
||||
switch (bitField.getStartElapsedEncodingStrategy()) {
|
||||
case PREV_DELTA:
|
||||
int startTimeDelta = buffer.readVInt();
|
||||
int startTime = startTimeDelta + prev.getStartElapsed();
|
||||
spanEventBo.setStartElapsed(startTime);
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
spanEventBo.setStartElapsed(prev.getStartElapsed());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported SequenceEncodingStrategy");
|
||||
}
|
||||
spanEventBo.setEndElapsed(buffer.readVInt());
|
||||
|
||||
switch (bitField.getSequenceEncodingStrategy()) {
|
||||
case PREV_DELTA:
|
||||
int sequenceDelta = buffer.readVInt();
|
||||
final int sequence = sequenceDelta + prev.getSequence();
|
||||
spanEventBo.setSequence((short) sequence);
|
||||
break;
|
||||
case PREV_ADD1:
|
||||
spanEventBo.setSequence((short) (prev.getSequence() + 1));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported SequenceEncodingStrategy");
|
||||
}
|
||||
|
||||
switch (bitField.getDepthEncodingStrategy()) {
|
||||
case RAW:
|
||||
spanEventBo.setDepth(buffer.readSVInt());
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
spanEventBo.setDepth(prev.getDepth());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported DepthEncodingStrategy");
|
||||
}
|
||||
|
||||
switch (bitField.getServiceTypeEncodingStrategy()) {
|
||||
case RAW:
|
||||
spanEventBo.setServiceType(buffer.readShort());
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
spanEventBo.setServiceType(prev.getServiceType());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported ServiceTypeEncodingStrategy");
|
||||
}
|
||||
|
||||
|
||||
spanEventBo.setApiId(buffer.readSVInt());
|
||||
|
||||
if (bitField.isSetRpc()) {
|
||||
spanEventBo.setRpc(buffer.readPrefixedString());
|
||||
}
|
||||
|
||||
if (bitField.isSetEndPoint()) {
|
||||
spanEventBo.setEndPoint(buffer.readPrefixedString());
|
||||
}
|
||||
if (bitField.isSetDestinationId()) {
|
||||
spanEventBo.setDestinationId(buffer.readPrefixedString());
|
||||
}
|
||||
|
||||
if (bitField.isSetNextSpanId()) {
|
||||
spanEventBo.setNextSpanId(buffer.readLong());
|
||||
}
|
||||
|
||||
|
||||
if (bitField.isSetHasException()) {
|
||||
int exceptionId = buffer.readSVInt();
|
||||
String exceptionMessage = buffer.readPrefixedString();
|
||||
spanEventBo.setExceptionInfo(exceptionId, exceptionMessage);
|
||||
}
|
||||
|
||||
if (bitField.isSetAnnotation()) {
|
||||
List<AnnotationBo> annotationBoList = readAnnotationList(buffer, decodingContext);
|
||||
spanEventBo.setAnnotationBoList(annotationBoList);
|
||||
}
|
||||
|
||||
if (bitField.isSetNextAsyncId()) {
|
||||
spanEventBo.setNextAsyncId(buffer.readSVInt());
|
||||
}
|
||||
|
||||
if (bitField.isSetAsyncId()) {
|
||||
spanEventBo.setAsyncId(buffer.readInt());
|
||||
spanEventBo.setAsyncSequence((short) buffer.readVInt());
|
||||
}
|
||||
|
||||
return spanEventBo;
|
||||
}
|
||||
|
||||
private SpanEventBo readFirstSpanEvent(Buffer buffer, SpanEventBo firstSpanEvent, SpanDecodingContext decodingContext) {
|
||||
SpanEventBitField bitField = new SpanEventBitField(buffer.readByte());
|
||||
|
||||
firstSpanEvent.setStartElapsed(buffer.readVInt());
|
||||
firstSpanEvent.setEndElapsed(buffer.readVInt());
|
||||
|
||||
firstSpanEvent.setSequence(buffer.readShort());
|
||||
firstSpanEvent.setDepth(buffer.readSVInt());
|
||||
firstSpanEvent.setServiceType(buffer.readShort());
|
||||
|
||||
if (bitField.isSetRpc()) {
|
||||
firstSpanEvent.setRpc(buffer.readPrefixedString());
|
||||
}
|
||||
|
||||
if (bitField.isSetEndPoint()) {
|
||||
firstSpanEvent.setEndPoint(buffer.readPrefixedString());
|
||||
}
|
||||
if (bitField.isSetDestinationId()) {
|
||||
firstSpanEvent.setDestinationId(buffer.readPrefixedString());
|
||||
}
|
||||
|
||||
firstSpanEvent.setApiId(buffer.readSVInt());
|
||||
|
||||
if (bitField.isSetNextSpanId()) {
|
||||
firstSpanEvent.setNextSpanId(buffer.readLong());
|
||||
}
|
||||
|
||||
if (bitField.isSetHasException()) {
|
||||
int exceptionId = buffer.readSVInt();
|
||||
String exceptionMessage = buffer.readPrefixedString();
|
||||
firstSpanEvent.setExceptionInfo(exceptionId, exceptionMessage);
|
||||
}
|
||||
|
||||
if (bitField.isSetAnnotation()) {
|
||||
List<AnnotationBo> annotationBoList = readAnnotationList(buffer, decodingContext);
|
||||
firstSpanEvent.setAnnotationBoList(annotationBoList);
|
||||
}
|
||||
|
||||
if (bitField.isSetNextAsyncId()) {
|
||||
firstSpanEvent.setNextAsyncId(buffer.readSVInt());
|
||||
}
|
||||
|
||||
// if (bitField.isSetAsyncId()) {
|
||||
// firstSpanEvent.setAsyncId(buffer.readInt());
|
||||
// firstSpanEvent.setAsyncSequence((short) buffer.readVInt());
|
||||
// }
|
||||
return firstSpanEvent;
|
||||
}
|
||||
|
||||
private List<AnnotationBo> readAnnotationList(Buffer buffer, SpanDecodingContext decodingContext) {
|
||||
int annotationListSize = buffer.readVInt();
|
||||
List<AnnotationBo> annotationBoList = new ArrayList<>(annotationListSize);
|
||||
|
||||
// AnnotationBo prev = decodingContext.getPrevFirstAnnotationBo();
|
||||
AnnotationBo prev = null;
|
||||
for (int i = 0; i < annotationListSize; i++) {
|
||||
AnnotationBo current;
|
||||
if (i == 0) {
|
||||
current = readFirstAnnotationBo(buffer);
|
||||
// save first annotation for delta bitfield
|
||||
// decodingContext.setPrevFirstAnnotationBo(current);
|
||||
} else {
|
||||
current = readDeltaAnnotationBo(buffer, prev);
|
||||
}
|
||||
|
||||
prev = current;
|
||||
annotationBoList.add(current);
|
||||
}
|
||||
return annotationBoList;
|
||||
}
|
||||
|
||||
private AnnotationBo readFirstAnnotationBo(Buffer buffer) {
|
||||
AnnotationBo current;
|
||||
current = new AnnotationBo();
|
||||
current.setKey(buffer.readSVInt());
|
||||
|
||||
byte valueType = buffer.readByte();
|
||||
byte[] valueBytes = buffer.readPrefixedBytes();
|
||||
Object value = transcoder.decode(valueType, valueBytes);
|
||||
|
||||
current.setValueType(valueType);
|
||||
current.setValue(value);
|
||||
return current;
|
||||
}
|
||||
|
||||
private AnnotationBo readDeltaAnnotationBo(Buffer buffer, AnnotationBo prev) {
|
||||
AnnotationBo annotation = new AnnotationBo();
|
||||
|
||||
final int prevKey = prev.getKey();
|
||||
|
||||
annotation.setKey(buffer.readSVInt() + prevKey);
|
||||
|
||||
byte valueType = buffer.readByte();
|
||||
byte[] valueBytes = buffer.readPrefixedBytes();
|
||||
Object value = transcoder.decode(valueType, valueBytes);
|
||||
annotation.setValueType(valueType);
|
||||
annotation.setValue(value);
|
||||
return annotation;
|
||||
}
|
||||
|
||||
|
||||
private SpanEventBo readQualifier(SpanAdaptor span, Buffer buffer) {
|
||||
String applicationId = buffer.readPrefixedString();
|
||||
span.setApplicationId(applicationId);
|
||||
|
||||
String agentId = buffer.readPrefixedString();
|
||||
span.setAgentId(agentId);
|
||||
|
||||
long agentStartTime = buffer.readVLong();
|
||||
span.setAgentStartTime(agentStartTime);
|
||||
|
||||
long spanId = buffer.readLong();
|
||||
span.setSpanId(spanId);
|
||||
|
||||
int firstSpanEventSequence = buffer.readSVInt();
|
||||
if (firstSpanEventSequence == -1) {
|
||||
// buffer.readByte();
|
||||
// spanEvent not exist ??
|
||||
logger.info("firstSpanEvent is null. bug!!!!");
|
||||
return null;
|
||||
} else {
|
||||
return readQualifierFirstSpanEvent(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private SpanEventBo readQualifierFirstSpanEvent(Buffer buffer) {
|
||||
final SpanEventBo firstSpanEvent = new SpanEventBo();
|
||||
|
||||
final byte bitField = buffer.readByte();
|
||||
if (SpanEventQualifierBitField.isSetAsync(bitField)) {
|
||||
int asyncId = buffer.readInt();
|
||||
int asyncSequence = buffer.readVInt();
|
||||
firstSpanEvent.setAsyncId(asyncId);
|
||||
firstSpanEvent.setAsyncSequence((short) asyncSequence);
|
||||
}
|
||||
return firstSpanEvent;
|
||||
}
|
||||
|
||||
public void next(SpanDecodingContext decodingContext) {
|
||||
decodingContext.next();
|
||||
}
|
||||
|
||||
public void finish(SpanDecodingContext decodingContext) {
|
||||
decodingContext.finish();
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.util.TransactionId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanDecodingContext {
|
||||
|
||||
// private AnnotationBo prevAnnotationBo;
|
||||
private long collectorAcceptedTime;
|
||||
private TransactionId transactionId;
|
||||
|
||||
// public AnnotationBo getPrevFirstAnnotationBo() {
|
||||
// return prevAnnotationBo;
|
||||
// }
|
||||
//
|
||||
// public void setPrevFirstAnnotationBo(AnnotationBo prevAnnotationBo) {
|
||||
// this.prevAnnotationBo = prevAnnotationBo;
|
||||
// }
|
||||
|
||||
|
||||
public void setCollectorAcceptedTime(long collectorAcceptedTime) {
|
||||
this.collectorAcceptedTime = collectorAcceptedTime;
|
||||
}
|
||||
|
||||
public long getCollectorAcceptedTime() {
|
||||
return collectorAcceptedTime;
|
||||
}
|
||||
|
||||
public void setTransactionId(TransactionId transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public TransactionId getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
|
||||
public void next() {
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
}
|
||||
}
|
||||
+428
@@ -0,0 +1,428 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
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 com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanBitFiled;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanEventBitField;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanEventQualifierBitField;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanEncoder {
|
||||
|
||||
public static final Comparator<SpanEventBo> SPAN_EVENT_SEQUENCE_COMPARATOR = new Comparator<SpanEventBo>() {
|
||||
@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) {
|
||||
if (asyncId1 == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (asyncId2 == -1) {
|
||||
return -1;
|
||||
}
|
||||
return asyncIdCompare;
|
||||
}
|
||||
return Integer.compare(o1.getAsyncSequence(), o2.getAsyncSequence());
|
||||
}
|
||||
};
|
||||
|
||||
public static final Comparator<AnnotationBo> ANNOTATION_COMPARATOR = new Comparator<AnnotationBo>() {
|
||||
@Override
|
||||
public int compare(AnnotationBo o1, AnnotationBo o2) {
|
||||
return Integer.compare(o1.getKey(), o2.getKey());
|
||||
}
|
||||
};
|
||||
public static byte TYPE_SPAN = 0;
|
||||
public static byte TYPE_SPAN_CHUNK = 1;
|
||||
|
||||
// reserved
|
||||
public static byte TYPE_INDEX = 2;
|
||||
|
||||
|
||||
public ByteBuffer encodeSpanQualifier(SpanEncodingContext<SpanBo> encodingCtx) {
|
||||
final SpanBo spanBo = encodingCtx.getValue();
|
||||
final List<SpanEventBo> spanEventBoList = spanBo.getSpanEventBoList();
|
||||
final SpanEventBo firstEvent = getFirstSpanEvent(spanEventBoList);
|
||||
|
||||
return encodeQualifier(TYPE_SPAN, spanBo.getApplicationId(), spanBo.getAgentId(), spanBo.getAgentStartTime(), spanBo.getSpanId(), firstEvent);
|
||||
}
|
||||
|
||||
public ByteBuffer encodeSpanChunkQualifier(SpanEncodingContext<SpanChunkBo> encodingCtx) {
|
||||
final SpanChunkBo spanChunkBo = encodingCtx.getValue();
|
||||
|
||||
final List<SpanEventBo> spanEventBoList = spanChunkBo.getSpanEventBoList();
|
||||
final SpanEventBo firstEvent = getFirstSpanEvent(spanEventBoList);
|
||||
|
||||
return encodeQualifier(TYPE_SPAN_CHUNK, spanChunkBo.getApplicationId(), spanChunkBo.getAgentId(), spanChunkBo.getAgentStartTime(), spanChunkBo.getSpanId(), firstEvent);
|
||||
}
|
||||
|
||||
private ByteBuffer encodeQualifier(byte type, String applicationId, String agentId, long agentStartTime, long spanId, SpanEventBo firstEvent) {
|
||||
final Buffer buffer = new AutomaticBuffer(128);
|
||||
buffer.putByte(type);
|
||||
buffer.putPrefixedString(applicationId);
|
||||
buffer.putPrefixedString(agentId);
|
||||
buffer.putVLong(agentStartTime);
|
||||
buffer.putLong(spanId);
|
||||
|
||||
if (firstEvent != null) {
|
||||
buffer.putSVInt(firstEvent.getSequence());
|
||||
|
||||
final byte bitField = SpanEventQualifierBitField.buildBitField(firstEvent);
|
||||
buffer.putByte(bitField);
|
||||
// case : async span
|
||||
if (SpanEventQualifierBitField.isSetAsync(bitField)) {
|
||||
buffer.putInt(firstEvent.getAsyncId());
|
||||
buffer.putVInt(firstEvent.getAsyncSequence());
|
||||
}
|
||||
} else {
|
||||
// simple trace case
|
||||
// buffer.putSVInt((short) -1);
|
||||
|
||||
// byte cfBitField = SpanEventQualifierBitField.setAsync((byte) 0, false);
|
||||
// buffer.putByte(cfBitField);
|
||||
}
|
||||
|
||||
return buffer.wrapByteBuffer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private SpanEventBo getFirstSpanEvent(List<SpanEventBo> spanEventBoList) {
|
||||
if (CollectionUtils.isEmpty(spanEventBoList)) {
|
||||
return null;
|
||||
}
|
||||
// TODO duplicated sort
|
||||
sortSpanEvent(spanEventBoList);
|
||||
return spanEventBoList.get(0);
|
||||
}
|
||||
|
||||
public ByteBuffer encodeSpanChunkColumnValue(SpanEncodingContext<SpanChunkBo> encodingCtx) {
|
||||
final SpanChunkBo spanChunkBo = encodingCtx.getValue();
|
||||
// TODO duplicated sort
|
||||
sortSpanEvent(spanChunkBo.getSpanEventBoList());
|
||||
|
||||
final Buffer buffer = new AutomaticBuffer(256);
|
||||
|
||||
final byte version = spanChunkBo.getVersion();
|
||||
buffer.putByte(version);
|
||||
|
||||
|
||||
final List<SpanEventBo> spanEventBoList = spanChunkBo.getSpanEventBoList();
|
||||
writeSpanEventList(buffer, spanEventBoList, encodingCtx);
|
||||
|
||||
return buffer.wrapByteBuffer();
|
||||
}
|
||||
|
||||
private void writeSpanEventList(Buffer buffer, List<SpanEventBo> spanEventBoList, SpanEncodingContext<?> encodingCtx) {
|
||||
if (CollectionUtils.isEmpty(spanEventBoList)) {
|
||||
buffer.putVInt(0);
|
||||
} else {
|
||||
buffer.putVInt(spanEventBoList.size());
|
||||
|
||||
SpanEventBo prevSpanEvent = null;
|
||||
for (SpanEventBo spanEventBo : spanEventBoList) {
|
||||
if (prevSpanEvent == null) {
|
||||
writeFirstSpanEvent(buffer, spanEventBo, encodingCtx);
|
||||
} else {
|
||||
writeNextSpanEvent(buffer, spanEventBo, prevSpanEvent, encodingCtx);
|
||||
}
|
||||
prevSpanEvent = spanEventBo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ByteBuffer encodeSpanColumnValue(SpanEncodingContext<SpanBo> encodingCtx) {
|
||||
final SpanBo span = encodingCtx.getValue();
|
||||
|
||||
sortSpanEvent(span.getSpanEventBoList());
|
||||
|
||||
final SpanBitFiled bitField = SpanBitFiled.build(span);
|
||||
|
||||
final Buffer buffer = new AutomaticBuffer(256);
|
||||
|
||||
final byte version = span.getRawVersion();
|
||||
buffer.putByte(version);
|
||||
|
||||
// bit field
|
||||
buffer.putByte(bitField.getBitField());
|
||||
|
||||
|
||||
final short serviceType = span.getServiceType();
|
||||
buffer.putShort(serviceType);
|
||||
|
||||
switch (bitField.getApplicationServiceTypeEncodingStrategy()) {
|
||||
case PREV_EQUALS:
|
||||
break;
|
||||
case RAW:
|
||||
buffer.putShort(span.getApplicationServiceType());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("applicationServiceType");
|
||||
}
|
||||
|
||||
|
||||
// insert for rowkey
|
||||
// buffer.put(spanID);
|
||||
if (!bitField.isRoot()) {
|
||||
buffer.putLong(span.getParentSpanId());
|
||||
}
|
||||
|
||||
// prevSpanEvent coding
|
||||
final long startTime = span.getStartTime();
|
||||
final long startTimeDelta = span.getCollectorAcceptTime() - startTime;
|
||||
buffer.putVLong(startTimeDelta);
|
||||
buffer.putVInt(span.getElapsed());
|
||||
|
||||
|
||||
buffer.putPrefixedString(span.getRpc());
|
||||
|
||||
buffer.putPrefixedString(span.getEndPoint());
|
||||
buffer.putPrefixedString(span.getRemoteAddr());
|
||||
buffer.putSVInt(span.getApiId());
|
||||
|
||||
|
||||
// BIT flag
|
||||
if (bitField.isSetErrorCode()) {
|
||||
buffer.putInt(span.getErrCode());
|
||||
}
|
||||
|
||||
if (bitField.isSetHasException()) {
|
||||
buffer.putSVInt(span.getExceptionId());
|
||||
buffer.putPrefixedString(span.getExceptionMessage());
|
||||
}
|
||||
|
||||
if (bitField.isSetFlag()) {
|
||||
buffer.putShort(span.getFlag());
|
||||
}
|
||||
|
||||
|
||||
if (bitField.isSetLoggingTransactionInfo()) {
|
||||
buffer.putByte(span.getLoggingTransactionInfo());
|
||||
}
|
||||
|
||||
buffer.putPrefixedString(span.getAcceptorHost());
|
||||
|
||||
if (bitField.isSetAnnotation()) {
|
||||
List<AnnotationBo> annotationBoList = span.getAnnotationBoList();
|
||||
writeAnnotationList(buffer, annotationBoList, encodingCtx);
|
||||
}
|
||||
|
||||
final List<SpanEventBo> spanEventBoList = span.getSpanEventBoList();
|
||||
writeSpanEventList(buffer, spanEventBoList, encodingCtx);
|
||||
|
||||
return buffer.wrapByteBuffer();
|
||||
}
|
||||
|
||||
private void sortSpanEvent(List<SpanEventBo> spanEventBoList) {
|
||||
|
||||
if (CollectionUtils.isEmpty(spanEventBoList)) {
|
||||
return;
|
||||
}
|
||||
Collections.sort(spanEventBoList, SPAN_EVENT_SEQUENCE_COMPARATOR);
|
||||
}
|
||||
|
||||
public void writeFirstSpanEvent(Buffer buffer, SpanEventBo spanEventBo, SpanEncodingContext<?> encodingCtx) {
|
||||
|
||||
final SpanEventBitField bitField = SpanEventBitField.buildFirst(spanEventBo);
|
||||
|
||||
final byte firstSpanBitField1 = (byte) bitField.getBitField();
|
||||
buffer.putByte(firstSpanBitField1);
|
||||
|
||||
buffer.putVInt(spanEventBo.getStartElapsed());
|
||||
buffer.putVInt(spanEventBo.getEndElapsed());
|
||||
|
||||
buffer.putShort(spanEventBo.getSequence());
|
||||
buffer.putSVInt(spanEventBo.getDepth());
|
||||
buffer.putShort(spanEventBo.getServiceType());
|
||||
|
||||
|
||||
if (bitField.isSetRpc()) {
|
||||
buffer.putPrefixedString(spanEventBo.getRpc());
|
||||
}
|
||||
|
||||
if (bitField.isSetEndPoint()) {
|
||||
buffer.putPrefixedString(spanEventBo.getEndPoint());
|
||||
}
|
||||
if (bitField.isSetDestinationId()) {
|
||||
buffer.putPrefixedString(spanEventBo.getDestinationId());
|
||||
}
|
||||
|
||||
buffer.putSVInt(spanEventBo.getApiId());
|
||||
|
||||
if (bitField.isSetNextSpanId()) {
|
||||
buffer.putLong(spanEventBo.getNextSpanId());
|
||||
}
|
||||
|
||||
if (bitField.isSetHasException()) {
|
||||
buffer.putSVInt(spanEventBo.getExceptionId());
|
||||
buffer.putPrefixedString(spanEventBo.getExceptionMessage());
|
||||
}
|
||||
|
||||
if (bitField.isSetAnnotation()) {
|
||||
final List<AnnotationBo> annotationBoList = spanEventBo.getAnnotationBoList();
|
||||
writeAnnotationList(buffer, annotationBoList, encodingCtx);
|
||||
}
|
||||
|
||||
if (bitField.isSetNextAsyncId()) {
|
||||
buffer.putSVInt(spanEventBo.getNextAsyncId());
|
||||
}
|
||||
|
||||
// if (bitField.isSetAsyncId()) {
|
||||
// buffer.putInt(spanEventBo.getAsyncId());
|
||||
// buffer.putVInt(spanEventBo.getAsyncSequence());
|
||||
// }
|
||||
}
|
||||
|
||||
public void writeNextSpanEvent(Buffer buffer, SpanEventBo spanEventBo, SpanEventBo prevSpanEvent, SpanEncodingContext<?> encodingCtx) {
|
||||
|
||||
final SpanEventBitField bitField = SpanEventBitField.build(spanEventBo, prevSpanEvent);
|
||||
|
||||
buffer.putShort(bitField.getBitField());
|
||||
|
||||
switch (bitField.getStartElapsedEncodingStrategy()) {
|
||||
case PREV_DELTA:
|
||||
final int startTimeDelta = spanEventBo.getStartElapsed() - prevSpanEvent.getStartElapsed();
|
||||
buffer.putVInt(startTimeDelta);
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
// skip bitfield
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported SequenceEncodingStrategy");
|
||||
}
|
||||
buffer.putVInt(spanEventBo.getEndElapsed());
|
||||
|
||||
switch (bitField.getSequenceEncodingStrategy()) {
|
||||
case PREV_DELTA:
|
||||
final int sequenceDelta = spanEventBo.getSequence() - prevSpanEvent.getSequence();
|
||||
buffer.putVInt(sequenceDelta);
|
||||
break;
|
||||
case PREV_ADD1:
|
||||
// skip bitfield
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported SequenceEncodingStrategy");
|
||||
}
|
||||
|
||||
switch (bitField.getDepthEncodingStrategy()) {
|
||||
case RAW:
|
||||
buffer.putSVInt(spanEventBo.getDepth());
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
// skip bitfield
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported DepthEncodingStrategy");
|
||||
}
|
||||
|
||||
switch (bitField.getServiceTypeEncodingStrategy()) {
|
||||
case RAW:
|
||||
buffer.putShort(spanEventBo.getServiceType());
|
||||
break;
|
||||
case PREV_EQUALS:
|
||||
// skip bitfield
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unsupported ServiceTypeEncodingStrategy");
|
||||
}
|
||||
|
||||
|
||||
buffer.putSVInt(spanEventBo.getApiId());
|
||||
|
||||
if (bitField.isSetRpc()) {
|
||||
buffer.putPrefixedString(spanEventBo.getRpc());
|
||||
}
|
||||
|
||||
if (bitField.isSetEndPoint()) {
|
||||
buffer.putPrefixedString(spanEventBo.getEndPoint());
|
||||
}
|
||||
if (bitField.isSetDestinationId()) {
|
||||
buffer.putPrefixedString(spanEventBo.getDestinationId());
|
||||
}
|
||||
|
||||
if (bitField.isSetNextSpanId()) {
|
||||
buffer.putLong(spanEventBo.getNextSpanId());
|
||||
}
|
||||
|
||||
if (bitField.isSetHasException()) {
|
||||
buffer.putSVInt(spanEventBo.getExceptionId());
|
||||
buffer.putPrefixedString(spanEventBo.getExceptionMessage());
|
||||
}
|
||||
|
||||
if (bitField.isSetAnnotation()) {
|
||||
List<AnnotationBo> annotationBoList = spanEventBo.getAnnotationBoList();
|
||||
writeAnnotationList(buffer, annotationBoList, encodingCtx);
|
||||
}
|
||||
|
||||
if (bitField.isSetNextAsyncId()) {
|
||||
buffer.putSVInt(spanEventBo.getNextAsyncId());
|
||||
}
|
||||
|
||||
if (bitField.isSetAsyncId()) {
|
||||
buffer.putInt(spanEventBo.getAsyncId());
|
||||
buffer.putVInt(spanEventBo.getAsyncSequence());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotationList(Buffer buffer, List<AnnotationBo> annotationBoList, SpanEncodingContext<?> encodingCtx) {
|
||||
if (CollectionUtils.isEmpty(annotationBoList)) {
|
||||
return;
|
||||
}
|
||||
Collections.sort(annotationBoList, ANNOTATION_COMPARATOR);
|
||||
|
||||
buffer.putVInt(annotationBoList.size());
|
||||
|
||||
// AnnotationBo prev = encodingCtx.getPrevFirstAnnotationBo();
|
||||
AnnotationBo prev = null;
|
||||
for (int i = 0; i < annotationBoList.size(); i++) {
|
||||
final AnnotationBo current = annotationBoList.get(i);
|
||||
// first row
|
||||
if (i == 0) {
|
||||
|
||||
// first annotation
|
||||
buffer.putSVInt(current.getKey());
|
||||
buffer.putByte(current.getRawValueType());
|
||||
buffer.putPrefixedBytes(current.getByteValue());
|
||||
// else {
|
||||
// writeDeltaAnnotationBo(buffer, prev, current);
|
||||
// }
|
||||
// save first annotation
|
||||
// encodingCtx.setPrevFirstAnnotationBo(current);
|
||||
} else {
|
||||
writeDeltaAnnotationBo(buffer, prev, current);
|
||||
}
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDeltaAnnotationBo(Buffer buffer, AnnotationBo prev, AnnotationBo current) {
|
||||
// prev : -30 cur: -20 = -20 - - 30 = 10
|
||||
// prev : 20 cur: 100 = 100 - 20 = 80
|
||||
// prev : -40 cur: 1000 = 1000 + 40 = 10040
|
||||
final int prevKey = prev.getKey();
|
||||
final int currentKey = current.getKey();
|
||||
buffer.putSVInt(currentKey - prevKey);
|
||||
buffer.putByte(current.getRawValueType());
|
||||
buffer.putPrefixedBytes(current.getByteValue());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
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)
|
||||
*/
|
||||
public class SpanEncodingContext<T> {
|
||||
private T value;
|
||||
|
||||
private AnnotationBo prevAnnotationBo;
|
||||
|
||||
public SpanEncodingContext(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// public AnnotationBo getPrevFirstAnnotationBo() {
|
||||
// return prevAnnotationBo;
|
||||
// }
|
||||
//
|
||||
// public void setPrevFirstAnnotationBo(AnnotationBo prevAnnotationBo) {
|
||||
// this.prevAnnotationBo = prevAnnotationBo;
|
||||
// }
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
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.stereotype.Component;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
import static com.navercorp.pinpoint.common.hbase.HBaseTables.TRACE_V2_CF_SPAN;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Component
|
||||
public class SpanSerializerV2 implements HbaseSerializer<SpanBo, Put> {
|
||||
|
||||
|
||||
private final SpanEncoder spanEncoder = new SpanEncoder();
|
||||
|
||||
public SpanSerializerV2() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void serialize(SpanBo spanBo, Put put, SerializationContext context) {
|
||||
|
||||
final SpanEncodingContext<SpanBo> encodingContext = new SpanEncodingContext<>(spanBo);
|
||||
|
||||
ByteBuffer qualifier = spanEncoder.encodeSpanQualifier(encodingContext);
|
||||
ByteBuffer columnValue = spanEncoder.encodeSpanColumnValue(encodingContext);
|
||||
|
||||
long acceptedTime = put.getTimeStamp();
|
||||
put.addColumn(TRACE_V2_CF_SPAN, qualifier, acceptedTime, columnValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public enum DepthEncodingStrategy {
|
||||
// 1bit
|
||||
PREV_EQUALS(0),
|
||||
RAW(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
DepthEncodingStrategy(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public enum SequenceEncodingStrategy {
|
||||
// 1 bit
|
||||
PREV_ADD1(0),
|
||||
PREV_DELTA(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
SequenceEncodingStrategy(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public enum ServiceTypeEncodingStrategy {
|
||||
|
||||
// 1 bit
|
||||
PREV_EQUALS(0),
|
||||
RAW(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
ServiceTypeEncodingStrategy(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public enum SimpleServiceTypeEncodingStrategy {
|
||||
|
||||
// 1 bit
|
||||
PREV_EQUALS(0),
|
||||
RAW(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
SimpleServiceTypeEncodingStrategy(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.trace.LoggingInfo;
|
||||
import com.navercorp.pinpoint.common.util.BitFieldUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanBitFiled {
|
||||
|
||||
// 1bit
|
||||
public static final int SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY = 0;
|
||||
public static final int SET_ROOT = 1;
|
||||
public static final int SET_ERROR_CODE = 2;
|
||||
public static final int SET_HAS_EXCEPTION = 3;
|
||||
public static final int SET_FLAG = 4;
|
||||
public static final int SET_LOGGING_TRANSACTION_INFO = 5;
|
||||
public static final int SET_ANNOTATION = 6;
|
||||
|
||||
|
||||
private static final long ROOT_PARENT_SPAN_ID = -1;
|
||||
// used : 7bit
|
||||
// reserved : 1 bit
|
||||
private byte bitField = 0;
|
||||
|
||||
public static SpanBitFiled build(SpanBo spanBo) {
|
||||
if (spanBo == null) {
|
||||
throw new NullPointerException("spanBo must not be null");
|
||||
}
|
||||
final SpanBitFiled spanBitFiled = new SpanBitFiled();
|
||||
|
||||
|
||||
if (spanBo.getServiceType() == spanBo.getApplicationServiceType()) {
|
||||
spanBitFiled.setApplicationServiceTypeEncodingStrategy(SimpleServiceTypeEncodingStrategy.PREV_EQUALS);
|
||||
} else {
|
||||
spanBitFiled.setApplicationServiceTypeEncodingStrategy(SimpleServiceTypeEncodingStrategy.RAW);
|
||||
}
|
||||
|
||||
if (spanBo.getParentSpanId() == ROOT_PARENT_SPAN_ID) {
|
||||
spanBitFiled.setRoot(true);
|
||||
}
|
||||
if (spanBo.getErrCode() != 0) {
|
||||
spanBitFiled.setErrorCode(true);
|
||||
}
|
||||
|
||||
if (spanBo.hasException()) {
|
||||
spanBitFiled.setHasException(true);
|
||||
}
|
||||
|
||||
if (spanBo.getFlag() != 0) {
|
||||
spanBitFiled.setFlag(true);
|
||||
}
|
||||
|
||||
if (spanBo.getLoggingTransactionInfo() != LoggingInfo.NOT_LOGGED.getCode()) {
|
||||
spanBitFiled.setLoggingTransactionInfo(true);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(spanBo.getAnnotationBoList())) {
|
||||
spanBitFiled.setAnnotation(true);
|
||||
}
|
||||
|
||||
return spanBitFiled;
|
||||
}
|
||||
|
||||
public SpanBitFiled() {
|
||||
}
|
||||
|
||||
public SpanBitFiled(byte bitField) {
|
||||
this.bitField = bitField;
|
||||
}
|
||||
|
||||
public byte getBitField() {
|
||||
return bitField;
|
||||
}
|
||||
|
||||
// for test
|
||||
void maskAll() {
|
||||
bitField = -1;
|
||||
}
|
||||
|
||||
private void setBit(int position, boolean value) {
|
||||
this.bitField = BitFieldUtils.setBit(bitField, position, value);
|
||||
}
|
||||
|
||||
private boolean testBit(int position) {
|
||||
return BitFieldUtils.testBit(bitField, position);
|
||||
}
|
||||
|
||||
private int getBit(int position) {
|
||||
return BitFieldUtils.getBit(bitField, position);
|
||||
}
|
||||
|
||||
public SimpleServiceTypeEncodingStrategy getApplicationServiceTypeEncodingStrategy() {
|
||||
final int set = getBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY);
|
||||
switch (set) {
|
||||
case 0:
|
||||
return SimpleServiceTypeEncodingStrategy.PREV_EQUALS;
|
||||
case 1:
|
||||
return SimpleServiceTypeEncodingStrategy.RAW;
|
||||
default:
|
||||
throw new IllegalArgumentException("SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
void setApplicationServiceTypeEncodingStrategy(SimpleServiceTypeEncodingStrategy strategy) {
|
||||
switch (strategy) {
|
||||
case PREV_EQUALS:
|
||||
setBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY, false);
|
||||
break;
|
||||
case RAW:
|
||||
setBit(SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("SET_APPLICATION_SERVICE_TYPE_ENCODING_STRATEGY");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean isRoot() {
|
||||
return testBit(SET_ROOT);
|
||||
}
|
||||
|
||||
// for test
|
||||
void setRoot(boolean root) {
|
||||
setBit(SET_ROOT, root);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetErrorCode() {
|
||||
return testBit(SET_ERROR_CODE);
|
||||
}
|
||||
|
||||
|
||||
// for test
|
||||
void setErrorCode(boolean errorCode) {
|
||||
setBit(SET_ERROR_CODE, errorCode);
|
||||
}
|
||||
|
||||
public boolean isSetHasException() {
|
||||
return testBit(SET_HAS_EXCEPTION);
|
||||
}
|
||||
|
||||
// for test
|
||||
void setHasException(boolean hasException) {
|
||||
setBit(SET_HAS_EXCEPTION, hasException);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetFlag() {
|
||||
return testBit(SET_FLAG);
|
||||
}
|
||||
|
||||
// for test
|
||||
void setFlag(boolean flag) {
|
||||
setBit(SET_FLAG, flag);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetLoggingTransactionInfo() {
|
||||
return testBit(SET_LOGGING_TRANSACTION_INFO);
|
||||
}
|
||||
|
||||
// for test
|
||||
void setLoggingTransactionInfo(boolean loggingTransactionInfo) {
|
||||
setBit(SET_LOGGING_TRANSACTION_INFO, loggingTransactionInfo);
|
||||
}
|
||||
|
||||
public boolean isSetAnnotation() {
|
||||
return testBit(SET_ANNOTATION);
|
||||
}
|
||||
|
||||
|
||||
public void setAnnotation(boolean annotation) {
|
||||
setBit(SET_ANNOTATION, annotation);
|
||||
}
|
||||
}
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.AnnotationBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanEventBo;
|
||||
import com.navercorp.pinpoint.common.util.BitFieldUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanEventBitField {
|
||||
|
||||
|
||||
public static final int SET_ANNOTATION = 0;
|
||||
public static final int SET_HAS_EXCEPTION = 1;
|
||||
public static final int SET_NEXT_ASYNCID = 2;
|
||||
public static final int SET_ASYNCID = 3;
|
||||
public static final int SET_NEXT_SPANID = 4;
|
||||
public static final int SET_ENDPOINT = 5;
|
||||
public static final int SET_DESTINATIONID = 6;
|
||||
public static final int SET_RPC = 7;
|
||||
// firstSpan bitField -----------------------------------------------
|
||||
public static final int START_ELAPSED_ENCODING_STRATEGY = 8;
|
||||
public static final int SERVICE_TYPE_ENCODING_STRATEGY = 9;
|
||||
public static final int SEQUENCE_ENCODING_STRATEGY = 10;
|
||||
public static final int DEPTH_ENCODING_STRATEGY = 11;
|
||||
|
||||
public static final int API_ENCODING_STRATEGY = 13;
|
||||
|
||||
|
||||
private short bitField = 0;
|
||||
|
||||
|
||||
public static SpanEventBitField buildFirst(SpanEventBo spanEventBo) {
|
||||
if (spanEventBo == null) {
|
||||
throw new NullPointerException("spanEventBo must not be null");
|
||||
}
|
||||
final SpanEventBitField bitFiled = new SpanEventBitField();
|
||||
|
||||
if (spanEventBo.getRpc() != null) {
|
||||
bitFiled.setRpc(true);
|
||||
}
|
||||
if (spanEventBo.getEndPoint() != null) {
|
||||
bitFiled.setEndPoint(true);
|
||||
}
|
||||
|
||||
if (spanEventBo.getDestinationId() != null) {
|
||||
bitFiled.setDestinationId(true);
|
||||
}
|
||||
|
||||
if (spanEventBo.getNextSpanId() != -1) {
|
||||
bitFiled.setNextSpanId(true);
|
||||
}
|
||||
|
||||
if (spanEventBo.hasException()) {
|
||||
bitFiled.setHasException(true);
|
||||
}
|
||||
|
||||
final List<AnnotationBo> annotationBoList = spanEventBo.getAnnotationBoList();
|
||||
if (CollectionUtils.isNotEmpty(annotationBoList)) {
|
||||
bitFiled.setAnnotation(true);
|
||||
}
|
||||
|
||||
if (spanEventBo.getNextAsyncId() != -1) {
|
||||
bitFiled.setNextAsyncId(true);
|
||||
}
|
||||
|
||||
|
||||
if (spanEventBo.getAsyncId() == -1 && spanEventBo.getAsyncSequence() == -1) {
|
||||
bitFiled.setAsyncId(false);
|
||||
} else {
|
||||
bitFiled.setAsyncId(true);
|
||||
}
|
||||
return bitFiled;
|
||||
}
|
||||
|
||||
public static SpanEventBitField build(SpanEventBo spanEventBo, SpanEventBo prevSpanEventBo) {
|
||||
if (spanEventBo == null) {
|
||||
throw new NullPointerException("spanEventBo must not be null");
|
||||
}
|
||||
if (prevSpanEventBo == null) {
|
||||
throw new NullPointerException("prevSpanEventBo must not be null");
|
||||
}
|
||||
|
||||
final SpanEventBitField bitFiled = buildFirst(spanEventBo);
|
||||
|
||||
if (spanEventBo.getStartElapsed() == prevSpanEventBo.getStartElapsed()) {
|
||||
bitFiled.setStartElapsedEncodingStrategy(StartElapsedTimeEncodingStrategy.PREV_EQUALS);
|
||||
} else {
|
||||
bitFiled.setStartElapsedEncodingStrategy(StartElapsedTimeEncodingStrategy.PREV_DELTA);
|
||||
}
|
||||
|
||||
// sequence prev: 5 current: 6 = 6 - 5= delta 1
|
||||
final short sequenceDelta = (short) (spanEventBo.getSequence() - prevSpanEventBo.getSequence());
|
||||
if (sequenceDelta == 1) {
|
||||
bitFiled.setSequenceEncodingStrategy(SequenceEncodingStrategy.PREV_ADD1);
|
||||
} else {
|
||||
bitFiled.setSequenceEncodingStrategy(SequenceEncodingStrategy.PREV_DELTA);
|
||||
}
|
||||
|
||||
if (spanEventBo.getDepth() == prevSpanEventBo.getDepth()) {
|
||||
bitFiled.setDepthEncodingStrategy(DepthEncodingStrategy.PREV_EQUALS);
|
||||
} else {
|
||||
bitFiled.setDepthEncodingStrategy(DepthEncodingStrategy.RAW);
|
||||
}
|
||||
|
||||
|
||||
if (prevSpanEventBo.getServiceType() == spanEventBo.getServiceType()) {
|
||||
bitFiled.setServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy.PREV_EQUALS);
|
||||
} else {
|
||||
bitFiled.setServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy.RAW);
|
||||
}
|
||||
|
||||
|
||||
return bitFiled;
|
||||
}
|
||||
|
||||
public SpanEventBitField() {
|
||||
}
|
||||
|
||||
public SpanEventBitField(short bitField) {
|
||||
this.bitField = bitField;
|
||||
}
|
||||
|
||||
// for test
|
||||
void maskAll() {
|
||||
bitField = -1;
|
||||
}
|
||||
|
||||
public short getBitField() {
|
||||
return bitField;
|
||||
}
|
||||
|
||||
private void setBit(int position, boolean value) {
|
||||
this.bitField = BitFieldUtils.setBit(bitField, position, value);
|
||||
}
|
||||
|
||||
private boolean testBit(int position) {
|
||||
return BitFieldUtils.testBit(bitField, position);
|
||||
}
|
||||
|
||||
private int getBit(int position) {
|
||||
return BitFieldUtils.getBit(bitField, position);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetHasException() {
|
||||
return testBit(SET_HAS_EXCEPTION);
|
||||
}
|
||||
|
||||
void setHasException(boolean hasException) {
|
||||
setBit(SET_HAS_EXCEPTION, hasException);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetAnnotation() {
|
||||
return testBit(SET_ANNOTATION);
|
||||
}
|
||||
|
||||
void setAnnotation(boolean annotation) {
|
||||
setBit(SET_ANNOTATION, annotation);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetNextAsyncId() {
|
||||
return testBit(SET_NEXT_ASYNCID);
|
||||
}
|
||||
|
||||
void setNextAsyncId(boolean nextAsyncSpanId) {
|
||||
setBit(SET_NEXT_ASYNCID, nextAsyncSpanId);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetNextSpanId() {
|
||||
return testBit(SET_NEXT_SPANID);
|
||||
}
|
||||
|
||||
void setNextSpanId(boolean nextSpanId) {
|
||||
setBit(SET_NEXT_SPANID, nextSpanId);
|
||||
}
|
||||
|
||||
public boolean isSetEndPoint() {
|
||||
return testBit(SET_ENDPOINT);
|
||||
}
|
||||
|
||||
void setEndPoint(boolean endPoint) {
|
||||
setBit(SET_ENDPOINT, endPoint);
|
||||
}
|
||||
|
||||
public boolean isSetDestinationId() {
|
||||
return testBit(SET_DESTINATIONID);
|
||||
}
|
||||
|
||||
void setDestinationId(boolean destinationId) {
|
||||
setBit(SET_DESTINATIONID, destinationId);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSetRpc() {
|
||||
return testBit(SET_RPC);
|
||||
}
|
||||
|
||||
void setRpc(boolean rpc) {
|
||||
setBit(SET_RPC, rpc);
|
||||
}
|
||||
|
||||
public boolean isSetAsyncId() {
|
||||
return testBit(SET_ASYNCID);
|
||||
}
|
||||
|
||||
void setAsyncId(boolean asyncId) {
|
||||
setBit(SET_ASYNCID, asyncId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public StartElapsedTimeEncodingStrategy getStartElapsedEncodingStrategy() {
|
||||
final int set = getBit(START_ELAPSED_ENCODING_STRATEGY);
|
||||
switch (set) {
|
||||
case 0:
|
||||
return StartElapsedTimeEncodingStrategy.PREV_EQUALS;
|
||||
case 1:
|
||||
return StartElapsedTimeEncodingStrategy.PREV_DELTA;
|
||||
default:
|
||||
throw new IllegalArgumentException("SERVICE_TYPE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
void setStartElapsedEncodingStrategy(StartElapsedTimeEncodingStrategy strategy) {
|
||||
switch (strategy) {
|
||||
case PREV_EQUALS:
|
||||
setBit(START_ELAPSED_ENCODING_STRATEGY, false);
|
||||
break;
|
||||
case PREV_DELTA:
|
||||
setBit(START_ELAPSED_ENCODING_STRATEGY, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("START_ELAPSED_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ServiceTypeEncodingStrategy getServiceTypeEncodingStrategy() {
|
||||
final int set = getBit(SERVICE_TYPE_ENCODING_STRATEGY);
|
||||
switch (set) {
|
||||
case 0:
|
||||
return ServiceTypeEncodingStrategy.PREV_EQUALS;
|
||||
case 1:
|
||||
return ServiceTypeEncodingStrategy.RAW;
|
||||
default:
|
||||
throw new IllegalArgumentException("SERVICE_TYPE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
void setServiceTypeEncodingStrategy(ServiceTypeEncodingStrategy strategy) {
|
||||
switch (strategy) {
|
||||
case PREV_EQUALS:
|
||||
setBit(SERVICE_TYPE_ENCODING_STRATEGY, false);
|
||||
break;
|
||||
case RAW:
|
||||
setBit(SERVICE_TYPE_ENCODING_STRATEGY, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("SERVICE_TYPE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
public SequenceEncodingStrategy getSequenceEncodingStrategy() {
|
||||
final int set = getBit(SEQUENCE_ENCODING_STRATEGY);
|
||||
switch (set) {
|
||||
case 0:
|
||||
return SequenceEncodingStrategy.PREV_ADD1;
|
||||
case 1:
|
||||
return SequenceEncodingStrategy.PREV_DELTA;
|
||||
default:
|
||||
throw new IllegalArgumentException("SEQUENCE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setSequenceEncodingStrategy(SequenceEncodingStrategy strategy) {
|
||||
switch (strategy) {
|
||||
case PREV_ADD1:
|
||||
setBit(SEQUENCE_ENCODING_STRATEGY, false);
|
||||
break;
|
||||
case PREV_DELTA:
|
||||
setBit(SEQUENCE_ENCODING_STRATEGY, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("SEQUENCE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
public DepthEncodingStrategy getDepthEncodingStrategy() {
|
||||
final int set = getBit(DEPTH_ENCODING_STRATEGY);
|
||||
switch (set) {
|
||||
case 0:
|
||||
return DepthEncodingStrategy.PREV_EQUALS;
|
||||
case 1:
|
||||
return DepthEncodingStrategy.RAW;
|
||||
default:
|
||||
throw new IllegalArgumentException("DEPTH_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
void setDepthEncodingStrategy(DepthEncodingStrategy strategy) {
|
||||
switch (strategy) {
|
||||
case PREV_EQUALS:
|
||||
setBit(DEPTH_ENCODING_STRATEGY, false);
|
||||
break;
|
||||
case RAW:
|
||||
setBit(DEPTH_ENCODING_STRATEGY, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("SEQUENCE_ENCODING_STRATEGY");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanEventBo;
|
||||
import com.navercorp.pinpoint.common.util.BitFieldUtils;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanEventQualifierBitField {
|
||||
|
||||
public static final int SET_ASYNC = 0;
|
||||
|
||||
public static byte buildBitField(SpanEventBo firstSpanEvent) {
|
||||
if (firstSpanEvent == null) {
|
||||
// no async bit field
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte bitField = 0;
|
||||
|
||||
final int asyncId = firstSpanEvent.getAsyncId();
|
||||
final short asyncSequence = firstSpanEvent.getAsyncSequence();
|
||||
if (asyncId == -1 && asyncSequence == -1) {
|
||||
bitField = setAsync(bitField, false);
|
||||
} else {
|
||||
bitField = setAsync(bitField, true);
|
||||
}
|
||||
|
||||
return bitField;
|
||||
}
|
||||
|
||||
private SpanEventQualifierBitField() {
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSetAsync(byte bitField) {
|
||||
return BitFieldUtils.testBit(bitField, SET_ASYNC);
|
||||
}
|
||||
|
||||
public static byte setAsync(byte bitField, boolean async) {
|
||||
return BitFieldUtils.setBit(bitField, SET_ASYNC, async);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public enum StartElapsedTimeEncodingStrategy {
|
||||
// 1 bit
|
||||
PREV_EQUALS(0),
|
||||
PREV_DELTA(1);
|
||||
|
||||
private final int code;
|
||||
|
||||
StartElapsedTimeEncodingStrategy(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ package com.navercorp.pinpoint.common.server.bo;
|
||||
|
||||
import com.navercorp.pinpoint.common.buffer.AutomaticBuffer;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.AnnotationSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.AnnotationSerializer;
|
||||
import com.navercorp.pinpoint.common.trace.AnnotationKey;
|
||||
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.navercorp.pinpoint.common.server.bo;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.AnnotationSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.SpanEventSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.AnnotationSerializer;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanEventSerializer;
|
||||
import com.navercorp.pinpoint.common.trace.ServiceType;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
+2
-1
@@ -14,10 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer;
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v1;
|
||||
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v1.SpanSerializer;
|
||||
import com.navercorp.pinpoint.common.trace.LoggingInfo;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.Assert;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanEncoderTest {
|
||||
@Test
|
||||
public void encodeSpanColumnValue() throws Exception {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2;
|
||||
|
||||
import com.navercorp.pinpoint.common.util.BytesUtils;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanSerializerV2Test {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testEstimationDelta() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanBitFiled;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SimpleServiceTypeEncodingStrategy;
|
||||
import com.navercorp.pinpoint.common.trace.LoggingInfo;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanBitFiledTest {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Test
|
||||
public void testRoot_1() throws Exception {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setParentSpanId(-1);
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
Assert.assertTrue(spanBitFiled.isRoot());
|
||||
|
||||
spanBitFiled.setRoot(false);
|
||||
Assert.assertFalse(spanBitFiled.isRoot());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoot_2() throws Exception {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setParentSpanId(0);
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
Assert.assertFalse(spanBitFiled.isRoot());
|
||||
|
||||
spanBitFiled.maskAll();
|
||||
spanBitFiled.setRoot(false);
|
||||
Assert.assertFalse(spanBitFiled.isRoot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorCode_1() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setErrCode(1);
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertTrue(spanBitFiled.isSetErrorCode());
|
||||
|
||||
spanBitFiled.setErrorCode(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorCode_2() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setErrCode(0);
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertFalse(spanBitFiled.isSetErrorCode());
|
||||
|
||||
spanBitFiled.maskAll();
|
||||
spanBitFiled.setErrorCode(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetErrorCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplicationServiceTypeEncodingStrategy_PREV_TYPE_EQUALS() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setServiceType((short) 1000);
|
||||
spanBo.setApplicationServiceType((short) 1000);
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertEquals(spanBitFiled.getApplicationServiceTypeEncodingStrategy(), SimpleServiceTypeEncodingStrategy.PREV_EQUALS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplicationServiceTypeEncodingStrategy_RAW() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setServiceType((short) 1000);
|
||||
spanBo.setApplicationServiceType((short) 2000);
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertEquals(spanBitFiled.getApplicationServiceTypeEncodingStrategy(), SimpleServiceTypeEncodingStrategy.RAW);
|
||||
|
||||
spanBitFiled.maskAll();
|
||||
Assert.assertEquals(spanBitFiled.getApplicationServiceTypeEncodingStrategy(), SimpleServiceTypeEncodingStrategy.RAW);
|
||||
spanBitFiled.setApplicationServiceTypeEncodingStrategy(SimpleServiceTypeEncodingStrategy.PREV_EQUALS);
|
||||
Assert.assertEquals(spanBitFiled.getApplicationServiceTypeEncodingStrategy(), SimpleServiceTypeEncodingStrategy.PREV_EQUALS);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHasException_1() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setExceptionInfo(1, "error");
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertTrue(spanBitFiled.isSetHasException());
|
||||
|
||||
spanBitFiled.setHasException(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetHasException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasException_2() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertFalse(spanBitFiled.isSetHasException());
|
||||
|
||||
spanBitFiled.maskAll();
|
||||
spanBitFiled.setHasException(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetHasException());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testLoggingTransactionInfo_1() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
spanBo.setLoggingTransactionInfo(LoggingInfo.INFO.getCode());
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertTrue(spanBitFiled.isSetLoggingTransactionInfo());
|
||||
|
||||
spanBitFiled.setLoggingTransactionInfo(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetLoggingTransactionInfo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoggingTransactionInfo_2() {
|
||||
SpanBo spanBo = new SpanBo();
|
||||
|
||||
SpanBitFiled spanBitFiled = SpanBitFiled.build(spanBo);
|
||||
|
||||
Assert.assertFalse(spanBitFiled.isSetLoggingTransactionInfo());
|
||||
|
||||
spanBitFiled.maskAll();
|
||||
spanBitFiled.setLoggingTransactionInfo(false);
|
||||
Assert.assertFalse(spanBitFiled.isSetLoggingTransactionInfo());
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.bitfield.SpanEventBitField;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanEventBitFieldTest {
|
||||
@Test
|
||||
public void isSetHasException() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setHasException_shortToByteCasting() throws Exception {
|
||||
SpanEventBitField field = new SpanEventBitField();
|
||||
field.setHasException(true);
|
||||
|
||||
byte byteField = (byte) field.getBitField();
|
||||
|
||||
SpanEventBitField byteCastField = new SpanEventBitField(byteField);
|
||||
Assert.assertTrue(byteCastField.isSetHasException());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,8 @@ create 'ApiMetaData', { NAME => 'Api', COMPRESSION => 'SNAPPY', TTL => 31536000,
|
||||
create 'SqlMetaData_Ver2', { NAME => 'Sql', COMPRESSION => 'SNAPPY', TTL => 15552000, DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
create 'Traces', { NAME => 'S', TTL => 5184000, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, { NAME => 'A', TTL => 5184000, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, { NAME => 'T', TTL => 5184000, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
create 'TraceV2', { NAME => 'S', TTL => 5184000, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, {NUMREGIONS => 256, SPLITALGO => 'UniformSplit'}
|
||||
|
||||
create 'ApplicationTraceIndex', { NAME => 'I', TTL => 5184000, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
create 'ApplicationMapStatisticsCaller_Ver2', { NAME => 'C', TTL => 5184000, VERSIONS => 1, COMPRESSION => 'SNAPPY', DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
@@ -11,6 +11,8 @@ create 'ApiMetaData', { NAME => 'Api', TTL => 31536000, DATA_BLOCK_ENCODING => '
|
||||
create 'SqlMetaData_Ver2', { NAME => 'Sql', TTL => 15552000, DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
create 'Traces', { NAME => 'S', TTL => 5184000, DATA_BLOCK_ENCODING => 'PREFIX' }, { NAME => 'A', TTL => 5184000, DATA_BLOCK_ENCODING => 'PREFIX' }, { NAME => 'T', TTL => 5184000, DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x2f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
create 'TraceV2', { NAME => 'S', TTL => 5184000, DATA_BLOCK_ENCODING => 'PREFIX' }, {NUMREGIONS => 256, SPLITALGO => 'UniformSplit'}
|
||||
|
||||
create 'ApplicationTraceIndex', { NAME => 'I', TTL => 5184000, DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
create 'ApplicationMapStatisticsCaller_Ver2', { NAME => 'C', TTL => 5184000, VERSIONS => 1, DATA_BLOCK_ENCODING => 'PREFIX' }, {SPLITS=>["\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"]}
|
||||
|
||||
@@ -12,6 +12,7 @@ disable 'SqlMetaData_Ver2'
|
||||
|
||||
disable 'ApplicationTraceIndex'
|
||||
disable 'Traces'
|
||||
disable 'TraceV2'
|
||||
|
||||
|
||||
disable 'ApplicationMapStatisticsCaller_Ver2'
|
||||
|
||||
@@ -30,12 +30,14 @@ public interface TraceDao {
|
||||
|
||||
List<SpanBo> selectSpan(TransactionId transactionId);
|
||||
|
||||
@Deprecated
|
||||
List<SpanBo> selectSpanAndAnnotation(TransactionId transactionId);
|
||||
|
||||
List<List<SpanBo>> selectSpans(List<TransactionId> transactionIdList);
|
||||
|
||||
List<List<SpanBo>> selectAllSpans(Collection<TransactionId> transactionIdList);
|
||||
|
||||
@Deprecated
|
||||
List<SpanBo> selectSpans(TransactionId transactionId);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.navercorp.pinpoint.web.dao.hbase;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.web.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.web.vo.TransactionId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Beta
|
||||
public class HbaseDualReadDao implements TraceDao {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final TraceDao master;
|
||||
private final TraceDao slave;
|
||||
|
||||
public HbaseDualReadDao(TraceDao v2, TraceDao slave) {
|
||||
if (v2 == null) {
|
||||
throw new NullPointerException("master must not be null");
|
||||
}
|
||||
if (slave == null) {
|
||||
throw new NullPointerException("v1 must not be null");
|
||||
}
|
||||
|
||||
this.master = v2;
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpan(TransactionId transactionId) {
|
||||
Throwable masterThrowable = null;
|
||||
List<SpanBo> result = null;
|
||||
try {
|
||||
result = master.selectSpan(transactionId);
|
||||
} catch (Throwable th) {
|
||||
masterThrowable = th;
|
||||
}
|
||||
try {
|
||||
slave.selectSpan(transactionId);
|
||||
} catch (Throwable th) {
|
||||
logger.debug("slave error :{}", th.getMessage(), th);
|
||||
}
|
||||
|
||||
rethrowRuntimeException(masterThrowable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpanAndAnnotation(TransactionId transactionId) {
|
||||
Throwable masterThrowable = null;
|
||||
List<SpanBo> result = null;
|
||||
try {
|
||||
result = master.selectSpanAndAnnotation(transactionId);
|
||||
} catch (Throwable th) {
|
||||
masterThrowable = th;
|
||||
}
|
||||
try {
|
||||
slave.selectSpanAndAnnotation(transactionId);
|
||||
} catch (Throwable th) {
|
||||
logger.debug("slave error :{}", th.getMessage(), th);
|
||||
}
|
||||
|
||||
rethrowRuntimeException(masterThrowable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectSpans(List<TransactionId> transactionIdList) {
|
||||
Throwable masterThrowable = null;
|
||||
List<List<SpanBo>> result = null;
|
||||
try {
|
||||
result = master.selectSpans(transactionIdList);
|
||||
} catch (Throwable th) {
|
||||
masterThrowable = th;
|
||||
}
|
||||
try {
|
||||
slave.selectSpans(transactionIdList);
|
||||
} catch (Throwable th) {
|
||||
logger.debug("slave error :{}", th.getMessage(), th);
|
||||
}
|
||||
|
||||
rethrowRuntimeException(masterThrowable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectAllSpans(Collection<TransactionId> transactionIdList) {
|
||||
Throwable masterThrowable = null;
|
||||
List<List<SpanBo>> result = null;
|
||||
try {
|
||||
result = master.selectAllSpans(transactionIdList);
|
||||
} catch (Throwable th) {
|
||||
masterThrowable = th;
|
||||
}
|
||||
try {
|
||||
slave.selectAllSpans(transactionIdList);
|
||||
} catch (Throwable th) {
|
||||
logger.debug("slave error :{}", th.getMessage(), th);
|
||||
}
|
||||
|
||||
rethrowRuntimeException(masterThrowable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpans(TransactionId transactionId) {
|
||||
Throwable masterThrowable = null;
|
||||
List<SpanBo> result = null;
|
||||
try {
|
||||
result = master.selectSpans(transactionId);
|
||||
} catch (Throwable th) {
|
||||
masterThrowable = th;
|
||||
}
|
||||
try {
|
||||
slave.selectSpans(transactionId);
|
||||
} catch (Throwable th) {
|
||||
logger.debug("slave error :{}", th.getMessage(), th);
|
||||
}
|
||||
|
||||
rethrowRuntimeException(masterThrowable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void rethrowRuntimeException(Throwable exception) {
|
||||
if (exception != null) {
|
||||
this.<RuntimeException>rethrowException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Exception> void rethrowException(final Throwable exception) throws T {
|
||||
throw (T) exception;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.navercorp.pinpoint.web.dao.hbase;
|
||||
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.web.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.web.vo.TransactionId;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class HbaseTraceCompatibilityDao implements TraceDao {
|
||||
|
||||
private final TraceDao master;
|
||||
private final TraceDao slave;
|
||||
|
||||
public HbaseTraceCompatibilityDao(TraceDao master, TraceDao slave) {
|
||||
if (master == null) {
|
||||
throw new NullPointerException("master must not be null");
|
||||
}
|
||||
if (slave == null) {
|
||||
throw new NullPointerException("slave must not be null");
|
||||
}
|
||||
|
||||
this.master = master;
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpan(TransactionId transactionId) {
|
||||
List<SpanBo> spanBos = this.master.selectSpan(transactionId);
|
||||
if (CollectionUtils.isNotEmpty(spanBos)) {
|
||||
return spanBos;
|
||||
}
|
||||
|
||||
return slave.selectSpan(transactionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpanAndAnnotation(TransactionId transactionId) {
|
||||
List<SpanBo> spanBos = this.master.selectSpanAndAnnotation(transactionId);
|
||||
if (CollectionUtils.isNotEmpty(spanBos)) {
|
||||
return spanBos;
|
||||
}
|
||||
|
||||
return slave.selectSpanAndAnnotation(transactionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectSpans(List<TransactionId> transactionIdList) {
|
||||
List<List<SpanBo>> spanBos = this.master.selectSpans(transactionIdList);
|
||||
if (CollectionUtils.isNotEmpty(spanBos)) {
|
||||
return spanBos;
|
||||
}
|
||||
|
||||
return slave.selectSpans(transactionIdList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectAllSpans(Collection<TransactionId> transactionIdList) {
|
||||
List<List<SpanBo>> spanBos = this.master.selectAllSpans(transactionIdList);
|
||||
if (CollectionUtils.isNotEmpty(spanBos)) {
|
||||
return spanBos;
|
||||
}
|
||||
|
||||
return slave.selectAllSpans(transactionIdList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpans(TransactionId transactionId) {
|
||||
List<SpanBo> spanBos = this.master.selectSpans(transactionId);
|
||||
if (CollectionUtils.isNotEmpty(spanBos)) {
|
||||
return spanBos;
|
||||
}
|
||||
|
||||
return slave.selectSpans(transactionId);
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,12 @@ import com.navercorp.pinpoint.common.hbase.HBaseTables;
|
||||
import com.navercorp.pinpoint.common.hbase.HbaseOperations2;
|
||||
import com.navercorp.pinpoint.common.hbase.RowMapper;
|
||||
import com.navercorp.pinpoint.web.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.web.mapper.CellTraceMapper;
|
||||
import com.navercorp.pinpoint.web.vo.TransactionId;
|
||||
import com.sematext.hbase.wd.AbstractRowKeyDistributor;
|
||||
import org.apache.hadoop.hbase.client.Get;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -41,6 +44,8 @@ import java.util.List;
|
||||
@Repository
|
||||
public class HbaseTraceDao implements TraceDao {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private HbaseOperations2 template2;
|
||||
|
||||
@@ -48,8 +53,7 @@ public class HbaseTraceDao implements TraceDao {
|
||||
@Qualifier("traceDistributor")
|
||||
private AbstractRowKeyDistributor rowKeyDistributor;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("spanMapper")
|
||||
|
||||
private RowMapper<List<SpanBo>> spanMapper;
|
||||
|
||||
@Autowired
|
||||
@@ -62,6 +66,16 @@ public class HbaseTraceDao implements TraceDao {
|
||||
@Value("#{pinpointWebProps['web.hbase.selectAllSpans.limit'] ?: 500}")
|
||||
private int selectAllSpansLimit;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("spanMapper")
|
||||
public void setSpanMapper(RowMapper<List<SpanBo>> spanMapper) {
|
||||
final Logger logger = LoggerFactory.getLogger(spanMapper.getClass());
|
||||
if (logger.isDebugEnabled()) {
|
||||
spanMapper = CellTraceMapper.wrap(spanMapper);
|
||||
}
|
||||
this.spanMapper = spanMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpan(TransactionId transactionId) {
|
||||
if (transactionId == null) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.navercorp.pinpoint.web.dao.hbase;
|
||||
|
||||
import com.navercorp.pinpoint.web.dao.TraceDao;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* TraceDao Factory for compatibility
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Repository
|
||||
public class HbaseTraceDaoFactory implements FactoryBean<TraceDao> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDao")
|
||||
private TraceDao v1;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoV2")
|
||||
private TraceDao v2;
|
||||
|
||||
|
||||
@Value("#{pinpointWebProps['web.experimental.span.format.compatibility.version'] ?: 'v1'}")
|
||||
private String mode = "v1";
|
||||
|
||||
@Override
|
||||
public TraceDao getObject() throws Exception {
|
||||
|
||||
logger.info("TraceDao Compatibility {}", mode);
|
||||
|
||||
if (mode.equalsIgnoreCase("v1")) {
|
||||
return v1;
|
||||
}
|
||||
else if (mode.equalsIgnoreCase("v2")) {
|
||||
return v2;
|
||||
}
|
||||
else if (mode.equalsIgnoreCase("compatibilityMode")) {
|
||||
return new HbaseTraceCompatibilityDao(v2, v1);
|
||||
}
|
||||
else if (mode.equalsIgnoreCase("dualRead")) {
|
||||
return new HbaseDualReadDao(v2, v1);
|
||||
}
|
||||
return v1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return TraceDao.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.navercorp.pinpoint.web.dao.hbase;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.navercorp.pinpoint.common.hbase.HBaseTables;
|
||||
import com.navercorp.pinpoint.common.hbase.HbaseOperations2;
|
||||
import com.navercorp.pinpoint.common.hbase.RowMapper;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.web.dao.TraceDao;
|
||||
import com.navercorp.pinpoint.web.mapper.CellTraceMapper;
|
||||
import com.navercorp.pinpoint.web.vo.TransactionId;
|
||||
import com.sematext.hbase.wd.AbstractRowKeyDistributor;
|
||||
import org.apache.hadoop.hbase.client.Get;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
@Beta
|
||||
@Repository
|
||||
public class HbaseTraceDaoV2 implements TraceDao {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private HbaseOperations2 template2;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("traceV2Distributor")
|
||||
private AbstractRowKeyDistributor rowKeyDistributor;
|
||||
|
||||
|
||||
private RowMapper<List<SpanBo>> spanMapperV2;
|
||||
|
||||
|
||||
@Value("#{pinpointWebProps['web.hbase.selectSpans.limit'] ?: 500}")
|
||||
private int selectSpansLimit;
|
||||
|
||||
@Value("#{pinpointWebProps['web.hbase.selectAllSpans.limit'] ?: 500}")
|
||||
private int selectAllSpansLimit;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("spanMapperV2")
|
||||
public void setSpanMapperV2(RowMapper<List<SpanBo>> spanMapperV2) {
|
||||
final Logger logger = LoggerFactory.getLogger(spanMapperV2.getClass());
|
||||
if (logger.isDebugEnabled()) {
|
||||
spanMapperV2 = CellTraceMapper.wrap(spanMapperV2);
|
||||
}
|
||||
this.spanMapperV2 = spanMapperV2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpan(TransactionId transactionId) {
|
||||
if (transactionId == null) {
|
||||
throw new NullPointerException("transactionId must not be null");
|
||||
}
|
||||
|
||||
byte[] traceIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes());
|
||||
return template2.get(HBaseTables.TRACE_V2, traceIdBytes, HBaseTables.TRACE_V2_CF_SPAN, spanMapperV2);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public List<SpanBo> selectSpanAndAnnotation(TransactionId transactionId) {
|
||||
if (transactionId == null) {
|
||||
throw new NullPointerException("transactionId must not be null");
|
||||
}
|
||||
|
||||
return selectSpan(transactionId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectSpans(List<TransactionId> transactionIdList) {
|
||||
return selectSpans(transactionIdList, selectSpansLimit);
|
||||
}
|
||||
|
||||
public List<List<SpanBo>> selectSpans(List<TransactionId> transactionIdList, int hBaseGetLimitSize) {
|
||||
if (transactionIdList == null) {
|
||||
throw new NullPointerException("transactionIdList must not be null");
|
||||
}
|
||||
|
||||
List<List<TransactionId>> splitTransactionIdList = splitTransactionIdList(transactionIdList, hBaseGetLimitSize);
|
||||
|
||||
return getSpans(splitTransactionIdList, HBaseTables.TRACE_V2_CF_SPAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<SpanBo>> selectAllSpans(Collection<TransactionId> transactionIdList) {
|
||||
return selectAllSpans(transactionIdList, selectAllSpansLimit);
|
||||
}
|
||||
|
||||
public List<List<SpanBo>> selectAllSpans(Collection<TransactionId> transactionIdList, int hBaseGetLimitSize) {
|
||||
if (transactionIdList == null) {
|
||||
throw new NullPointerException("transactionIdList must not be null");
|
||||
}
|
||||
|
||||
List<List<TransactionId>> splitTransactionIdList = splitTransactionIdList(Lists.newArrayList(transactionIdList), hBaseGetLimitSize);
|
||||
|
||||
|
||||
return getSpans(splitTransactionIdList, HBaseTables.TRACE_V2_CF_SPAN);
|
||||
}
|
||||
|
||||
|
||||
private List<List<TransactionId>> splitTransactionIdList(List<TransactionId> transactionIdList, int maxTransactionIdListSize) {
|
||||
if (transactionIdList == null || transactionIdList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<List<TransactionId>> splitTransactionIdList = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
int endIndex = transactionIdList.size();
|
||||
while (index < endIndex) {
|
||||
int subListEndIndex = Math.min(index + maxTransactionIdListSize, endIndex);
|
||||
splitTransactionIdList.add(transactionIdList.subList(index, subListEndIndex));
|
||||
index = subListEndIndex;
|
||||
}
|
||||
|
||||
return splitTransactionIdList;
|
||||
}
|
||||
|
||||
private List<List<SpanBo>> getSpans(List<List<TransactionId>> splitTransactionIdList, byte[] columnFamily) {
|
||||
if (splitTransactionIdList == null || splitTransactionIdList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<List<SpanBo>> spanBoList = new ArrayList<>();
|
||||
for (List<TransactionId> transactionIdList : splitTransactionIdList) {
|
||||
spanBoList.addAll(getSpans0(transactionIdList, columnFamily));
|
||||
}
|
||||
return spanBoList;
|
||||
}
|
||||
|
||||
private List<List<SpanBo>> getSpans0(List<TransactionId> transactionIdList, byte[] columnFamily) {
|
||||
if (transactionIdList == null || transactionIdList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (columnFamily == null) {
|
||||
throw new NullPointerException("columnFamily may not be null.");
|
||||
}
|
||||
|
||||
final List<Get> getList = new ArrayList<>(transactionIdList.size());
|
||||
for (TransactionId transactionId : transactionIdList) {
|
||||
|
||||
final byte[] transactionIdBytes = rowKeyDistributor.getDistributedKey(transactionId.getBytes());
|
||||
final Get get = new Get(transactionIdBytes);
|
||||
get.addFamily(columnFamily);
|
||||
|
||||
getList.add(get);
|
||||
}
|
||||
return template2.get(HBaseTables.TRACE_V2, getList, spanMapperV2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpanBo> selectSpans(TransactionId transactionId) {
|
||||
return selectSpan(transactionId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.navercorp.pinpoint.web.mapper;
|
||||
|
||||
import com.navercorp.pinpoint.common.hbase.RowMapper;
|
||||
import com.navercorp.pinpoint.web.util.CellTracker;
|
||||
import com.navercorp.pinpoint.web.util.DefaultCellTracker;
|
||||
import org.apache.hadoop.hbase.Cell;
|
||||
import org.apache.hadoop.hbase.client.Result;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class CellTraceMapper<T> implements RowMapper<T> {
|
||||
private RowMapper<T> delegate;
|
||||
|
||||
public static <T> RowMapper<T> wrap(RowMapper<T> deleagate) {
|
||||
|
||||
return new CellTraceMapper<T>(deleagate);
|
||||
}
|
||||
|
||||
|
||||
private CellTraceMapper(RowMapper<T> delegate) {
|
||||
if (delegate == null) {
|
||||
throw new NullPointerException("delegate must not be null");
|
||||
}
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T mapRow(Result result, int rowNum) throws Exception {
|
||||
final T returnValue = this.delegate.mapRow(result, rowNum);
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
|
||||
final Cell[] rawCells = result.rawCells();
|
||||
|
||||
final CellTracker cellTracker = new DefaultCellTracker(delegate.getClass().getSimpleName());
|
||||
for (Cell cell : rawCells) {
|
||||
cellTracker.trace(cell);
|
||||
}
|
||||
cellTracker.log();
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,6 @@ import java.util.*;
|
||||
public class SpanMapper implements RowMapper<List<SpanBo>> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private AnnotationMapper annotationMapper;
|
||||
|
||||
private final AnnotationBoDecoder annotationBoDecoder = new AnnotationBoDecoder();
|
||||
@@ -79,7 +78,7 @@ public class SpanMapper implements RowMapper<List<SpanBo>> {
|
||||
spanBo.setTraceTransactionSequence(transactionId.getTransactionSequence());
|
||||
spanBo.setCollectorAcceptTime(cell.getTimestamp());
|
||||
|
||||
spanBo.setSpanID(Bytes.toLong(cell.getQualifierArray(), cell.getQualifierOffset()));
|
||||
spanBo.setSpanId(Bytes.toLong(cell.getQualifierArray(), cell.getQualifierOffset()));
|
||||
readSpan(spanBo, cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("read span :{}", spanBo);
|
||||
@@ -118,9 +117,14 @@ public class SpanMapper implements RowMapper<List<SpanBo>> {
|
||||
}
|
||||
}
|
||||
for (SpanEventBo spanEventBo : spanEventBoList) {
|
||||
SpanBo spanBo = spanMap.get(spanEventBo.getSpanId());
|
||||
final Long spanId = spanEventBo.getSpanId();
|
||||
SpanBo spanBo = spanMap.get(spanId);
|
||||
if (spanBo != null) {
|
||||
spanBo.addSpanEvent(spanEventBo);
|
||||
} else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Span not exist spanId:{} spanEvent:{}", spanEventBo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (annotationMapper != null) {
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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.web.mapper;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.navercorp.pinpoint.common.PinpointConstants;
|
||||
import com.navercorp.pinpoint.common.buffer.Buffer;
|
||||
import com.navercorp.pinpoint.common.buffer.OffsetFixedBuffer;
|
||||
import com.navercorp.pinpoint.common.hbase.HBaseTables;
|
||||
import com.navercorp.pinpoint.common.hbase.RowMapper;
|
||||
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.SpanDecoder;
|
||||
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;
|
||||
import org.apache.hadoop.hbase.client.Result;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
@Beta
|
||||
@Component
|
||||
public class SpanMapperV2 implements RowMapper<List<SpanBo>> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public static final int AGENT_NAME_MAX_LEN = PinpointConstants.AGENT_NAME_MAX_LEN;
|
||||
public static final int DISTRIBUTE_HASH_SIZE = 1;
|
||||
|
||||
private final SpanDecoder spanDecoder = new SpanDecoder();
|
||||
|
||||
|
||||
@Override
|
||||
public List<SpanBo> mapRow(Result result, int rowNum) throws Exception {
|
||||
if (result.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
byte[] rowKey = result.getRow();
|
||||
final TransactionId transactionId = newTransactionId(rowKey, DISTRIBUTE_HASH_SIZE);
|
||||
|
||||
final Cell[] rawCells = result.rawCells();
|
||||
|
||||
final List<Object> out = new ArrayList<>(rawCells.length);
|
||||
final SpanDecodingContext decodingContext = new SpanDecodingContext();
|
||||
decodingContext.setTransactionId(transactionId);
|
||||
|
||||
for (Cell cell : rawCells) {
|
||||
// only if family name is "span"
|
||||
if (CellUtil.matchingFamily(cell, HBaseTables.TRACE_V2_CF_SPAN)) {
|
||||
|
||||
decodingContext.setCollectorAcceptedTime(cell.getTimestamp());
|
||||
|
||||
final Buffer qualifier = new OffsetFixedBuffer(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
|
||||
final Buffer columnValue = new OffsetFixedBuffer(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
|
||||
|
||||
this.spanDecoder.decode(qualifier, columnValue, decodingContext, out);
|
||||
|
||||
} else {
|
||||
logger.warn("Unknown ColumnFamily :{}", Bytes.toStringBinary(CellUtil.cloneFamily(cell)));
|
||||
}
|
||||
this.spanDecoder.next(decodingContext);
|
||||
}
|
||||
this.spanDecoder.finish(decodingContext);
|
||||
|
||||
|
||||
return buildSpanBoList(out);
|
||||
|
||||
}
|
||||
|
||||
private TransactionId newTransactionId(byte[] rowKey, int offset) {
|
||||
|
||||
String agentId = BytesUtils.toStringAndRightTrim(rowKey, offset, AGENT_NAME_MAX_LEN);
|
||||
long agentStartTime = BytesUtils.bytesToLong(rowKey, offset + AGENT_NAME_MAX_LEN);
|
||||
long transactionSequence = BytesUtils.bytesToLong(rowKey, offset + BytesUtils.LONG_BYTE_LENGTH + AGENT_NAME_MAX_LEN);
|
||||
|
||||
return new TransactionId(agentId, agentStartTime, transactionSequence);
|
||||
}
|
||||
|
||||
private List<SpanBo> buildSpanBoList(List<Object> out) {
|
||||
|
||||
LinkedHashMultimap<Long, SpanBo> spanMap = LinkedHashMultimap.create();
|
||||
List<SpanChunkBo> spanChunkList = new ArrayList<>();
|
||||
for (Object decodedSpan : out) {
|
||||
if (decodedSpan instanceof SpanBo) {
|
||||
SpanBo span = (SpanBo) decodedSpan;
|
||||
|
||||
spanMap.put(span.getSpanId(), span);
|
||||
|
||||
} else if (decodedSpan instanceof SpanChunkBo) {
|
||||
|
||||
SpanChunkBo spanChunk = (SpanChunkBo) decodedSpan;
|
||||
spanChunkList.add(spanChunk);
|
||||
} else {
|
||||
|
||||
logger.warn("Unknown span type {}", decodedSpan);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<SpanBo> spanBoList = bindSpanChunk(spanMap, spanChunkList);
|
||||
bindAgentInfo(spanBoList);
|
||||
return spanBoList;
|
||||
}
|
||||
|
||||
private void sortSpanEvent(List<SpanEventBo> spanEventBoList) {
|
||||
if (CollectionUtils.isEmpty(spanEventBoList)) {
|
||||
return;
|
||||
}
|
||||
Collections.sort(spanEventBoList, SpanEncoder.SPAN_EVENT_SEQUENCE_COMPARATOR);
|
||||
}
|
||||
|
||||
private void bindAgentInfo(List<SpanBo> spanBoList) {
|
||||
// TODO workaround. fix class dependency
|
||||
for (SpanBo spanBo : spanBoList) {
|
||||
|
||||
List<SpanEventBo> spanEventBoList = spanBo.getSpanEventBoList();
|
||||
sortSpanEvent(spanEventBoList);
|
||||
for (SpanEventBo spanEventBo : spanEventBoList) {
|
||||
spanEventBo.setAgentId(spanBo.getAgentId());
|
||||
spanEventBo.setApplicationId(spanBo.getApplicationId());
|
||||
spanEventBo.setAgentStartTime(spanBo.getAgentStartTime());
|
||||
|
||||
spanEventBo.setTraceAgentId(spanBo.getTraceAgentId());
|
||||
spanEventBo.setTraceAgentStartTime(spanBo.getTraceAgentStartTime());
|
||||
spanEventBo.setTraceTransactionSequence(spanBo.getTraceTransactionSequence());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<SpanBo> bindSpanChunk(LinkedHashMultimap<Long, SpanBo> spanMap, List<SpanChunkBo> spanChunkList) {
|
||||
for (SpanChunkBo spanChunkBo : spanChunkList) {
|
||||
final Long spanId = spanChunkBo.getSpanId();
|
||||
Set<SpanBo> matchedSpanBoList = spanMap.get(spanId);
|
||||
if (matchedSpanBoList != null) {
|
||||
final int spanIdCollisionSize = matchedSpanBoList.size();
|
||||
if (spanIdCollisionSize > 1) {
|
||||
// exceptional case dump
|
||||
logger.warn("spanIdCollision {}", matchedSpanBoList);
|
||||
}
|
||||
|
||||
int agentLevelCollisionCount = 0;
|
||||
for (SpanBo spanBo : matchedSpanBoList) {
|
||||
if (StringUtils.equals(spanBo.getAgentId(), spanChunkBo.getAgentId())) {
|
||||
spanBo.addSpanEventBoList(spanChunkBo.getSpanEventBoList());
|
||||
agentLevelCollisionCount++;
|
||||
}
|
||||
}
|
||||
if (agentLevelCollisionCount > 1) {
|
||||
// exceptional case dump
|
||||
logger.warn("agentLevelCollision {}", matchedSpanBoList);
|
||||
}
|
||||
} else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Span not exist spanId:{} spanChunk:{}", spanId, spanChunkBo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Lists.newArrayList(spanMap.values());
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
@@ -71,6 +72,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
|
||||
private AgentInfoService agentInfoService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.navercorp.pinpoint.web.vo.scatter.Dot;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -48,6 +49,7 @@ public class ScatterChartServiceImpl implements ScatterChartService {
|
||||
private ApplicationTraceIndexDao applicationTraceIndexDao;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,10 +43,12 @@ import com.navercorp.pinpoint.web.security.MetaDataFilter;
|
||||
import com.navercorp.pinpoint.web.security.MetaDataFilter.MetaData;
|
||||
import com.navercorp.pinpoint.web.vo.TransactionId;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
@@ -59,6 +61,7 @@ public class SpanServiceImpl implements SpanService {
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
// @Autowired
|
||||
@@ -83,7 +86,7 @@ public class SpanServiceImpl implements SpanService {
|
||||
}
|
||||
|
||||
final List<SpanBo> spans = traceDao.selectSpanAndAnnotation(transactionId);
|
||||
if (spans == null || spans.isEmpty()) {
|
||||
if (CollectionUtils.isEmpty(spans)) {
|
||||
return new SpanResult(SpanAligner2.FAIL_MATCH, new CallTreeIterator(null));
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.navercorp.pinpoint.web.vo.callstacks.RecordSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
@@ -57,6 +58,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
@Qualifier("hbaseTraceDaoFactory")
|
||||
private TraceDao traceDao;
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.navercorp.pinpoint.web.util;
|
||||
|
||||
import org.apache.hadoop.hbase.Cell;
|
||||
import org.apache.hadoop.hbase.CellUtil;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public interface CellTracker {
|
||||
|
||||
void trace(Cell cell);
|
||||
|
||||
void log();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.navercorp.pinpoint.web.util;
|
||||
|
||||
import org.apache.hadoop.hbase.Cell;
|
||||
import org.apache.hadoop.hbase.CellUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class DefaultCellTracker implements CellTracker {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final String message;
|
||||
|
||||
private int serializedSize = 0;
|
||||
private int serializedKeySize = 0;
|
||||
private int cellCount = 0;
|
||||
|
||||
public DefaultCellTracker(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Cell cell) {
|
||||
this.serializedSize += CellUtil.estimatedSerializedSizeOf(cell);
|
||||
this.serializedKeySize += CellUtil.estimatedSerializedSizeOfKey(cell);
|
||||
this.cellCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log() {
|
||||
final int nonKey = serializedSize - serializedKeySize;
|
||||
logger.debug("{} cellCount:{} serializedSize:{} key:{} nonKey:{}", message, cellCount, serializedSize, serializedKeySize, nonKey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.navercorp.pinpoint.web.util;
|
||||
|
||||
import org.apache.hadoop.hbase.Cell;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public final class EmptyCellTracker implements CellTracker {
|
||||
|
||||
public static final EmptyCellTracker EMPTY_CELL_TRACER = new EmptyCellTracker();
|
||||
|
||||
private EmptyCellTracker() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Cell cell) {
|
||||
// skip
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log() {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,15 @@
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="traceV2Distributor" class="com.sematext.hbase.wd.RowKeyDistributorByHashPrefix">
|
||||
<constructor-arg ref="traceV2Hasher"/>
|
||||
</bean>
|
||||
|
||||
<bean id="traceV2Hasher" class="com.navercorp.pinpoint.common.hbase.distributor.RangeOneByteSimpleHash">
|
||||
<constructor-arg type="int" value="32"/>
|
||||
<constructor-arg type="int" value="40"/>
|
||||
<constructor-arg type="int" value="256"/>
|
||||
</bean>
|
||||
|
||||
<bean id="agentStatRowKeyDistributor" class="com.sematext.hbase.wd.RowKeyDistributorByHashPrefix">
|
||||
<constructor-arg ref="agentStatRangeHasher"/>
|
||||
|
||||
@@ -34,4 +34,8 @@ config.openSource=true
|
||||
web.hbase.selectSpans.limit=500
|
||||
web.hbase.selectAllSpans.limit=500
|
||||
|
||||
web.activethread.activeAgent.duration.days=7
|
||||
web.activethread.activeAgent.duration.days=7
|
||||
|
||||
# span.binary format compatibility = v1 or v2 (WARNING : experimental feature)
|
||||
# experimental feature span format v2 : https://github.com/naver/pinpoint/issues/1819
|
||||
web.experimental.span.format.compatibility.version=v1
|
||||
@@ -44,7 +44,7 @@ public class LinkFilterTest {
|
||||
|
||||
fromSpanBo.setServiceType(tomcatServiceType);
|
||||
fromSpanBo.setAgentId("AGENT_A");
|
||||
fromSpanBo.setSpanID(100);
|
||||
fromSpanBo.setSpanId(100);
|
||||
|
||||
SpanBo toSpanBO = new SpanBo();
|
||||
toSpanBO.setApplicationId("APP_B");
|
||||
@@ -86,7 +86,7 @@ public class LinkFilterTest {
|
||||
|
||||
fromSpanBo.setServiceType(tomcatServiceType);
|
||||
fromSpanBo.setAgentId("AGENT_A");
|
||||
fromSpanBo.setSpanID(100);
|
||||
fromSpanBo.setSpanId(100);
|
||||
|
||||
SpanBo toSpanBO = new SpanBo();
|
||||
toSpanBO.setApplicationId("APP_B");
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.navercorp.pinpoint.web.mapper;
|
||||
|
||||
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;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.SpanEventBo;
|
||||
import com.navercorp.pinpoint.common.server.bo.serializer.trace.v2.SpanDecoder;
|
||||
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.server.bo.serializer.trace.v2.SpanEncodingContext;
|
||||
import com.navercorp.pinpoint.common.util.AnnotationTranscoder;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Woonduk Kang(emeroad)
|
||||
*/
|
||||
public class SpanMapperV2Test {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final AnnotationTranscoder transcoder = new AnnotationTranscoder();
|
||||
private final SpanDecoder decoder = new SpanDecoder();
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
SpanBo span = new SpanBo();
|
||||
span.setServiceType((short) 1000);
|
||||
span.setExceptionInfo(1, "spanException");
|
||||
|
||||
SpanEventBo firstSpanEventBo = new SpanEventBo();
|
||||
firstSpanEventBo.setExceptionInfo(2, "first");
|
||||
firstSpanEventBo.setEndElapsed(100);
|
||||
|
||||
AnnotationBo annotationBo = newAnnotation(200, "annotation");
|
||||
firstSpanEventBo.setAnnotationBoList(Lists.<AnnotationBo>newArrayList(annotationBo));
|
||||
firstSpanEventBo.setServiceType((short) 1003);
|
||||
firstSpanEventBo.setSequence((short) 0);
|
||||
|
||||
span.addSpanEvent(firstSpanEventBo);
|
||||
|
||||
//// next
|
||||
SpanEventBo nextSpanEventBo = new SpanEventBo();
|
||||
nextSpanEventBo.setEndElapsed(200);
|
||||
nextSpanEventBo.setServiceType((short) 2003);
|
||||
nextSpanEventBo.setSequence((short) 1);
|
||||
|
||||
|
||||
span.addSpanEvent(nextSpanEventBo);
|
||||
|
||||
SpanEncodingContext<SpanBo> encodingContext = new SpanEncodingContext<>(span);
|
||||
SpanEncoder encoder = new SpanEncoder();
|
||||
ByteBuffer byteBuffer = encoder.encodeSpanColumnValue(encodingContext);
|
||||
|
||||
Buffer buffer = new OffsetFixedBuffer(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.remaining());
|
||||
|
||||
SpanBo readSpan = new SpanBo();
|
||||
SpanDecodingContext decodingContext = new SpanDecodingContext();
|
||||
decoder.readSpanValue(buffer, readSpan, new SpanEventBo(), decodingContext);
|
||||
|
||||
Assert.assertEquals(readSpan.getSpanEventBoList().size(), 2);
|
||||
|
||||
|
||||
// span
|
||||
Assert.assertEquals(readSpan.getServiceType(), 1000);
|
||||
Assert.assertEquals(readSpan.hasException(), true);
|
||||
Assert.assertEquals(readSpan.getExceptionId(), 1);
|
||||
Assert.assertEquals(readSpan.getExceptionMessage(), "spanException");
|
||||
|
||||
List<SpanEventBo> spanEventBoList = readSpan.getSpanEventBoList();
|
||||
SpanEventBo readFirst = spanEventBoList.get(0);
|
||||
SpanEventBo readNext = spanEventBoList.get(1);
|
||||
|
||||
Assert.assertEquals(readFirst.getEndElapsed(), 100);
|
||||
Assert.assertEquals(readNext.getEndElapsed(), 200);
|
||||
|
||||
Assert.assertEquals(readFirst.getExceptionId(), 2);
|
||||
Assert.assertEquals(readNext.hasException(), false);
|
||||
|
||||
Assert.assertEquals(readFirst.getServiceType(), 1003);
|
||||
Assert.assertEquals(readNext.getServiceType(), 2003);
|
||||
|
||||
Assert.assertEquals(readFirst.getSequence(), 0);
|
||||
Assert.assertEquals(readNext.getSequence(), 1);
|
||||
|
||||
}
|
||||
|
||||
private AnnotationBo newAnnotation(int key, Object value) {
|
||||
AnnotationBo annotationBo = new AnnotationBo();
|
||||
annotationBo.setKey(key);
|
||||
|
||||
byte typeCode = transcoder.getTypeCode(value);
|
||||
byte[] encode = transcoder.encode(value, typeCode);
|
||||
annotationBo.setValue(value);
|
||||
annotationBo.setByteValue(encode);
|
||||
return annotationBo;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user