diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanChunkHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanChunkHandler.java index 89d8cc39906a..d20eff34f57e 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanChunkHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanChunkHandler.java @@ -6,6 +6,7 @@ import com.navercorp.pinpoint.collector.service.TraceService; import com.navercorp.pinpoint.common.server.bo.SpanChunkBo; import com.navercorp.pinpoint.common.server.bo.grpc.GrpcSpanFactory; +import com.navercorp.pinpoint.common.util.CollectionUtils; import com.navercorp.pinpoint.grpc.Header; import com.navercorp.pinpoint.grpc.MessageFormatUtils; import com.navercorp.pinpoint.grpc.server.ServerContext; @@ -14,10 +15,11 @@ import com.navercorp.pinpoint.grpc.trace.PTransactionId; import com.navercorp.pinpoint.io.request.ServerRequest; import io.grpc.Status; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -30,13 +32,15 @@ public class GrpcSpanChunkHandler implements SimpleHandler { private final Logger logger = LogManager.getLogger(getClass()); private final boolean isDebug = logger.isDebugEnabled(); - private final TraceService traceService; + private final TraceService[] traceServices; private final GrpcSpanFactory spanFactory; - public GrpcSpanChunkHandler(TraceService traceService, GrpcSpanFactory spanFactory) { - this.traceService = Objects.requireNonNull(traceService, "traceService"); + public GrpcSpanChunkHandler(TraceService[] traceServices, GrpcSpanFactory spanFactory) { + this.traceServices = Objects.requireNonNull(traceServices, "traceServices"); this.spanFactory = Objects.requireNonNull(spanFactory, "spanFactory"); + + logger.info("TraceServices {}", Arrays.toString(traceServices)); } @Override @@ -56,12 +60,15 @@ private void handleSpanChunk(PSpanChunk spanChunk) { logger.debug("Handle PSpanChunk={}", createSimpleSpanChunkLog(spanChunk)); } - try { - final Header agentInfo = ServerContext.getAgentInfo(); - final SpanChunkBo spanChunkBo = spanFactory.buildSpanChunkBo(spanChunk, agentInfo); - this.traceService.insertSpanChunk(spanChunkBo); - } catch (Exception e) { - logger.warn("Failed to handle spanChunk={}", MessageFormatUtils.debugLog(spanChunk), e); + + final Header agentInfo = ServerContext.getAgentInfo(); + final SpanChunkBo spanChunkBo = spanFactory.buildSpanChunkBo(spanChunk, agentInfo); + for (TraceService traceService : traceServices) { + try { + traceService.insertSpanChunk(spanChunkBo); + } catch (Exception e) { + logger.warn("Failed to handle spanChunk={}", MessageFormatUtils.debugLog(spanChunk), e); + } } } @@ -70,7 +77,7 @@ private String createSimpleSpanChunkLog(PSpanChunk spanChunk) { return ""; } - StringBuilder log = new StringBuilder(); + StringBuilder log = new StringBuilder(64); PTransactionId transactionId = spanChunk.getTransactionId(); log.append(" transactionId:"); @@ -78,18 +85,17 @@ private String createSimpleSpanChunkLog(PSpanChunk spanChunk) { log.append(" spanId:").append(spanChunk.getSpanId()); - - StringBuilder spanEventSequenceLog = new StringBuilder(); - List spanEventList = spanChunk.getSpanEventList(); - for (PSpanEvent pSpanEvent : spanEventList) { - if (pSpanEvent == null) { - continue; + final List spanEventList = spanChunk.getSpanEventList(); + if (CollectionUtils.hasLength(spanEventList)) { + log.append(" spanEventSequence:"); + for (PSpanEvent pSpanEvent : spanEventList) { + if (pSpanEvent == null) { + continue; + } + log.append(pSpanEvent.getSequence()).append(" "); } - spanEventSequenceLog.append(pSpanEvent.getSequence()).append(" "); } - log.append(" spanEventSequence:").append(spanEventSequenceLog.toString()); - return log.toString(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanHandler.java index 901dd65be632..bd1bc67bd564 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSpanHandler.java @@ -21,6 +21,7 @@ import com.navercorp.pinpoint.collector.service.TraceService; import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.server.bo.grpc.GrpcSpanFactory; +import com.navercorp.pinpoint.common.util.CollectionUtils; import com.navercorp.pinpoint.grpc.Header; import com.navercorp.pinpoint.grpc.MessageFormatUtils; import com.navercorp.pinpoint.grpc.server.ServerContext; @@ -28,12 +29,12 @@ import com.navercorp.pinpoint.grpc.trace.PSpanEvent; import com.navercorp.pinpoint.grpc.trace.PTransactionId; import com.navercorp.pinpoint.io.request.ServerRequest; - import io.grpc.Status; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -47,13 +48,15 @@ public class GrpcSpanHandler implements SimpleHandler { private final Logger logger = LogManager.getLogger(getClass()); private final boolean isDebug = logger.isDebugEnabled(); - private final TraceService traceService; + private final TraceService[] traceServices; private final GrpcSpanFactory spanFactory; - public GrpcSpanHandler(TraceService traceService, GrpcSpanFactory spanFactory) { - this.traceService = Objects.requireNonNull(traceService, "traceService"); + public GrpcSpanHandler(TraceService[] traceServices, GrpcSpanFactory spanFactory) { + this.traceServices = Objects.requireNonNull(traceServices, "traceServices"); this.spanFactory = Objects.requireNonNull(spanFactory, "spanFactory"); + + logger.info("TraceServices {}", Arrays.toString(traceServices)); } @Override @@ -72,12 +75,14 @@ private void handleSpan(PSpan span) { logger.debug("Handle PSpan={}", createSimpleSpanLog(span)); } - try { - Header agentInfo = ServerContext.getAgentInfo(); - final SpanBo spanBo = spanFactory.buildSpanBo(span, agentInfo); - traceService.insertSpan(spanBo); - } catch (Exception e) { - logger.warn("Failed to handle span={}", MessageFormatUtils.debugLog(span), e); + final Header agentInfo = ServerContext.getAgentInfo(); + final SpanBo spanBo = spanFactory.buildSpanBo(span, agentInfo); + for (TraceService traceService : traceServices) { + try { + traceService.insertSpan(spanBo); + } catch (Throwable e) { + logger.warn("Failed to handle span={}", MessageFormatUtils.debugLog(span), e); + } } } @@ -86,7 +91,7 @@ private String createSimpleSpanLog(PSpan span) { return ""; } - StringBuilder log = new StringBuilder(); + StringBuilder log = new StringBuilder(64); PTransactionId transactionId = span.getTransactionId(); log.append(" transactionId:"); @@ -94,17 +99,17 @@ private String createSimpleSpanLog(PSpan span) { log.append(" spanId:").append(span.getSpanId()); - StringBuilder spanEventSequenceLog = new StringBuilder(); - List spanEventList = span.getSpanEventList(); - for (PSpanEvent pSpanEvent : spanEventList) { - if (pSpanEvent == null) { - continue; + final List spanEventList = span.getSpanEventList(); + if (CollectionUtils.hasLength(spanEventList)) { + log.append(" spanEventSequence:"); + for (PSpanEvent pSpanEvent : spanEventList) { + if (pSpanEvent == null) { + continue; + } + log.append(pSpanEvent.getSequence()).append(" "); } - spanEventSequenceLog.append(pSpanEvent.getSequence()).append(" "); } - log.append(" spanEventSequence:").append(spanEventSequenceLog.toString()); - return log.toString(); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSqlMetaDataHandler.java b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSqlMetaDataHandler.java index e920b9fcb506..d0cb6bfd18d7 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSqlMetaDataHandler.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcSqlMetaDataHandler.java @@ -28,10 +28,11 @@ import com.navercorp.pinpoint.io.request.ServerRequest; import com.navercorp.pinpoint.io.request.ServerResponse; import io.grpc.Status; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.Objects; /** @@ -42,10 +43,11 @@ public class GrpcSqlMetaDataHandler implements RequestResponseHandler spanEventList = spanChunkBo.getSpanEventBoList(); + if (spanEventList != null) { + // TODO need to batch update later. + insertSpanEventList(spanEventList, applicationServiceType, spanChunkBo.getApplicationId(), spanChunkBo.getAgentId(), spanChunkBo.getEndPoint()); + } + } + + private ServiceType getApplicationServiceType(SpanChunkBo spanChunk) { + final short applicationServiceTypeCode = spanChunk.getApplicationServiceType(); + return registry.findServiceType(applicationServiceTypeCode); + } + + @Override + public void insertSpan(final SpanBo spanBo) { + traceDao.insert(spanBo); + applicationTraceIndexDao.insert(spanBo); + insertAcceptorHost(spanBo); + insertSpanStat(spanBo); + insertSpanEventStat(spanBo); + } + + private void insertAcceptorHost(SpanEventBo spanEvent, String applicationId, ServiceType serviceType) { + final String endPoint = spanEvent.getEndPoint(); + if (endPoint == null) { + logger.debug("endPoint is null. spanEvent:{}", spanEvent); + return; + } + final String destinationId = spanEvent.getDestinationId(); + if (destinationId == null) { + logger.debug("destinationId is null. spanEvent:{}", spanEvent); + return; + } + hostApplicationMapDao.insert(endPoint, destinationId, spanEvent.getServiceType(), applicationId, serviceType.getCode()); + } + + private void insertAcceptorHost(SpanBo span) { + // save host application map + // acceptor host is set at profiler module only when the span is not the kind of root span + final String acceptorHost = span.getAcceptorHost(); + if (acceptorHost == null) { + logger.debug("acceptorHost is null {}", span); + return; + } + final String spanApplicationName = span.getApplicationId(); + final short applicationServiceTypeCode = getApplicationServiceType(span).getCode(); + + final String parentApplicationName = span.getParentApplicationId(); + final short parentServiceType = span.getParentApplicationServiceType(); + + final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); + if (spanServiceType.isQueue()) { + hostApplicationMapDao.insert(span.getEndPoint(), spanApplicationName, applicationServiceTypeCode, parentApplicationName, parentServiceType); + } else { + hostApplicationMapDao.insert(acceptorHost, spanApplicationName, applicationServiceTypeCode, parentApplicationName, parentServiceType); + } + } + + private ServiceType getApplicationServiceType(SpanBo span) { + // Check if applicationServiceType is set. If not, use span's service type. + final short applicationServiceTypeCode = span.getApplicationServiceType(); + return registry.findServiceType(applicationServiceTypeCode); + } + + private void insertSpanStat(SpanBo span) { + final ServiceType applicationServiceType = getApplicationServiceType(span); + final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); + + final boolean isError = span.getErrCode() != 0; + int bugCheck = 0; + if (span.getParentSpanId() == -1) { + if (spanServiceType.isQueue()) { + // create virtual queue node + statisticsService.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); + + statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, span.getAcceptorHost(), spanServiceType, span.getAgentId(), span.getElapsed(), isError); + } else { + // create virtual user + statisticsService.updateCaller(span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); + + // update the span information of the current node (self) + statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getElapsed(), isError); + } + bugCheck++; + } + + // save statistics info only when parentApplicationContext exists + // when drawing server map based on statistics info, you must know the application name of the previous node. + if (span.getParentApplicationId() != null) { + String parentApplicationName = span.getParentApplicationId(); + logger.debug("Received parent application name. {}", parentApplicationName); + + ServiceType parentApplicationType = registry.findServiceType(span.getParentApplicationServiceType()); + + // create virtual queue node if current' span's service type is a queue AND : + // 1. parent node's application service type is not a queue (it may have come from a queue that is traced) + // 2. current node's application service type is not a queue (current node may be a queue that is traced) + if (spanServiceType.isQueue()) { + if (!applicationServiceType.isQueue() && !parentApplicationType.isQueue()) { + // emulate virtual queue node's accept Span and record it's acceptor host + hostApplicationMapDao.insert(span.getRemoteAddr(), span.getAcceptorHost(), spanServiceType.getCode(), parentApplicationName, parentApplicationType.getCode()); + // emulate virtual queue node's send SpanEvent + statisticsService.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); + + parentApplicationName = span.getAcceptorHost(); + parentApplicationType = spanServiceType; + } + } + + statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, parentApplicationName, parentApplicationType, span.getAgentId(), span.getElapsed(), isError); + bugCheck++; + } + + // record the response time of the current node (self). + // blow code may be conflict of idea above callee key. + // it is odd to record reversely, because of already recording the caller data at previous node. + // the data may be different due to timeout or network error. + + statisticsService.updateResponseTime(span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); + + if (bugCheck != 1) { + logger.info("ambiguous span found(bug). span:{}", span); + } + } + + private void insertSpanEventStat(SpanBo span) { + + final List spanEventList = span.getSpanEventBoList(); + if (CollectionUtils.isEmpty(spanEventList)) { + return; + } + if (logger.isDebugEnabled()) { + logger.debug("handle spanEvent size:{}", spanEventList.size()); + } + + final ServiceType applicationServiceType = getApplicationServiceType(span); + // TODO need to batch update later. + insertSpanEventList(spanEventList, applicationServiceType, span.getApplicationId(), span.getAgentId(), span.getEndPoint()); + } + + private void insertSpanEventList(List spanEventList, ServiceType applicationServiceType, String applicationId, String agentId, String endPoint) { + + for (SpanEventBo spanEvent : spanEventList) { + final ServiceType spanEventType = registry.findServiceType(spanEvent.getServiceType()); + + if (isAlias(spanEventType, spanEvent)) { + insertAcceptorHost(spanEvent, applicationId, applicationServiceType); + continue; + } + + if (!spanEventType.isRecordStatistics()) { + continue; + } + + final String spanEventApplicationName = normalize(spanEvent.getDestinationId(), spanEventType); + final String spanEventEndPoint = spanEvent.getEndPoint(); + + // if terminal update statistics + final int elapsed = spanEvent.getEndElapsed(); + final boolean hasException = spanEvent.hasException(); + + if (applicationId == null || spanEventApplicationName == null) { + throttledLogger.info("Failed to insert statistics. Cause:SpanEvent has invalid format." + + "(application:{}/{}[{}], spanEventApplication:{}[{}])", + applicationId, agentId, applicationServiceType, spanEventApplicationName, spanEventType); + continue; + } + + /* + * save information to draw a server map based on statistics + */ + // save the information of caller (the spanevent that called span) + statisticsService.updateCaller(applicationId, applicationServiceType, agentId, spanEventApplicationName, spanEventType, spanEventEndPoint, elapsed, hasException); + + // save the information of callee (the span that spanevent called) + statisticsService.updateCallee(spanEventApplicationName, spanEventType, applicationId, applicationServiceType, endPoint, elapsed, hasException); + } + } + + private String normalize(String spanEventApplicationName, ServiceType spanEventType) { + if (spanEventType.getCategory() == ServiceTypeCategory.DATABASE) { + // empty database id + if (spanEventApplicationName == null) { + return "UNKNOWN_DATABASE"; + } + } + return spanEventApplicationName; + } + + private boolean isAlias(ServiceType spanEventType, SpanEventBo forDebugEvent) { + if (!spanEventType.isAlias()) { + return false; + } + if (spanEventType.isRecordStatistics()) { + logger.error("ServiceType with ALIAS should NOT have RECORD_STATISTICS {}", forDebugEvent); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/SqlMetaDataService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/SqlMetaDataService.java index a3dea452f27c..04fcd39a7af5 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/SqlMetaDataService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/SqlMetaDataService.java @@ -1,36 +1,7 @@ -/* - * Copyright 2018 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.collector.service; -import com.navercorp.pinpoint.collector.dao.SqlMetaDataDao; import com.navercorp.pinpoint.common.server.bo.SqlMetaDataBo; -import org.springframework.stereotype.Service; - -import java.util.Objects; - -@Service -public class SqlMetaDataService { - private final SqlMetaDataDao sqlMetaDataDao; - - public SqlMetaDataService(SqlMetaDataDao sqlMetaDataDao) { - this.sqlMetaDataDao = Objects.requireNonNull(sqlMetaDataDao, "sqlMetaDataDao"); - } - public void insert(final SqlMetaDataBo sqlMetaDataBo) { - this.sqlMetaDataDao.insert(sqlMetaDataBo); - } +public interface SqlMetaDataService { + void insert(SqlMetaDataBo sqlMetaDataBo); } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/TraceService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/TraceService.java index 475df588c9d0..50ce48344f87 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/TraceService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/TraceService.java @@ -1,265 +1,10 @@ -/* - * Copyright 2018 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.collector.service; -import com.navercorp.pinpoint.collector.dao.ApplicationTraceIndexDao; -import com.navercorp.pinpoint.collector.dao.HostApplicationMapDao; -import com.navercorp.pinpoint.collector.dao.TraceDao; -import com.navercorp.pinpoint.common.profiler.logging.ThrottledLogger; 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.trace.ServiceType; -import com.navercorp.pinpoint.common.trace.ServiceTypeCategory; -import com.navercorp.pinpoint.loader.service.ServiceTypeRegistryService; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Objects; - -@Service -public class TraceService { - private final Logger logger = LogManager.getLogger(getClass()); - - private final ThrottledLogger throttledLogger = ThrottledLogger.getLogger(logger, 10000); - - private final TraceDao traceDao; - - private final ApplicationTraceIndexDao applicationTraceIndexDao; - - private final HostApplicationMapDao hostApplicationMapDao; - - private final StatisticsService statisticsService; - - private final ServiceTypeRegistryService registry; - - public TraceService(TraceDao traceDao, - ApplicationTraceIndexDao applicationTraceIndexDao, - HostApplicationMapDao hostApplicationMapDao, - StatisticsService statisticsService, - ServiceTypeRegistryService registry) { - this.traceDao = Objects.requireNonNull(traceDao, "traceDao"); - this.applicationTraceIndexDao = Objects.requireNonNull(applicationTraceIndexDao, "applicationTraceIndexDao"); - this.hostApplicationMapDao = Objects.requireNonNull(hostApplicationMapDao, "hostApplicationMapDao"); - this.statisticsService = Objects.requireNonNull(statisticsService, "statisticsService"); - this.registry = Objects.requireNonNull(registry, "registry"); - } - - public void insertSpanChunk(final SpanChunkBo spanChunkBo) { - traceDao.insertSpanChunk(spanChunkBo); - final ServiceType applicationServiceType = getApplicationServiceType(spanChunkBo); - final List spanEventList = spanChunkBo.getSpanEventBoList(); - if (spanEventList != null) { - // TODO need to batch update later. - insertSpanEventList(spanEventList, applicationServiceType, spanChunkBo.getApplicationId(), spanChunkBo.getAgentId(), spanChunkBo.getEndPoint()); - } - } - - private ServiceType getApplicationServiceType(SpanChunkBo spanChunk) { - final short applicationServiceTypeCode = spanChunk.getApplicationServiceType(); - return registry.findServiceType(applicationServiceTypeCode); - } - - public void insertSpan(final SpanBo spanBo) { - traceDao.insert(spanBo); - applicationTraceIndexDao.insert(spanBo); - insertAcceptorHost(spanBo); - insertSpanStat(spanBo); - insertSpanEventStat(spanBo); - } - - private void insertAcceptorHost(SpanEventBo spanEvent, String applicationId, ServiceType serviceType) { - final String endPoint = spanEvent.getEndPoint(); - if (endPoint == null) { - logger.debug("endPoint is null. spanEvent:{}", spanEvent); - return; - } - final String destinationId = spanEvent.getDestinationId(); - if (destinationId == null) { - logger.debug("destinationId is null. spanEvent:{}", spanEvent); - return; - } - hostApplicationMapDao.insert(endPoint, destinationId, spanEvent.getServiceType(), applicationId, serviceType.getCode()); - } - - private void insertAcceptorHost(SpanBo span) { - // save host application map - // acceptor host is set at profiler module only when the span is not the kind of root span - final String acceptorHost = span.getAcceptorHost(); - if (acceptorHost == null) { - logger.debug("acceptorHost is null {}", span); - return; - } - final String spanApplicationName = span.getApplicationId(); - final short applicationServiceTypeCode = getApplicationServiceType(span).getCode(); - - final String parentApplicationName = span.getParentApplicationId(); - final short parentServiceType = span.getParentApplicationServiceType(); - - final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); - if (spanServiceType.isQueue()) { - hostApplicationMapDao.insert(span.getEndPoint(), spanApplicationName, applicationServiceTypeCode, parentApplicationName, parentServiceType); - } else { - hostApplicationMapDao.insert(acceptorHost, spanApplicationName, applicationServiceTypeCode, parentApplicationName, parentServiceType); - } - } - - private ServiceType getApplicationServiceType(SpanBo span) { - // Check if applicationServiceType is set. If not, use span's service type. - final short applicationServiceTypeCode = span.getApplicationServiceType(); - return registry.findServiceType(applicationServiceTypeCode); - } - - private void insertSpanStat(SpanBo span) { - final ServiceType applicationServiceType = getApplicationServiceType(span); - final ServiceType spanServiceType = registry.findServiceType(span.getServiceType()); - - final boolean isError = span.getErrCode() != 0; - int bugCheck = 0; - if (span.getParentSpanId() == -1) { - if (spanServiceType.isQueue()) { - // create virtual queue node - statisticsService.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); - - statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, span.getAcceptorHost(), spanServiceType, span.getAgentId(), span.getElapsed(), isError); - } else { - // create virtual user - statisticsService.updateCaller(span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); - - // update the span information of the current node (self) - statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, span.getApplicationId(), ServiceType.USER, span.getAgentId(), span.getElapsed(), isError); - } - bugCheck++; - } - - // save statistics info only when parentApplicationContext exists - // when drawing server map based on statistics info, you must know the application name of the previous node. - if (span.getParentApplicationId() != null) { - String parentApplicationName = span.getParentApplicationId(); - logger.debug("Received parent application name. {}", parentApplicationName); - - ServiceType parentApplicationType = registry.findServiceType(span.getParentApplicationServiceType()); - - // create virtual queue node if current' span's service type is a queue AND : - // 1. parent node's application service type is not a queue (it may have come from a queue that is traced) - // 2. current node's application service type is not a queue (current node may be a queue that is traced) - if (spanServiceType.isQueue()) { - if (!applicationServiceType.isQueue() && !parentApplicationType.isQueue()) { - // emulate virtual queue node's accept Span and record it's acceptor host - hostApplicationMapDao.insert(span.getRemoteAddr(), span.getAcceptorHost(), spanServiceType.getCode(), parentApplicationName, parentApplicationType.getCode()); - // emulate virtual queue node's send SpanEvent - statisticsService.updateCaller(span.getAcceptorHost(), spanServiceType, span.getRemoteAddr(), span.getApplicationId(), applicationServiceType, span.getEndPoint(), span.getElapsed(), isError); - - parentApplicationName = span.getAcceptorHost(); - parentApplicationType = spanServiceType; - } - } - - statisticsService.updateCallee(span.getApplicationId(), applicationServiceType, parentApplicationName, parentApplicationType, span.getAgentId(), span.getElapsed(), isError); - bugCheck++; - } - - // record the response time of the current node (self). - // blow code may be conflict of idea above callee key. - // it is odd to record reversely, because of already recording the caller data at previous node. - // the data may be different due to timeout or network error. - - statisticsService.updateResponseTime(span.getApplicationId(), applicationServiceType, span.getAgentId(), span.getElapsed(), isError); - - if (bugCheck != 1) { - logger.info("ambiguous span found(bug). span:{}", span); - } - } - - private void insertSpanEventStat(SpanBo span) { - - final List spanEventList = span.getSpanEventBoList(); - if (CollectionUtils.isEmpty(spanEventList)) { - return; - } - if (logger.isDebugEnabled()) { - logger.debug("handle spanEvent size:{}", spanEventList.size()); - } - - final ServiceType applicationServiceType = getApplicationServiceType(span); - // TODO need to batch update later. - insertSpanEventList(spanEventList, applicationServiceType, span.getApplicationId(), span.getAgentId(), span.getEndPoint()); - } - - private void insertSpanEventList(List spanEventList, ServiceType applicationServiceType, String applicationId, String agentId, String endPoint) { - - for (SpanEventBo spanEvent : spanEventList) { - final ServiceType spanEventType = registry.findServiceType(spanEvent.getServiceType()); - - if (isAlias(spanEventType, spanEvent)) { - insertAcceptorHost(spanEvent, applicationId, applicationServiceType); - continue; - } - - if (!spanEventType.isRecordStatistics()) { - continue; - } - - final String spanEventApplicationName = normalize(spanEvent.getDestinationId(), spanEventType); - final String spanEventEndPoint = spanEvent.getEndPoint(); - - // if terminal update statistics - final int elapsed = spanEvent.getEndElapsed(); - final boolean hasException = spanEvent.hasException(); - - if (applicationId == null || spanEventApplicationName == null) { - throttledLogger.info("Failed to insert statistics. Cause:SpanEvent has invalid format." + - "(application:{}/{}[{}], spanEventApplication:{}[{}])", - applicationId, agentId, applicationServiceType, spanEventApplicationName, spanEventType); - continue; - } - - /* - * save information to draw a server map based on statistics - */ - // save the information of caller (the spanevent that called span) - statisticsService.updateCaller(applicationId, applicationServiceType, agentId, spanEventApplicationName, spanEventType, spanEventEndPoint, elapsed, hasException); - - // save the information of callee (the span that spanevent called) - statisticsService.updateCallee(spanEventApplicationName, spanEventType, applicationId, applicationServiceType, endPoint, elapsed, hasException); - } - } - private String normalize(String spanEventApplicationName, ServiceType spanEventType) { - if (spanEventType.getCategory() == ServiceTypeCategory.DATABASE) { - // empty database id - if (spanEventApplicationName == null) { - return "UNKNOWN_DATABASE"; - } - } - return spanEventApplicationName; - } +public interface TraceService { + void insertSpanChunk(SpanChunkBo spanChunkBo); - private boolean isAlias(ServiceType spanEventType, SpanEventBo forDebugEvent) { - if (!spanEventType.isAlias()) { - return false; - } - if (spanEventType.isRecordStatistics()) { - logger.error("ServiceType with ALIAS should NOT have RECORD_STATISTICS {}", forDebugEvent); - return false; - } - return true; - } -} \ No newline at end of file + void insertSpan(SpanBo spanBo); +}