diff --git a/src/main/java/com/nhn/pinpoint/web/dao/StringMetaDataDao.java b/src/main/java/com/nhn/pinpoint/web/dao/StringMetaDataDao.java new file mode 100644 index 000000000..49c087b20 --- /dev/null +++ b/src/main/java/com/nhn/pinpoint/web/dao/StringMetaDataDao.java @@ -0,0 +1,13 @@ +package com.nhn.pinpoint.web.dao; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; + +import java.util.List; + +/** + * + */ +public interface StringMetaDataDao { + List getStringMetaData(String agentId, int stringId, long time); +} diff --git a/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java b/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java new file mode 100644 index 000000000..eb0e41520 --- /dev/null +++ b/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseStringMetaDataDao.java @@ -0,0 +1,39 @@ +package com.nhn.pinpoint.web.dao.hbase; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import com.nhn.pinpoint.web.dao.StringMetaDataDao; +import org.apache.hadoop.hbase.client.Get; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * + */ +@Repository +public class HbaseStringMetaDataDao implements StringMetaDataDao { + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("stringMetaDataMapper") + private RowMapper> stringMetaDataMapper; + + @Override + public List getStringMetaData(String agentId, int stringId, long time) { + StringMetaDataBo stringMetaData = new StringMetaDataBo(agentId, stringId, time); + byte[] rowKey = stringMetaData.toRowKey(); + + Get get = new Get(rowKey); + get.addFamily(HBaseTables.STRING_METADATA_CF_STR); + + return hbaseOperations2.get(HBaseTables.STRING_METADATA, get, stringMetaDataMapper); + } +} diff --git a/src/main/java/com/nhn/pinpoint/web/mapper/StringMetaDataMapper.java b/src/main/java/com/nhn/pinpoint/web/mapper/StringMetaDataMapper.java new file mode 100644 index 000000000..49e2e3c49 --- /dev/null +++ b/src/main/java/com/nhn/pinpoint/web/mapper/StringMetaDataMapper.java @@ -0,0 +1,35 @@ +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.bo.SqlMetaDataBo; +import com.nhn.pinpoint.common.bo.StringMetaDataBo; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +@Component +public class StringMetaDataMapper implements RowMapper> { + @Override + public List mapRow(Result result, int rowNum) throws Exception { + + byte[] rowKey = result.getRow(); + + List stringMetaDataList = new ArrayList(); + KeyValue[] keyList = result.raw(); + for (KeyValue keyValue : keyList) { + StringMetaDataBo sqlMetaDataBo = new StringMetaDataBo(); + sqlMetaDataBo.readRowKey(rowKey); + String stringValue = Bytes.toString(keyValue.getBuffer(), keyValue.getQualifierOffset(), keyValue.getQualifierLength()); + sqlMetaDataBo.setStringValue(stringValue); + stringMetaDataList.add(sqlMetaDataBo); + } + return stringMetaDataList; + } +} diff --git a/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java b/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java index 8e01579e6..9b72c71c8 100644 --- a/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java +++ b/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import com.nhn.pinpoint.common.bo.*; +import com.nhn.pinpoint.web.dao.StringMetaDataDao; import com.nhn.pinpoint.web.vo.TransactionId; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -38,6 +39,9 @@ public class SpanServiceImpl implements SpanService { @Autowired private ApiMetaDataDao apiMetaDataDao; + @Autowired + private StringMetaDataDao stringMetaDataDao; + private SqlParser sqlParser = new SqlParser(); private OutputParameterParser outputParameterParser = new OutputParameterParser(); @@ -53,12 +57,13 @@ public class SpanServiceImpl implements SpanService { // transitionApiId(order); transitionDynamicApiId(order); transitionSqlId(order); + transitionCachedString(order); // TODO root span not found시 row data라도 보여줘야 됨. return order; } - private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { + private void transitionAnnotation(List spans, AnnotationReplacementCallback annotationReplacementCallback) { for (SpanAlign spanAlign : spans) { List annotationBoList; if (spanAlign.isSpan()) { @@ -186,13 +191,6 @@ public class SpanServiceImpl implements SpanService { return sb.toString(); } - private String getAgentId(SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - return spanAlign.getSpanBo().getAgentId(); - } else { - return spanAlign.getSpanEventBo().getAgentId(); - } - } private void transitionDynamicApiId(List spans) { this.transitionAnnotation(spans, new AnnotationReplacementCallback() { @@ -233,6 +231,55 @@ public class SpanServiceImpl implements SpanService { }); } + private void transitionCachedString(List spans) { + this.transitionAnnotation(spans, new AnnotationReplacementCallback() { + @Override + public void replacement(SpanAlign spanAlign, List annotationBoList) { + final AgentKey key = getAgentKey(spanAlign); + List cachedStringAnnotation = findCachedStringAnnotation(annotationBoList); + if (cachedStringAnnotation.isEmpty()) { + return; + } + for (AnnotationBo annotationBo : cachedStringAnnotation) { + final int cachedArgsKey = annotationBo.getKey(); + int stringMeataDataId = (Integer) annotationBo.getValue(); + List stringMetaList = stringMetaDataDao.getStringMetaData(key.getAgentId(), stringMeataDataId, key.getAgentStartTime()); + int size = stringMetaList.size(); + if (size == 0) { + logger.warn("StringMetaData not Found {}/{}/{}", key.getAgentId(), stringMeataDataId, key.getAgentStartTime()); + AnnotationBo api = new AnnotationBo(); + // API METADATA ERROR가 아님. 추후 수정. + api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode()); + api.setValue("CACHED-STRING-ID not found. stringId:" + cachedArgsKey); + annotationBoList.add(api); + } else if (size >= 1) { + // key 충돌 경우는 후추 처리한다. 실제 상황에서는 일부러 만들지 않는한 발생할수 없다. + StringMetaDataBo stringMetaDataBo = stringMetaList.get(0); + + AnnotationBo stringMetaData = new AnnotationBo(); + stringMetaData.setKey(AnnotationKey.cachedArgsToArgs(cachedArgsKey)); + stringMetaData.setValue(stringMetaDataBo.getStringValue()); + annotationBoList.add(stringMetaData); + if (size > 1) { + logger.warn("stringMetaData size not 1 :{}", stringMetaList); + } + } + } + } + + }); + } + + private List findCachedStringAnnotation(List annotationBoList) { + List findAnnotationBoList = new ArrayList(annotationBoList.size()); + for (AnnotationBo annotationBo : annotationBoList) { + if (AnnotationKey.isCachedArgsKey(annotationBo.getKey())) { + findAnnotationBoList.add(annotationBo); + } + } + return findAnnotationBoList; + } + private int getApiId(SpanAlign spanAlign) { if (spanAlign.isSpan()) { return spanAlign.getSpanBo().getApiId();