From bd73b73bb9ab87b99d5df1de0ea3c2d16851018a Mon Sep 17 00:00:00 2001 From: Woonduk Kang Date: Wed, 12 Jun 2013 10:20:25 +0000 Subject: [PATCH] =?UTF-8?q?[=EA=B0=95=EC=9A=B4=EB=8D=95]=20[LUCYSUS-1744]?= =?UTF-8?q?=20Metadata=EB=A5=BC=20=EC=B0=BE=EB=8A=94=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0.=20agentId=20+=20agentStart=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=EC=9D=84=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9C=A0=EB=8B=88=ED=81=AC=ED=95=98=EA=B2=8C=20MetaData?= =?UTF-8?q?=EB=A5=BC=20=EC=A7=91=EC=96=B4=EC=98=A4=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@1871 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../web/controller/MainController.java | 2 +- .../nhn/pinpoint/web/dao/AgentInfoDao.java | 4 ++ .../web/dao/hbase/HbaseAgentInfoDao.java | 33 +++++++++-- .../pinpoint/web/mapper/AgentInfoMapper.java | 57 +++++++++++++++++++ .../pinpoint/web/service/SpanServiceImpl.java | 25 ++++---- .../web/dao/hbase/HbaseAgentInfoDaoTest.java | 6 +- 6 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/nhn/pinpoint/web/mapper/AgentInfoMapper.java diff --git a/src/main/java/com/nhn/pinpoint/web/controller/MainController.java b/src/main/java/com/nhn/pinpoint/web/controller/MainController.java index 24c5d3fbf..40a1bc474 100644 --- a/src/main/java/com/nhn/pinpoint/web/controller/MainController.java +++ b/src/main/java/com/nhn/pinpoint/web/controller/MainController.java @@ -47,7 +47,7 @@ public class MainController { public String agentStatus(Model model, HttpServletResponse response, @RequestParam("agentId") String agentId) { AgentInfoBo agentInfo = monitor.getAgentInfo(agentId); - long gap = System.currentTimeMillis() - agentInfo.getTimestamp(); + long gap = System.currentTimeMillis() - agentInfo.getStartTime(); model.addAttribute("gap", gap); model.addAttribute("agentinfo", agentInfo); diff --git a/src/main/java/com/nhn/pinpoint/web/dao/AgentInfoDao.java b/src/main/java/com/nhn/pinpoint/web/dao/AgentInfoDao.java index 31d3637da..9249c3efc 100644 --- a/src/main/java/com/nhn/pinpoint/web/dao/AgentInfoDao.java +++ b/src/main/java/com/nhn/pinpoint/web/dao/AgentInfoDao.java @@ -2,10 +2,14 @@ package com.nhn.pinpoint.web.dao; import com.nhn.pinpoint.common.bo.AgentInfoBo; +import java.util.List; + /** * */ public interface AgentInfoDao { AgentInfoBo findAgentInfoBeforeStartTime(String agentId, long currentTime); + + List getAgentInfo(String agentId, long startTime); } diff --git a/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java b/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java index 21022e778..3e38de094 100644 --- a/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java +++ b/src/main/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDao.java @@ -4,20 +4,22 @@ import com.nhn.pinpoint.common.bo.AgentInfoBo; import com.nhn.pinpoint.common.util.BytesUtils; import com.nhn.pinpoint.common.util.RowKeyUtils; import com.nhn.pinpoint.common.util.TimeUtils; -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.ResultScanner; -import org.apache.hadoop.hbase.client.Scan; +import com.nhn.pinpoint.web.mapper.AgentInfoMapper; +import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.util.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.hadoop.hbase.ResultsExtractor; +import org.springframework.data.hadoop.hbase.RowMapper; import org.springframework.stereotype.Repository; import com.nhn.pinpoint.web.dao.AgentInfoDao; import com.nhn.pinpoint.common.hbase.HBaseTables; import com.nhn.pinpoint.common.hbase.HbaseOperations2; +import java.util.List; + /** * */ @@ -29,6 +31,29 @@ public class HbaseAgentInfoDao implements AgentInfoDao { @Autowired private HbaseOperations2 hbaseOperations2; + private RowMapper> agentInfoMapper = new AgentInfoMapper(); + + /** + * agentId, startTime을 기반으로 유니크한 AgentInfo를 찾아낸다. + * @param agentId + * @param startTime + * @return + */ + @Override + public List getAgentInfo(final String agentId, final long startTime) { + + byte[] agentIdBytes = Bytes.toBytes(agentId); + long reverseStartTime = TimeUtils.reverseCurrentTimeMillis(startTime); + byte[] rowKey = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, reverseStartTime); + + Get get = new Get(rowKey); + get.addFamily(HBaseTables.AGENTINFO_CF_INFO); + + List agentInfoBoList = hbaseOperations2.get(HBaseTables.AGENTINFO, get, agentInfoMapper); + + return agentInfoBoList; + } + /** * currentTime에서 가장 근접한 시간의 agent startTime을 find한다. * @@ -53,7 +78,7 @@ public class HbaseAgentInfoDao implements AgentInfoDao { byte[] value = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER); AgentInfoBo agentInfoBo = new AgentInfoBo(); agentInfoBo.setAgentId(agentId); - agentInfoBo.setTimestamp(startTime); + agentInfoBo.setStartTime(startTime); agentInfoBo.readValue(value); logger.debug("agent:{} startTime find {}", agentId, startTime); diff --git a/src/main/java/com/nhn/pinpoint/web/mapper/AgentInfoMapper.java b/src/main/java/com/nhn/pinpoint/web/mapper/AgentInfoMapper.java new file mode 100644 index 000000000..08b5e786c --- /dev/null +++ b/src/main/java/com/nhn/pinpoint/web/mapper/AgentInfoMapper.java @@ -0,0 +1,57 @@ +package com.nhn.pinpoint.web.mapper; + +import com.nhn.pinpoint.common.bo.AgentInfoBo; +import com.nhn.pinpoint.common.hbase.HBaseTables; +import com.nhn.pinpoint.common.util.BytesUtils; +import com.nhn.pinpoint.common.util.TimeUtils; +import org.apache.hadoop.hbase.KeyValue; +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.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +@Component +public class AgentInfoMapper implements RowMapper> { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public List mapRow(Result result, int rowNum) throws Exception { + KeyValue[] raw = result.raw(); + + List agentInfoBoList = new ArrayList(raw.length); + for (int i = 0; i < raw.length; i++) { + KeyValue keyValue = raw[i]; + AgentInfoBo agentInfoBo = mappingAgentInfo(keyValue); + + agentInfoBoList.add(agentInfoBo); + } + + return agentInfoBoList; + } + + private AgentInfoBo mappingAgentInfo(KeyValue keyValue) { + AgentInfoBo agentInfoBo = new AgentInfoBo(); + agentInfoBo.readValue(keyValue.getValue()); + + byte[] rowKey = keyValue.getRow(); + String agentId = Bytes.toString(rowKey, 0, HBaseTables.AGENT_NAME_MAX_LEN - 1).trim(); + agentInfoBo.setAgentId(agentId); + + long reverseStartTime = BytesUtils.bytesToLong(rowKey, HBaseTables.AGENT_NAME_MAX_LEN); + long startTime = TimeUtils.recoveryCurrentTimeMillis(reverseStartTime); + agentInfoBo.setStartTime(startTime); + + logger.debug("agentInfo:{}", agentInfoBo); + + return agentInfoBo; + } +} 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 48a8a0df2..893bcf7fd 100644 --- a/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java +++ b/src/main/java/com/nhn/pinpoint/web/service/SpanServiceImpl.java @@ -91,7 +91,7 @@ public class SpanServiceImpl implements SpanService { AgentInfoBo agentInfoBo = null; try { - agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); + agentInfoBo = getAgentInfoBo(spanAlign); logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); } catch (AgentIdNotFoundException ex) { AnnotationBo agentInfoNotFound = new AnnotationBo(); @@ -104,7 +104,7 @@ public class SpanServiceImpl implements SpanService { // TODO 일단 시간까지 조회는 하지 말고 하자. // 미리 sqlMetaDataList를 indentifier로 필터치는 로직이 더 좋을것으로 생각됨. int hashCode = (Integer) sqlIdAnnotation.getValue(); - List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentInfoBo.getAgentId(), hashCode, agentInfoBo.getTimestamp()); + List sqlMetaDataList = sqlMetaDataDao.getSqlMetaData(agentInfoBo.getAgentId(), hashCode, agentInfoBo.getStartTime()); int size = sqlMetaDataList.size(); if (size == 0) { AnnotationBo api = new AnnotationBo(); @@ -208,7 +208,7 @@ public class SpanServiceImpl implements SpanService { AgentInfoBo agentInfoBo = null; try { - agentInfoBo = findAgentInfoBoBeforeStartTime(spanAlign); + agentInfoBo = getAgentInfoBo(spanAlign); logger.info("{} Agent StartTime found:{}", agentInfoBo.getAgentId(), agentInfoBo); } catch (AgentIdNotFoundException ex) { AnnotationBo agentInfoNotFound = new AnnotationBo(); @@ -219,7 +219,8 @@ public class SpanServiceImpl implements SpanService { } int apiId = (Integer) apiIdAnnotation.getValue(); - List apiMetaDataList = apiMetaDataDao.getApiMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), apiId, agentInfoBo.getTimestamp()); + // agentIdentifer를 기준으로 좀더 정확한 데이터를 찾을수 있을 듯 하다. + List apiMetaDataList = apiMetaDataDao.getApiMetaData(agentInfoBo.getAgentId(), agentInfoBo.getIdentifier(), apiId, agentInfoBo.getStartTime()); int size = apiMetaDataList.size(); if (size == 0) { AnnotationBo api = new AnnotationBo(); @@ -251,14 +252,18 @@ public class SpanServiceImpl implements SpanService { }); } - private AgentInfoBo findAgentInfoBoBeforeStartTime(SpanAlign spanAlign) { + private AgentInfoBo getAgentInfoBo(SpanAlign spanAlign) { String agentId = getAgentId(spanAlign); - long startTime = spanAlign.getSpanBo().getStartTime(); - AgentInfoBo agentInfoBeforeStartTime = agentInfoDao.findAgentInfoBeforeStartTime(agentId, startTime); - if (agentInfoBeforeStartTime == null) { - throw new AgentIdNotFoundException(agentId, startTime); + long agentStartTime = spanAlign.getSpanBo().getAgentStartTime(); + + List agentInfoBo = agentInfoDao.getAgentInfo(agentId, agentStartTime); + if (agentInfoBo == null || agentInfoBo.size() == 0) { + throw new AgentIdNotFoundException(agentId, agentStartTime); } - return agentInfoBeforeStartTime; + // 현재는 qualifier에 고정된 상수를 집어 넣으므로 한상 1개 만존재하므로 0으로 검색하면 된다. + // span에는 identifier가 없고, + // 만약 2개 이상의 starttime을 가진 agentInfo가 존재한다면 동시에 같은 id를 가진 agent가 스타트된것을 확인하는 정도의 기능이 가능한다. + return agentInfoBo.get(0); } private String collisionApiDidMessage(int apidId, List apiMetaDataList) { diff --git a/src/test/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDaoTest.java b/src/test/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDaoTest.java index 7d7c48605..8b328007d 100644 --- a/src/test/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDaoTest.java +++ b/src/test/java/com/nhn/pinpoint/web/dao/hbase/HbaseAgentInfoDaoTest.java @@ -35,13 +35,13 @@ public class HbaseAgentInfoDaoTest { insertDao.insert(agentInfo3); AgentInfoBo testcaseAgent1 = selectDao.findAgentInfoBeforeStartTime("testcaseAgent", 20005); - Assert.assertEquals(testcaseAgent1.getTimestamp(), 20000); + Assert.assertEquals(testcaseAgent1.getStartTime(), 20000); AgentInfoBo testcaseAgent2 = selectDao.findAgentInfoBeforeStartTime("testcaseAgent", 10004); - Assert.assertEquals(testcaseAgent2.getTimestamp(), 10000); + Assert.assertEquals(testcaseAgent2.getStartTime(), 10000); AgentInfoBo testcaseAgent3 = selectDao.findAgentInfoBeforeStartTime("testcaseAgent", 50000); - Assert.assertEquals(testcaseAgent3.getTimestamp(), 30000); + Assert.assertEquals(testcaseAgent3.getStartTime(), 30000); }