From 00d208fdea0f20f8e932f4c6295c25e403955cf0 Mon Sep 17 00:00:00 2001 From: emeroad Date: Wed, 22 Jun 2016 18:24:15 +0900 Subject: [PATCH] #1819 extract deserializer - reduce array copy --- .../collector/dao/hbase/HbaseTraceDao.java | 8 +- .../common/server/bo/AnnotationBoDecoder.java | 57 ++++++++ .../common/server/bo/AnnotationBoList.java | 4 +- .../pinpoint/common/server/bo/SpanBo.java | 11 +- .../common/server/bo/SpanEventBo.java | 12 +- .../bo/serializer/AnnotationSerializer.java | 14 +- .../bo/serializer/SpanEventSerializer.java | 29 ++-- .../server/bo/serializer/SpanSerializer.java | 21 +-- .../common/server/bo/AnnotationBoTest.java | 24 ++-- .../common/server/bo/SpanEventBoTest.java | 13 +- .../server/bo/serializer/SpanBoTest.java | 26 ++-- commons-server/src/test/resources/log4j.xml | 33 +++++ .../pinpoint/common/util/BytesUtils.java | 3 +- .../pinpoint/web/mapper/AnnotationMapper.java | 20 +-- .../pinpoint/web/mapper/SpanMapper.java | 125 ++++++++++++++++-- 15 files changed, 305 insertions(+), 95 deletions(-) create mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java create mode 100644 commons-server/src/test/resources/log4j.xml diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java index 69f6b062a561..ae78db22d672 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseTraceDao.java @@ -79,8 +79,11 @@ public void insert(final TSpan span) { final SpanBo spanBo = new SpanBo(span); + long acceptedTime = acceptedTimeService.getAcceptedTime(); + spanBo.setCollectorAcceptTime(acceptedTime); + final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(span)); - final Put put = new Put(rowKey); + final Put put = new Put(rowKey, acceptedTime); this.spanSerializer.serialize(spanBo, put, null); this.annotationSerializer.serialize(spanBo, put, null); @@ -114,7 +117,8 @@ private void addNestedSpanEvent(Put put, TSpan span) { @Override public void insertSpanChunk(TSpanChunk spanChunk) { final byte[] rowKey = getDistributeRowKey(SpanUtils.getTransactionId(spanChunk)); - final Put put = new Put(rowKey); + final long acceptedTime = acceptedTimeService.getAcceptedTime(); + final Put put = new Put(rowKey, acceptedTime); final List spanEventBoList = spanChunk.getSpanEventList(); if (CollectionUtils.isEmpty(spanEventBoList)) { diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java new file mode 100644 index 000000000000..af8397fa2d2f --- /dev/null +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoDecoder.java @@ -0,0 +1,57 @@ +package com.navercorp.pinpoint.common.server.bo; + +import com.navercorp.pinpoint.common.buffer.Buffer; +import com.navercorp.pinpoint.common.util.AnnotationTranscoder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Woonduk Kang(emeroad) + */ +public class AnnotationBoDecoder { + + private final AnnotationTranscoder transcoder = new AnnotationTranscoder(); + + + public List decode(Buffer buffer) { + + final int size = buffer.readVInt(); + if (size == 0) { + // don' fix return Collections.emptyList(); + // exist outer add method + return new ArrayList<>(); + } + + List annotationBoList = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + + AnnotationBo annotation = decodeAnnotation(buffer); + annotationBoList.add(annotation); + + } + + return annotationBoList; + } + + + public AnnotationBo decodeAnnotation(Buffer buffer) { + + final AnnotationBo annotation = new AnnotationBo(); + + annotation.setVersion(buffer.readByte()); + annotation.setKey(buffer.readSVInt()); + + byte valueType = buffer.readByte(); + annotation.setValueType(valueType); + + byte[] byteValue = buffer.readPrefixedBytes(); + annotation.setByteValue(byteValue); + + Object decodeObject = transcoder.decode(valueType, byteValue); + annotation.setValue(decodeObject); + + return annotation; + } +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java index 21354866346e..066372563b07 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoList.java @@ -25,6 +25,7 @@ /** * @author emeroad */ +@Deprecated public class AnnotationBoList { private List annotationBoList; @@ -40,7 +41,7 @@ public AnnotationBoList(int annotationBoListSize) { public AnnotationBoList(List annotationBoList) { if (annotationBoList == null) { - this.annotationBoList = Collections.emptyList(); + this.annotationBoList = new ArrayList<>(); return; } this.annotationBoList = annotationBoList; @@ -64,6 +65,7 @@ public void writeValue(Buffer writer) { } } + @Deprecated public void readValue(Buffer reader) { int size = reader.readVInt(); if (size == 0) { diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java index 08a7448c749b..a1dd3ecdd3b0 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java @@ -407,7 +407,11 @@ public short getApplicationServiceType() { return this.serviceType; } } - + + /** + * @see com.navercorp.pinpoint.common.trace.LoggingInfo + * @return loggingInfo key + */ public byte getLoggingTransactionInfo() { return loggingTransactionInfo; } @@ -483,9 +487,6 @@ public int readValue(byte[] bytes, int offset, int length) { this.version = buffer.readByte(); - // this.mostTraceID = buffer.readLong(); - // this.leastTraceID = buffer.readLong(); - this.agentId = buffer.readPrefixedString(); this.agentStartTime = buffer.readVLong(); @@ -566,4 +567,4 @@ public String toString() { sb.append('}'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java index 4327f00c1558..02f921d09b7c 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java @@ -394,6 +394,13 @@ public String getExceptionClass() { return exceptionClass; } + public void setExceptionInfo(int exceptionId, String exceptionMessage) { + this.hasException = true; + this.exceptionId = exceptionId; + this.exceptionMessage = exceptionMessage; + } + + public void setExceptionClass(String exceptionClass) { this.exceptionClass = exceptionClass; } @@ -461,6 +468,7 @@ public byte[] writeValue() { return buffer.getBuffer(); } + @Deprecated private void writeAnnotation(Buffer buffer) { AnnotationBoList annotationBo = new AnnotationBoList(this.annotationBoList); annotationBo.writeValue(buffer); @@ -472,9 +480,6 @@ public int readValue(byte[] bytes, int offset, int length) { this.version = buffer.readByte(); - // this.mostTraceID = buffer.readLong(); - // this.leastTraceID = buffer.readLong(); - this.agentId = buffer.readPrefixedString(); this.applicationId = buffer.readPrefixedString(); this.agentStartTime = buffer.readVLong(); @@ -509,6 +514,7 @@ public int readValue(byte[] bytes, int offset, int length) { return buffer.getOffset(); } + @Deprecated private List readAnnotation(Buffer buffer) { AnnotationBoList annotationBoList = new AnnotationBoList(); annotationBoList.readValue(buffer); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/AnnotationSerializer.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/AnnotationSerializer.java index c5f3a1299529..d6590c0e514d 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/AnnotationSerializer.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/AnnotationSerializer.java @@ -9,6 +9,7 @@ import org.apache.hadoop.hbase.util.Bytes; import org.springframework.stereotype.Component; +import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; @@ -26,23 +27,24 @@ public void serialize(SpanBo spanBo, Put put, SerializationContext context) { // TODO if we can identify whether the columnName is duplicated or not, // we can also know whether the span id is duplicated or not. - final byte[] spanId = Bytes.toBytes(spanBo.getSpanId()); + final ByteBuffer spanId = ByteBuffer.wrap(Bytes.toBytes(spanBo.getSpanId())); final List annotations = spanBo.getAnnotationBoList(); if (CollectionUtils.isNotEmpty(annotations)) { - byte[] bytes = writeAnnotationList(annotations); - put.addColumn(TRACES_CF_ANNOTATION, spanId, bytes); + ByteBuffer bytes = writeAnnotationList(annotations); + final long acceptedTime = put.getTimeStamp(); + put.addColumn(TRACES_CF_ANNOTATION, spanId, acceptedTime, bytes); } } - private byte[] writeAnnotationList(List annotationList) { + private ByteBuffer writeAnnotationList(List annotationList) { final Buffer buffer = new AutomaticBuffer(64); return writeAnnotationList(annotationList, buffer); } // for test - public byte[] writeAnnotationList(List annotationList, Buffer buffer) { + public ByteBuffer writeAnnotationList(List annotationList, Buffer buffer) { if (annotationList == null) { annotationList = Collections.emptyList(); @@ -54,7 +56,7 @@ public byte[] writeAnnotationList(List annotationList, Buffer buff writeAnnotation(annotationBo, buffer); } - return buffer.getBuffer(); + return buffer.wrapByteBuffer(); } // for test diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanEventSerializer.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanEventSerializer.java index 60b655d66631..7711a9730c1c 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanEventSerializer.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanEventSerializer.java @@ -5,11 +5,11 @@ 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.util.BytesUtils; import org.apache.hadoop.hbase.client.Put; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.nio.ByteBuffer; import java.util.List; import static com.navercorp.pinpoint.common.hbase.HBaseTables.TRACES_CF_TERMINALSPAN; @@ -22,31 +22,34 @@ public class SpanEventSerializer implements HbaseSerializer { private AnnotationSerializer annotationSerializer; - private AcceptedTimeService acceptedTimeService; - @Autowired public void setAnnotationSerializer(AnnotationSerializer annotationSerializer) { this.annotationSerializer = annotationSerializer; } - @Autowired - public void setAcceptedTimeService(AcceptedTimeService acceptedTimeService) { - this.acceptedTimeService = acceptedTimeService; - } - @Override public void serialize(SpanEventBo spanEventBo, Put put, SerializationContext context) { - byte[] rowId = BytesUtils.add(spanEventBo.getSpanId(), spanEventBo.getSequence(), spanEventBo.getAsyncId(), spanEventBo.getAsyncSequence()); + ByteBuffer rowId = writeQualifier(spanEventBo); - final byte[] value = writeValue(spanEventBo); - final long acceptedTime = acceptedTimeService.getAcceptedTime(); + final ByteBuffer value = writeValue(spanEventBo); + + final long acceptedTime = put.getTimeStamp(); put.addColumn(TRACES_CF_TERMINALSPAN, rowId, acceptedTime, value); } - public byte[] writeValue(SpanEventBo spanEventBo) { + private ByteBuffer writeQualifier(SpanEventBo spanEventBo) { + final Buffer rowId = new AutomaticBuffer(); + rowId.putLong(spanEventBo.getSpanId()); + rowId.putShort(spanEventBo.getSequence()); + rowId.putInt(spanEventBo.getAsyncId()); + rowId.putShort(spanEventBo.getAsyncSequence()); + return rowId.wrapByteBuffer(); + } + + public ByteBuffer writeValue(SpanEventBo spanEventBo) { final Buffer buffer = new AutomaticBuffer(512); buffer.putByte(spanEventBo.getVersion()); @@ -82,7 +85,7 @@ public byte[] writeValue(SpanEventBo spanEventBo) { buffer.putSVInt(spanEventBo.getNextAsyncId()); - return buffer.getBuffer(); + return buffer.wrapByteBuffer(); } } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanSerializer.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanSerializer.java index 42b1e84a520e..6b75b1431d46 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanSerializer.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanSerializer.java @@ -3,12 +3,12 @@ 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.util.AcceptedTimeService; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.util.Bytes; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.nio.ByteBuffer; + import static com.navercorp.pinpoint.common.hbase.HBaseTables.TRACES_CF_SPAN; /** * @author Woonduk Kang(emeroad) @@ -16,29 +16,22 @@ @Component public class SpanSerializer implements HbaseSerializer { - private AcceptedTimeService acceptedTimeService; - - @Autowired - public void setAcceptedTimeService(AcceptedTimeService acceptedTimeService) { - this.acceptedTimeService = acceptedTimeService; - } - @Override public void serialize(SpanBo spanBo, Put put, SerializationContext context) { - byte[] columnValue = writeColumnValue(spanBo); + ByteBuffer columnValue = writeColumnValue(spanBo); // TODO if we can identify whether the columnName is duplicated or not, // we can also know whether the span id is duplicated or not. - byte[] spanId = Bytes.toBytes(spanBo.getSpanId()); + ByteBuffer spanId = ByteBuffer.wrap(Bytes.toBytes(spanBo.getSpanId())); - long acceptedTime = acceptedTimeService.getAcceptedTime(); + long acceptedTime = put.getTimeStamp(); put.addColumn(TRACES_CF_SPAN, spanId, acceptedTime, columnValue); } // Variable encoding has been added in case of write io operation. The data size can be reduced by about 10%. - public byte[] writeColumnValue(SpanBo span) { + public ByteBuffer writeColumnValue(SpanBo span) { /* It is difficult to calculate the size of buffer. It's not impossible. However just use automatic incremental buffer for convenience's sake. @@ -92,6 +85,6 @@ public byte[] writeColumnValue(SpanBo span) { buffer.putByte(span.getLoggingTransactionInfo()); buffer.putPrefixedString(span.getAcceptorHost()); - return buffer.getBuffer(); + return buffer.wrapByteBuffer(); } } diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoTest.java index a18987757263..0126aaddf7d3 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoTest.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/AnnotationBoTest.java @@ -39,17 +39,10 @@ public class AnnotationBoTest { private AnnotationSerializer serializer = new AnnotationSerializer(); - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Test - public void testGetVersion() throws Exception { - - } + private AnnotationBoDecoder annotationBoDecoder = new AnnotationBoDecoder(); - @Test - public void testSetVersion() throws Exception { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); - } @Test public void testWriteValue() throws Exception { @@ -75,6 +68,19 @@ public void testWriteValue() throws Exception { Assert.assertEquals(annotation.getKey(), bo2.getKey()); Assert.assertEquals(annotation.getValueType(), bo2.getValueType()); Assert.assertArrayEquals(annotation.getByteValue(), bo2.getByteValue()); + + buffer.setOffset(0); + AnnotationBo decodedAnnotation = annotationBoDecoder.decodeAnnotation(buffer); + Assert.assertEquals(annotation.getKey(), decodedAnnotation.getKey()); + Assert.assertEquals(annotation.getValueType(), decodedAnnotation.getValueType()); + Assert.assertArrayEquals(annotation.getByteValue(), decodedAnnotation.getByteValue()); + + int i = 256<<1; + System.out.println(i); + i = i<<2; + System.out.println(i); + i = i<<2; + System.out.println(i); } diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java index 3bb5dadffa36..d817b2019d56 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/SpanEventBoTest.java @@ -23,7 +23,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; + +import java.nio.ByteBuffer; /** * @author emeroad @@ -60,13 +61,13 @@ public void testSerialize() throws Exception { spanEventBo.setStartElapsed(100); spanEventBo.setNextAsyncId(1000); - byte[] deprecatedBytes = spanEventBo.writeValue(); - byte[] bytes = serializer.writeValue(spanEventBo); - Assert.assertArrayEquals(bytes, deprecatedBytes); + ByteBuffer deprecatedBytes = ByteBuffer.wrap(spanEventBo.writeValue()); + ByteBuffer bytes = serializer.writeValue(spanEventBo); + Assert.assertEquals(bytes, deprecatedBytes); SpanEventBo newSpanEventBo = new SpanEventBo(); - int i = newSpanEventBo.readValue(bytes, 0, bytes.length); - Assert.assertEquals(bytes.length, i); + int i = newSpanEventBo.readValue(bytes.array(), bytes.arrayOffset(), bytes.remaining()); + Assert.assertEquals(bytes.limit(), i); Assert.assertEquals(spanEventBo.getAgentId(), newSpanEventBo.getAgentId()); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanBoTest.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanBoTest.java index b67a3c281f83..b515c3c5c72b 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanBoTest.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/serializer/SpanBoTest.java @@ -27,6 +27,8 @@ import com.navercorp.pinpoint.common.trace.ServiceType; +import java.nio.ByteBuffer; + /** * @author emeroad */ @@ -83,16 +85,16 @@ public void serialize_V1() { spanBo.setExceptionInfo(1000, "Exception"); - byte[] bytes = spanSerializer.writeColumnValue(spanBo); - byte[] deprecated = spanBo.writeValue(); + ByteBuffer bytes = spanSerializer.writeColumnValue(spanBo); + ByteBuffer deprecated = ByteBuffer.wrap(spanBo.writeValue()); - logger.debug("length:{}", bytes.length); - Assert.assertArrayEquals(bytes, deprecated); + logger.debug("length:{}", bytes.remaining()); + Assert.assertEquals(bytes, deprecated); SpanBo newSpanBo = new SpanBo(); - int i = newSpanBo.readValue(bytes, 0, bytes.length); + int i = newSpanBo.readValue(bytes.array(), bytes.arrayOffset(), bytes.remaining()); logger.debug("length:{}", i); - Assert.assertEquals(bytes.length, i); + Assert.assertEquals(bytes.limit(), i); Assert.assertEquals(newSpanBo.getAgentId(), spanBo.getAgentId()); Assert.assertEquals(newSpanBo.getApplicationId(), spanBo.getApplicationId()); Assert.assertEquals(newSpanBo.getAgentStartTime(), spanBo.getAgentStartTime()); @@ -134,15 +136,15 @@ public void serialize2_V1() { spanBo.setServiceType(ServiceType.STAND_ALONE.getCode()); spanBo.setApplicationServiceType(ServiceType.UNKNOWN.getCode()); - final byte[] bytes = spanSerializer.writeColumnValue(spanBo); - byte[] deprecated = spanBo.writeValue(); - logger.debug("length:{}", bytes.length); - Assert.assertArrayEquals(bytes, deprecated); + final ByteBuffer bytes = spanSerializer.writeColumnValue(spanBo); + ByteBuffer deprecated = ByteBuffer.wrap(spanBo.writeValue()); + logger.debug("length:{}", bytes.remaining()); + Assert.assertEquals(bytes, deprecated); SpanBo newSpanBo = new SpanBo(); - int i = newSpanBo.readValue(bytes, 0, bytes.length); + int i = newSpanBo.readValue(bytes.array(), bytes.arrayOffset(), bytes.remaining()); logger.debug("length:{}", i); - Assert.assertEquals(bytes.length, i); + Assert.assertEquals(bytes.limit(), i); Assert.assertEquals(spanBo.getServiceType(), spanBo.getServiceType()); Assert.assertEquals(spanBo.getApplicationServiceType(), spanBo.getApplicationServiceType()); diff --git a/commons-server/src/test/resources/log4j.xml b/commons-server/src/test/resources/log4j.xml new file mode 100644 index 000000000000..0550c3380428 --- /dev/null +++ b/commons-server/src/test/resources/log4j.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java index d3cc00008a7b..1ee7749e152d 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/BytesUtils.java @@ -517,7 +517,8 @@ public static byte[] add(final long preFix, final short postFix) { writeShort(postFix, buf, 8); return buf; } - + + @Deprecated public static byte[] add(final long preFix, final short postFix, final int intArg, final short shortArg) { byte[] buf = new byte[LONG_BYTE_LENGTH + SHORT_BYTE_LENGTH + INT_BYTE_LENGTH + SHORT_BYTE_LENGTH]; int offset = 0; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java index edd0ebd436dc..51273921f41d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/AnnotationMapper.java @@ -17,12 +17,13 @@ package com.navercorp.pinpoint.web.mapper; import com.navercorp.pinpoint.common.server.bo.AnnotationBo; -import com.navercorp.pinpoint.common.server.bo.AnnotationBoList; 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.AnnotationBoDecoder; +import org.apache.commons.collections.CollectionUtils; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.client.Result; @@ -40,31 +41,32 @@ public class AnnotationMapper implements RowMapper>> { private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final AnnotationBoDecoder annotationDecoder = new AnnotationBoDecoder(); + @Override public Map> mapRow(Result result, int rowNum) throws Exception { if (result.isEmpty()) { return Collections.emptyMap(); } - Cell[] rawCells = result.rawCells(); + final Cell[] rawCells = result.rawCells(); Map> annotationList = new HashMap<>(); for (Cell cell : rawCells) { - Buffer buffer = new OffsetFixedBuffer(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); + final Buffer buffer = new OffsetFixedBuffer(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); long spanId = buffer.readLong(); if (CellUtil.matchingFamily(cell, HBaseTables.TRACES_CF_ANNOTATION)) { - int valueLength = cell.getValueLength(); + final int valueLength = cell.getValueLength(); if (valueLength == 0) { continue; } buffer.setOffset(cell.getValueOffset()); - AnnotationBoList annotationBoList = new AnnotationBoList(); - annotationBoList.readValue(buffer); - if (annotationBoList.size() > 0 ) { - annotationBoList.setSpanId(spanId); - annotationList.put(spanId, annotationBoList.getAnnotationBoList()); + + List annotationBoList = annotationDecoder.decode(buffer); + if (CollectionUtils.isNotEmpty(annotationBoList)) { + annotationList.put(spanId, annotationBoList); } } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java index 3c9f710465ee..4b92a38ef25e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/SpanMapper.java @@ -16,7 +16,10 @@ package com.navercorp.pinpoint.web.mapper; +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.AnnotationBoDecoder; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.SpanEventBo; import com.navercorp.pinpoint.common.hbase.HBaseTables; @@ -43,6 +46,8 @@ public class SpanMapper implements RowMapper> { private AnnotationMapper annotationMapper; + private final AnnotationBoDecoder annotationBoDecoder = new AnnotationBoDecoder(); + public AnnotationMapper getAnnotationMapper() { return annotationMapper; } @@ -75,7 +80,7 @@ public List mapRow(Result result, int rowNum) throws Exception { spanBo.setCollectorAcceptTime(cell.getTimestamp()); spanBo.setSpanID(Bytes.toLong(cell.getQualifierArray(), cell.getQualifierOffset())); - spanBo.readValue(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); + readSpan(spanBo, cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); if (logger.isDebugEnabled()) { logger.debug("read span :{}", spanBo); } @@ -87,29 +92,25 @@ public List mapRow(Result result, int rowNum) throws Exception { spanEventBo.setTraceAgentStartTime(transactionId.getAgentStartTime()); spanEventBo.setTraceTransactionSequence(transactionId.getTransactionSequence()); - int offset = 0; // qualifier : spanId(long) + sequence(short) + asyncId(int) - long spanId = Bytes.toLong(cell.getQualifierArray(), cell.getQualifierOffset()); + final Buffer qualifier = new OffsetFixedBuffer(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); + long spanId = qualifier.readLong(); - // because above spanId type is "long", so offset is 8 - offset += Bytes.SIZEOF_LONG; - short sequence = Bytes.toShort(cell.getQualifierArray(), cell.getQualifierOffset() + offset); + short sequence = qualifier.readShort(); int asyncId = -1; - offset += Bytes.SIZEOF_SHORT; - if (cell.getQualifierLength() > offset) { - asyncId = Bytes.toInt(cell.getQualifierArray(), cell.getQualifierOffset() + offset); + if (qualifier.hasRemaining()) { + asyncId = qualifier.readInt(); } short asyncSequence = -1; - offset += Bytes.SIZEOF_INT; - if(cell.getQualifierLength() > offset) { - asyncSequence = Bytes.toShort(cell.getQualifierArray(), cell.getQualifierOffset() + offset); + if (qualifier.hasRemaining()) { + asyncSequence = qualifier.readShort(); } spanEventBo.setSpanId(spanId); spanEventBo.setSequence(sequence); spanEventBo.setAsyncId(asyncId); spanEventBo.setAsyncSequence(asyncSequence); - - spanEventBo.readValue(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); + + readSpanEvent(spanEventBo, cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); if (logger.isDebugEnabled()) { logger.debug("read spanEvent :{}", spanEventBo); } @@ -139,4 +140,100 @@ private void addAnnotation(List spanList, Map> bo.setAnnotationBoList(anoList); } } + + // for test + public int readSpanEvent(final SpanEventBo spanEvent, byte[] bytes, int offset, int length) { + final Buffer buffer = new OffsetFixedBuffer(bytes, offset, length); + + spanEvent.setVersion(buffer.readByte()); + + spanEvent.setAgentId(buffer.readPrefixedString()); + spanEvent.setApplicationId(buffer.readPrefixedString()); + spanEvent.setAgentStartTime(buffer.readVLong()); + + spanEvent.setStartElapsed(buffer.readVInt()); + spanEvent.setEndElapsed(buffer.readVInt()); + + // don't need to get sequence because it can be got at Qualifier + // this.sequence = buffer.readShort(); + + + spanEvent.setRpc(buffer.readPrefixedString()); + spanEvent.setServiceType(buffer.readShort()); + spanEvent.setEndPoint(buffer.readPrefixedString()); + spanEvent.setDestinationId(buffer.readPrefixedString()); + spanEvent.setApiId(buffer.readSVInt()); + + spanEvent.setDepth(buffer.readSVInt()); + spanEvent.setNextSpanId(buffer.readLong()); + + final boolean hasException = buffer.readBoolean(); + if (hasException) { + spanEvent.setExceptionInfo(buffer.readSVInt(), buffer.readPrefixedString()); + } + + final List annotationBoList = annotationBoDecoder.decode(buffer); + spanEvent.setAnnotationBoList(annotationBoList); + if (buffer.hasRemaining()) { + spanEvent.setNextAsyncId(buffer.readSVInt()); + } + + return buffer.getOffset(); + } + + // for test + public int readSpan(SpanBo span, byte[] bytes, int offset, int length) { + final Buffer buffer = new OffsetFixedBuffer(bytes, offset, length); + + span.setVersion(buffer.readByte()); + + span.setAgentId(buffer.readPrefixedString()); + span.setAgentStartTime(buffer.readVLong()); + + // this.spanID = buffer.readLong(); + span.setParentSpanId(buffer.readLong()); + + span.setStartTime(buffer.readVLong()); + span.setElapsed(buffer.readVInt()); + + span.setRpc(buffer.readPrefixedString()); + span.setApplicationId(buffer.readPrefixedString()); + span.setServiceType(buffer.readShort()); + span.setEndPoint(buffer.readPrefixedString()); + span.setRemoteAddr(buffer.readPrefixedString()); + span.setApiId(buffer.readSVInt()); + + span.setErrCode(buffer.readSVInt()); + + final boolean hasException = buffer.readBoolean(); + if (hasException) { + int exceptionId = buffer.readSVInt(); + String exceptionMessage = buffer.readPrefixedString(); + span.setExceptionInfo(exceptionId, exceptionMessage); + + } + + span.setFlag(buffer.readShort()); + + // FIXME (2015.03) Legacy - applicationServiceType added in v1.1.0 + // Defaults to span's service type for older versions where applicationServiceType does not exist. + if (buffer.hasRemaining()) { + final boolean hasApplicationServiceType = buffer.readBoolean(); + if (hasApplicationServiceType) { + span.setApplicationServiceType(buffer.readShort()); + } + } + + if (buffer.hasRemaining()) { + span.setLoggingTransactionInfo(buffer.readByte()); + } + + if (buffer.hasRemaining()) { + span.setAcceptorHost(buffer.readPrefixedString()); + } + + return buffer.getOffset(); + } + + }