/* * 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.service; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.util.TransactionId; import com.navercorp.pinpoint.web.dao.ApplicationTraceIndexDao; import com.navercorp.pinpoint.web.dao.TraceDao; import com.navercorp.pinpoint.web.filter.Filter; import com.navercorp.pinpoint.web.scatter.ScatterData; import com.navercorp.pinpoint.web.vo.Range; import com.navercorp.pinpoint.web.vo.SelectedScatterArea; import com.navercorp.pinpoint.web.vo.TransactionMetadataQuery; 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; import java.util.List; /** * @author netspider * @author emeroad */ @Service public class ScatterChartServiceImpl implements ScatterChartService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private ApplicationTraceIndexDao applicationTraceIndexDao; @Autowired @Qualifier("hbaseTraceDaoFactory") private TraceDao traceDao; @Override public List<Dot> selectScatterData(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit) { if (applicationName == null) { throw new NullPointerException("applicationName must not be null"); } if (area == null) { throw new NullPointerException("area must not be null"); } return applicationTraceIndexDao.scanTraceScatter(applicationName, area, offsetTransactionId, offsetTransactionElapsed, limit); } @Override public List<Dot> selectScatterData(List<TransactionId> transactionIdList, String applicationName, Filter filter) { if (transactionIdList == null) { throw new NullPointerException("transactionIdList must not be null"); } if (applicationName == null) { throw new NullPointerException("applicationName must not be null"); } if (filter == null) { throw new NullPointerException("filter must not be null"); } final List<List<SpanBo>> traceList = traceDao.selectAllSpans(transactionIdList); final List<Dot> result = new ArrayList<>(); for (List<SpanBo> trace : traceList) { if (!filter.include(trace)) { continue; } for (SpanBo span : trace) { if (applicationName.equals(span.getApplicationId())) { final TransactionId transactionId = span.getTransactionId(); final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); result.add(dot); } } } return result; } /** * Queries for details on dots selected from the scatter chart. */ @Override public List<SpanBo> selectTransactionMetadata(final TransactionMetadataQuery query) { if (query == null) { throw new NullPointerException("query must not be null"); } final List<TransactionId> transactionIdList = query.getTransactionIdList(); final List<List<SpanBo>> selectedSpans = traceDao.selectSpans(transactionIdList); final List<SpanBo> result = new ArrayList<>(query.size()); int index = 0; for (List<SpanBo> spans : selectedSpans) { if (spans.isEmpty()) { // span data does not exist in storage - skip } else if (spans.size() == 1) { // case with a single unique span data result.add(spans.get(0)); } else { // for recursive calls, we need to identify which of the spans was selected. // pick only the spans with the same transactionId, collectorAcceptor, and responseTime for (SpanBo span : spans) { // should find the filtering condition with the correct index final TransactionMetadataQuery.QueryCondition filterQueryCondition = query.getQueryConditionByIndex(index); final TransactionId transactionId = span.getTransactionId(); final TransactionMetadataQuery.QueryCondition queryConditionKey = new TransactionMetadataQuery.QueryCondition(transactionId, span.getCollectorAcceptTime(), span.getElapsed()); if (queryConditionKey.equals(filterQueryCondition)) { result.add(span); } } } index++; } return result; } @Override public ScatterData selectScatterData(String applicationName, Range range, int xGroupUnit, int yGroupUnit, int limit, boolean backwardDirection) { if (applicationName == null) { throw new NullPointerException("applicationName must not be null"); } if (range == null) { throw new NullPointerException("range must not be null"); } return applicationTraceIndexDao.scanTraceScatterData(applicationName, range, xGroupUnit, yGroupUnit, limit, backwardDirection); } @Override public ScatterData selectScatterData(List<TransactionId> transactionIdList, String applicationName, Range range, int xGroupUnit, int yGroupUnit, Filter filter) { if (transactionIdList == null) { throw new NullPointerException("transactionIdList must not be null"); } if (applicationName == null) { throw new NullPointerException("applicationName must not be null"); } if (filter == null) { throw new NullPointerException("filter must not be null"); } final List<List<SpanBo>> traceList = traceDao.selectAllSpans(transactionIdList); ScatterData scatterData = new ScatterData(range.getFrom(), range.getTo(), xGroupUnit, yGroupUnit); for (List<SpanBo> trace : traceList) { if (!filter.include(trace)) { continue; } for (SpanBo span : trace) { if (applicationName.equals(span.getApplicationId())) { final TransactionId transactionId = span.getTransactionId(); final Dot dot = new Dot(transactionId, span.getCollectorAcceptTime(), span.getElapsed(), span.getErrCode(), span.getAgentId()); scatterData.addDot(dot); } } } return scatterData; } }