From bff5f34db6a5a5d1b76df8bc7b6c41b844715050 Mon Sep 17 00:00:00 2001 From: ga-ram Date: Wed, 28 Sep 2022 11:15:55 +0900 Subject: [PATCH] [#9254] Collects and retrieves URL statistics using Pinot --- .../dao/hbase/HbaseAgentUriStatDao.java | 89 ----------- .../grpc/stat/GrpcAgentUriStatMapper.java | 7 +- ...ice.java => EmptyAgentUriStatService.java} | 21 +-- .../bo/codec/stat/v2/AgentUriStatCodecV2.java | 6 + .../bo/codec/stat/v2/EachUriStatCodecV2.java | 15 +- .../stat/AgentStatDecodingContext.java | 13 ++ .../stat/AgentUriStatSerializer.java | 59 -------- .../common/server/bo/stat/AgentUriStatBo.java | 23 ++- .../common/server/bo/stat/EachUriStatBo.java | 49 +----- .../server/bo/stat/UriStatHistogram.java | 18 +-- .../bo/codec/stat/TestAgentStatFactory.java | 2 +- .../stat/v2/AgentUriStatCodecV2Test.java | 3 +- grpc/grpc-idl | 2 +- .../service/PinotAgentUriStatService.java | 74 +++++++++ .../metric/collector/dao/UriStatDao.java | 24 +++ .../collector/dao/pinot/PinotUriStatDao.java | 35 +++++ .../pinpoint/metric/common/model/UriStat.java | 141 ++++++++++++++++++ .../controller/SystemMetricController.java | 14 +- .../web/controller/UriStatController.java | 85 +++++++++++ .../metric/web/dao/SystemMetricDao.java | 6 +- .../pinpoint/metric/web/dao/UriStatDao.java | 30 ++++ .../dao/pinot/PinotSystemMetricDoubleDao.java | 6 +- .../dao/pinot/PinotSystemMetricLongDao.java | 6 +- .../metric/web/dao/pinot/PinotUriStatDao.java | 62 ++++++++ .../metric/web/model/UriStatGroup.java | 92 ++++++++++++ .../metric/web/model/UriStatSummary.java | 58 +++++++ .../typehandler/HistogramTypeHandler.java | 48 ++++++ .../web/service/SystemMetricDataService.java | 6 +- .../service/SystemMetricDataServiceImpl.java | 6 +- .../metric/web/service/UriStatService.java | 30 ++++ .../web/service/UriStatServiceImpl.java | 56 +++++++ .../web/util/MetricsQueryParameter.java | 102 +++++++++++++ .../metric/web/util/QueryParameter.java | 115 +++----------- .../web/util/UriStatQueryParameter.java | 64 ++++++++ .../metric/web/view/SystemMetricView.java | 16 +- .../metric/web/view/TimeSeriesValueView.java | 24 +++ .../metric/web/view/TimeSeriesView.java | 29 ++++ .../web/view/TimeseriesValueGroupView.java | 15 +- .../pinpoint/metric/web/view/UriStatView.java | 58 +++++++ .../src/main/pinot/pinot-urlStat-schema.json | 112 ++++++++++++++ .../src/main/pinot/pinot-urlStat-table.json | 33 ++++ ...plicationContext-collector-pinot-kafka.xml | 4 + .../pinot-collector/kafka-topic.properties | 3 +- .../mapper/pinot/SystemMetricDoubleMapper.xml | 4 +- .../mapper/pinot/SystemMetricLongMapper.xml | 4 +- .../pinot-web/mapper/pinot/UriStatMapper.xml | 128 ++++++++++++++++ .../pinot-web/mybatis-pinot-config.xml | 8 +- .../grpc/GrpcUriStatMessageConverter.java | 2 +- .../storage/AsyncQueueingUriStatStorage.java | 2 +- .../grpc/GrpcUriStatMessageConverterTest.java | 10 +- .../testapp/controller/SimpleController.java | 22 +++ .../SampledAgentStatDaoConfiguration.java | 12 -- .../stat/HbaseSampledAgentUriStatDao.java | 75 ---------- .../stat/SampledUriStatResultExtractor.java | 121 --------------- .../sampling/sampler/AgentUriStatSampler.java | 139 ----------------- .../stat/AgentStatServiceConfiguration.java | 15 -- .../stat/AgentUriStatChartService.java | 88 ----------- .../web/vo/stat/SampledAgentUriStat.java | 59 -------- .../sampler/AgentUriStatSamplerTest.java | 118 --------------- 59 files changed, 1454 insertions(+), 1014 deletions(-) delete mode 100644 collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentUriStatDao.java rename collector/src/main/java/com/navercorp/pinpoint/collector/service/{HBaseAgentUriStatService.java => EmptyAgentUriStatService.java} (58%) delete mode 100644 commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentUriStatSerializer.java create mode 100644 metric-module/collector-starter/src/main/java/com/navercorp/pinpoint/collector/service/PinotAgentUriStatService.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/UriStatDao.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/pinot/PinotUriStatDao.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/common/model/UriStat.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/UriStatController.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/UriStatDao.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotUriStatDao.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatGroup.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatSummary.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/mybatis/typehandler/HistogramTypeHandler.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatService.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatServiceImpl.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/MetricsQueryParameter.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/UriStatQueryParameter.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesValueView.java create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesView.java rename collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentUriStatDao.java => metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeseriesValueGroupView.java (68%) create mode 100644 metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/UriStatView.java create mode 100644 metric-module/metric/src/main/pinot/pinot-urlStat-schema.json create mode 100644 metric-module/metric/src/main/pinot/pinot-urlStat-table.json create mode 100644 metric-module/metric/src/main/resources/pinot-web/mapper/pinot/UriStatMapper.xml delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/stat/HbaseSampledAgentUriStatDao.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/SampledUriStatResultExtractor.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSampler.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentUriStatChartService.java delete mode 100644 web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledAgentUriStat.java delete mode 100644 web/src/test/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSamplerTest.java diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentUriStatDao.java b/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentUriStatDao.java deleted file mode 100644 index 257ab1f88e859..0000000000000 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/hbase/HbaseAgentUriStatDao.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020 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.dao.hbase; - -import com.navercorp.pinpoint.collector.dao.AgentUriStatDao; -import com.navercorp.pinpoint.collector.util.CollectorUtils; -import com.navercorp.pinpoint.common.hbase.HbaseOperations2; -import com.navercorp.pinpoint.common.hbase.HbaseTable; -import com.navercorp.pinpoint.common.hbase.TableNameProvider; -import com.navercorp.pinpoint.common.server.bo.serializer.stat.AgentStatHbaseOperationFactory; -import com.navercorp.pinpoint.common.server.bo.serializer.stat.AgentUriStatSerializer; -import com.navercorp.pinpoint.common.server.bo.stat.AgentStatType; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Put; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.springframework.stereotype.Repository; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -@Repository -public class HbaseAgentUriStatDao implements AgentUriStatDao { - - private final Logger logger = LogManager.getLogger(this.getClass()); - - - private final HbaseOperations2 hbaseTemplate; - - private final TableNameProvider tableNameProvider; - - private final AgentStatHbaseOperationFactory agentStatHbaseOperationFactory; - - private final AgentUriStatSerializer agentUriStatSerializer; - - public HbaseAgentUriStatDao(HbaseOperations2 hbaseTemplate, - TableNameProvider tableNameProvider, - AgentStatHbaseOperationFactory agentStatHbaseOperationFactory, - AgentUriStatSerializer agentUriStatSerializer) { - this.hbaseTemplate = Objects.requireNonNull(hbaseTemplate, "hbaseTemplate"); - this.tableNameProvider = Objects.requireNonNull(tableNameProvider, "tableNameProvider"); - this.agentStatHbaseOperationFactory = Objects.requireNonNull(agentStatHbaseOperationFactory, "agentStatHbaseOperationFactory"); - this.agentUriStatSerializer = Objects.requireNonNull(agentUriStatSerializer, "agentUriStatSerializer"); - } - - @Override - public void insert(AgentUriStatBo agentUriStatBo) { - String agentId = agentUriStatBo.getAgentId(); - - Objects.requireNonNull(agentId, "agentId"); - // Assert agentId - CollectorUtils.checkAgentId(agentId); - if (CollectionUtils.isEmpty(agentUriStatBo.getEachUriStatBoList())) { - return; - } - - if (logger.isDebugEnabled()) { - logger.debug("insert() agentUriStatBo:{}", agentUriStatBo); - } - - List agentUriStatPuts = this.agentStatHbaseOperationFactory.createPuts(agentId, AgentStatType.URI, Collections.singletonList(agentUriStatBo), this.agentUriStatSerializer); - if (!agentUriStatPuts.isEmpty()) { - TableName agentStatTableName = tableNameProvider.getTableName(HbaseTable.AGENT_URI_STAT); - this.hbaseTemplate.asyncPut(agentStatTableName, agentUriStatPuts); - } - } - -} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentUriStatMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentUriStatMapper.java index 211acc25c79ab..7e6728c6e6990 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentUriStatMapper.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/grpc/stat/GrpcAgentUriStatMapper.java @@ -40,11 +40,14 @@ public AgentUriStatBo map(final PAgentUriStat agentUriStat) { final String agentId = agentInfo.getAgentId(); final long startTimestamp = agentInfo.getAgentStartTime(); + final String applicationName = agentInfo.getApplicationName(); long timestamp = agentUriStat.getTimestamp(); int bucketVersion = agentUriStat.getBucketVersion(); AgentUriStatBo agentUriStatBo = new AgentUriStatBo(); + agentUriStatBo.setServiceName(""); // TODO: add serviceName when available + agentUriStatBo.setApplicationName(applicationName); agentUriStatBo.setAgentId(agentId); agentUriStatBo.setStartTimestamp(startTimestamp); agentUriStatBo.setTimestamp(timestamp); @@ -82,7 +85,7 @@ private UriStatHistogram convertUriStatHistogram(PUriHistogram pUriHistogram) { return null; } - double avg = pUriHistogram.getAvg(); + long total = pUriHistogram.getTotal(); long max = pUriHistogram.getMax(); int histogramCount = pUriHistogram.getHistogramCount(); @@ -95,7 +98,7 @@ private UriStatHistogram convertUriStatHistogram(PUriHistogram pUriHistogram) { UriStatHistogram uriStatHistogram = new UriStatHistogram(); uriStatHistogram.setCount(count); - uriStatHistogram.setAvg(avg); + uriStatHistogram.setTotal(total); uriStatHistogram.setMax(max); uriStatHistogram.setTimestampHistogram(histogram); diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentUriStatService.java b/collector/src/main/java/com/navercorp/pinpoint/collector/service/EmptyAgentUriStatService.java similarity index 58% rename from collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentUriStatService.java rename to collector/src/main/java/com/navercorp/pinpoint/collector/service/EmptyAgentUriStatService.java index 69ef004aedbb9..57fd9f1fb92f5 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/service/HBaseAgentUriStatService.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/service/EmptyAgentUriStatService.java @@ -16,28 +16,17 @@ package com.navercorp.pinpoint.collector.service; -import com.navercorp.pinpoint.collector.dao.hbase.HbaseAgentUriStatDao; import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.stereotype.Service; -import java.util.Objects; - /** * @author Taejin Koo */ -@Service("hBaseAgentUriStatService") -public class HBaseAgentUriStatService implements AgentUriStatService { - - private final HbaseAgentUriStatDao hbaseAgentUriStatDao; - - public HBaseAgentUriStatService(HbaseAgentUriStatDao hbaseAgentUriStatDao) { - this.hbaseAgentUriStatDao = Objects.requireNonNull(hbaseAgentUriStatDao, "hbaseAgentUriStatDao"); - } - +@ConditionalOnMissingBean(value = AgentUriStatService.class, ignored = EmptyAgentUriStatService.class) +@Service +public class EmptyAgentUriStatService implements AgentUriStatService { @Override - public void save(AgentUriStatBo agentUriStatBo) { - hbaseAgentUriStatDao.insert(agentUriStatBo); - } - + public void save(AgentUriStatBo agentUriStatBo) {} } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2.java index 14a68d8b94ad4..9b1d66b54bb21 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2.java @@ -79,6 +79,12 @@ public void encodeValues(Buffer valueBuffer, List agentUriStatBo public List decodeValues(Buffer valueBuffer, AgentStatDecodingContext decodingContext) { AgentUriStatBo agentUriStatBo = new AgentUriStatBo(); + final String serviceName = decodingContext.getServiceName(); + agentUriStatBo.setServiceName(serviceName); + + final String applicationName = decodingContext.getApplicationName(); + agentUriStatBo.setApplicationName(applicationName); + final String agentId = decodingContext.getAgentId(); agentUriStatBo.setAgentId(agentId); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/EachUriStatCodecV2.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/EachUriStatCodecV2.java index b9fe01472f344..23bf2c4843c9c 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/EachUriStatCodecV2.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/EachUriStatCodecV2.java @@ -29,7 +29,6 @@ import com.navercorp.pinpoint.common.server.bo.codec.stat.strategy.UnsignedLongEncodingStrategy; import com.navercorp.pinpoint.common.server.bo.codec.strategy.EncodingStrategy; import com.navercorp.pinpoint.common.server.bo.serializer.stat.AgentStatDecodingContext; -import com.navercorp.pinpoint.common.server.bo.serializer.stat.AgentStatUtils; import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.UriStatHistogram; @@ -94,7 +93,7 @@ private static class EachUriStatBoCodecEncoder implements AgentStatCodec.CodecEn private final UnsignedIntegerEncodingStrategy.Analyzer.Builder histogramCountAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); private final UnsignedIntegerEncodingStrategy.Analyzer.Builder countAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); - private final UnsignedLongEncodingStrategy.Analyzer.Builder avgAnalyzerBuilder = new UnsignedLongEncodingStrategy.Analyzer.Builder(); + private final UnsignedLongEncodingStrategy.Analyzer.Builder totalAnalyzerBuilder = new UnsignedLongEncodingStrategy.Analyzer.Builder(); private final UnsignedLongEncodingStrategy.Analyzer.Builder maxAnalyzerBuilder = new UnsignedLongEncodingStrategy.Analyzer.Builder(); private final UnsignedIntegerEncodingStrategy.Analyzer.Builder under100BucketCountAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); @@ -128,7 +127,7 @@ private void addValue(UriStatHistogram uriStatHistogram) { return; } countAnalyzerBuilder.addValue(uriStatHistogram.getCount()); - avgAnalyzerBuilder.addValue(AgentStatUtils.convertDoubleToLong(uriStatHistogram.getAvg())); + totalAnalyzerBuilder.addValue(uriStatHistogram.getTotal()); maxAnalyzerBuilder.addValue(uriStatHistogram.getMax()); int[] timestampHistogram = uriStatHistogram.getTimestampHistogram(); @@ -172,7 +171,7 @@ private List getAnalyzerList() { strategyAnalyzerList.add(histogramCountAnalyzerBuilder.build()); strategyAnalyzerList.add(countAnalyzerBuilder.build()); - strategyAnalyzerList.add(avgAnalyzerBuilder.build()); + strategyAnalyzerList.add(totalAnalyzerBuilder.build()); strategyAnalyzerList.add(maxAnalyzerBuilder.build()); strategyAnalyzerList.add(under100BucketCountAnalyzerBuilder.build()); @@ -218,7 +217,7 @@ public void decode(Buffer valueBuffer, AgentStatHeaderDecoder headerDecoder, int private Queue decodeUriStatHistogramList(Buffer valueBuffer, AgentStatHeaderDecoder headerDecoder, int valueSize) { EncodingStrategy countAnalyzerEncodingStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); - EncodingStrategy avgAnalyzerEncodingStrategy = UnsignedLongEncodingStrategy.getFromCode(headerDecoder.getCode()); + EncodingStrategy totalAnalyzerEncodingStrategy = UnsignedLongEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy maxAnalyzerEncodingStrategy = UnsignedLongEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy under100BucketCountAnalyzerEncodingStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); @@ -231,7 +230,7 @@ private Queue decodeUriStatHistogramList(Buffer valueBuffer, A EncodingStrategy over8000BucketCountAnalyzerEncodingStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); List countList = this.codec.decodeValues(valueBuffer, countAnalyzerEncodingStrategy, valueSize); - List avgList = this.codec.decodeValues(valueBuffer, avgAnalyzerEncodingStrategy, valueSize); + List totalList = this.codec.decodeValues(valueBuffer, totalAnalyzerEncodingStrategy, valueSize); List maxList = this.codec.decodeValues(valueBuffer, maxAnalyzerEncodingStrategy, valueSize); List under100BucketCountList = this.codec.decodeValues(valueBuffer, under100BucketCountAnalyzerEncodingStrategy, valueSize); @@ -249,8 +248,8 @@ private Queue decodeUriStatHistogramList(Buffer valueBuffer, A final Integer count = countList.get(i); uriStatHistogram.setCount(count); - final Long avg = avgList.get(i); - uriStatHistogram.setAvg(AgentStatUtils.convertLongToDouble(avg)); + final Long total = totalList.get(i); + uriStatHistogram.setTotal(total); final Long max = maxList.get(i); uriStatHistogram.setMax(max); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentStatDecodingContext.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentStatDecodingContext.java index ad5a3b5835a42..d6052423f3516 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentStatDecodingContext.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentStatDecodingContext.java @@ -21,12 +21,24 @@ */ public class AgentStatDecodingContext { + private String serviceName; + + private String applicationName; + private String agentId; private long baseTimestamp; private long timestampDelta; + public String getServiceName() { return serviceName; } + + public void setServiceName(String serviceName) { this.serviceName = serviceName; } + + public String getApplicationName() { return applicationName; } + + public void setApplicationName(String applicationName) { this.applicationName = applicationName; } + public String getAgentId() { return agentId; } @@ -50,4 +62,5 @@ public long getTimestampDelta() { public void setTimestampDelta(long timestampDelta) { this.timestampDelta = timestampDelta; } + } diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentUriStatSerializer.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentUriStatSerializer.java deleted file mode 100644 index 82b13fd4d3b4c..0000000000000 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/serializer/stat/AgentUriStatSerializer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 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.common.server.bo.serializer.stat; - -import com.navercorp.pinpoint.common.hbase.HbaseColumnFamily; -import com.navercorp.pinpoint.common.server.bo.codec.stat.AgentStatEncoder; -import com.navercorp.pinpoint.common.server.bo.serializer.HbaseSerializer; -import com.navercorp.pinpoint.common.server.bo.serializer.SerializationContext; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.hadoop.hbase.HConstants; -import org.apache.hadoop.hbase.client.Put; -import org.springframework.stereotype.Component; - -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -@Component -public class AgentUriStatSerializer implements HbaseSerializer, Put> { - - private final AgentStatEncoder agentUriStatEncoder; - - public AgentUriStatSerializer(AgentStatEncoder agentUriStatEncoder) { - this.agentUriStatEncoder = Objects.requireNonNull(agentUriStatEncoder, "agentUriStatEncoder"); - } - - @Override - public void serialize(List agentStatBos, Put put, SerializationContext context) { - if (CollectionUtils.isEmpty(agentStatBos)) { - throw new IllegalArgumentException("agentStatBos should not be empty"); - } - long initialTimestamp = agentStatBos.get(0).getTimestamp(); - long baseTimestamp = AgentStatUtils.getBaseTimestamp(initialTimestamp); - long timestampDelta = initialTimestamp - baseTimestamp; - ByteBuffer qualifierBuffer = this.agentUriStatEncoder.encodeQualifier(timestampDelta); - ByteBuffer valueBuffer = this.agentUriStatEncoder.encodeValue(agentStatBos); - - put.addColumn(HbaseColumnFamily.AGENT_URI_STAT_STATISTICS.getName(), qualifierBuffer, HConstants.LATEST_TIMESTAMP, valueBuffer); - } - -} diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentUriStatBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentUriStatBo.java index 74e5ac0cf0548..2118ac9aa9d04 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentUriStatBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/AgentUriStatBo.java @@ -24,15 +24,22 @@ * @author Taejin Koo */ public class AgentUriStatBo implements AgentStatDataPoint { - + private String serviceName; + private String applicationName; private String agentId; private long startTimestamp; - private long timestamp; private byte bucketVersion; - private List eachUriStatBoList = new ArrayList<>(); + public String getServiceName() { return serviceName; } + + public void setServiceName(String serviceName) { this.serviceName = serviceName; } + + public String getApplicationName() { return applicationName; } + + public void setApplicationName(String applicationName) { this.applicationName = applicationName; } + @Override public String getAgentId() { return agentId; @@ -103,6 +110,8 @@ public boolean equals(Object o) { AgentUriStatBo that = (AgentUriStatBo) o; + if (serviceName != null? !serviceName.equals(that.serviceName) : that.serviceName != null) return false; + if (applicationName != null? !applicationName.equals(that.applicationName) : that.applicationName != null) return false; if (startTimestamp != that.startTimestamp) return false; if (timestamp != that.timestamp) return false; if (bucketVersion != that.bucketVersion) return false; @@ -112,7 +121,9 @@ public boolean equals(Object o) { @Override public int hashCode() { - int result = agentId != null ? agentId.hashCode() : 0; + int result = serviceName != null ? serviceName.hashCode() : 0; + result = 31 * result + (applicationName != null ? applicationName.hashCode() : 0); + result = 31 * result + (agentId != null ? agentId.hashCode() : 0); result = 31 * result + (int) (startTimestamp ^ (startTimestamp >>> 32)); result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); result = 31 * result + (int) bucketVersion; @@ -123,7 +134,9 @@ public int hashCode() { @Override public String toString() { final StringBuilder sb = new StringBuilder("AgentUriStatBo{"); - sb.append("agentId='").append(agentId).append('\''); + sb.append("serviceName='").append(serviceName).append('\''); + sb.append(", applicationName=").append(applicationName); + sb.append(", agentId='").append(agentId).append('\''); sb.append(", startTimestamp=").append(startTimestamp); sb.append(", timestamp=").append(timestamp); sb.append(", bucketVersion=").append(bucketVersion); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/EachUriStatBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/EachUriStatBo.java index 493497ee446fe..263a4ee05f9de 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/EachUriStatBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/EachUriStatBo.java @@ -19,48 +19,12 @@ /** * @author Taejin Koo */ -public class EachUriStatBo implements AgentStatDataPoint { - - private String agentId; - private long startTimestamp; - - private long timestamp; +public class EachUriStatBo { private String uri; private UriStatHistogram totalHistogram = new UriStatHistogram(); private UriStatHistogram failedHistogram = null; - @Override - public String getAgentId() { - return agentId; - } - - @Override - public void setAgentId(String agentId) { - this.agentId = agentId; - } - - @Override - public long getStartTimestamp() { - return startTimestamp; - } - - @Override - public void setStartTimestamp(long startTimestamp) { - this.startTimestamp = startTimestamp; - } - - @Override - public long getTimestamp() { - return timestamp; - } - - @Override - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } - - @Override public AgentStatType getAgentStatType() { return AgentStatType.URI; } @@ -96,9 +60,6 @@ public boolean equals(Object o) { EachUriStatBo that = (EachUriStatBo) o; - if (startTimestamp != that.startTimestamp) return false; - if (timestamp != that.timestamp) return false; - if (agentId != null ? !agentId.equals(that.agentId) : that.agentId != null) return false; if (uri != null ? !uri.equals(that.uri) : that.uri != null) return false; if (totalHistogram != null ? !totalHistogram.equals(that.totalHistogram) : that.totalHistogram != null) return false; return failedHistogram != null ? failedHistogram.equals(that.failedHistogram) : that.failedHistogram == null; @@ -106,10 +67,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - int result = agentId != null ? agentId.hashCode() : 0; - result = 31 * result + (int) (startTimestamp ^ (startTimestamp >>> 32)); - result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); - result = 31 * result + (uri != null ? uri.hashCode() : 0); + int result = uri != null ? uri.hashCode() : 0; result = 31 * result + (totalHistogram != null ? totalHistogram.hashCode() : 0); result = 31 * result + (failedHistogram != null ? failedHistogram.hashCode() : 0); return result; @@ -118,9 +76,6 @@ public int hashCode() { @Override public String toString() { final StringBuilder sb = new StringBuilder("EachUriStatBo{"); - sb.append("agentId='").append(agentId).append('\''); - sb.append(", startTimestamp=").append(startTimestamp); - sb.append(", timestamp=").append(timestamp); sb.append(", uri='").append(uri).append('\''); sb.append(", totalHistogram=").append(totalHistogram); sb.append(", failedHistogram=").append(failedHistogram); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/UriStatHistogram.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/UriStatHistogram.java index 162817561f3db..8b417f7ee5330 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/UriStatHistogram.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/UriStatHistogram.java @@ -24,7 +24,7 @@ public class UriStatHistogram { private int count; - private double avg; + private long total; private long max = 0; private int[] timestampHistogram; @@ -36,12 +36,12 @@ public void setCount(int count) { this.count = count; } - public double getAvg() { - return avg; + public long getTotal() { + return total; } - public void setAvg(double avg) { - this.avg = avg; + public void setTotal(long total) { + this.total = total; } public long getMax() { @@ -72,7 +72,7 @@ public boolean equals(Object o) { UriStatHistogram that = (UriStatHistogram) o; if (count != that.count) return false; - if (Double.compare(that.avg, avg) != 0) return false; + if (total != that.total) return false; if (max != that.max) return false; return Arrays.equals(timestampHistogram, that.timestampHistogram); } @@ -80,10 +80,8 @@ public boolean equals(Object o) { @Override public int hashCode() { int result; - long temp; result = count; - temp = Double.doubleToLongBits(avg); - result = 31 * result + (int) (temp ^ (temp >>> 32)); + result = 31 * result + (int) (total ^ (total >>> 32)); result = 31 * result + (int) (max ^ (max >>> 32)); result = 31 * result + Arrays.hashCode(timestampHistogram); return result; @@ -93,7 +91,7 @@ public int hashCode() { public String toString() { final StringBuilder sb = new StringBuilder("UriStatHistogram{"); sb.append("count=").append(count); - sb.append(", avg=").append(avg); + sb.append(", total=").append(total); sb.append(", max=").append(max); sb.append(", timestampHistogram=").append(Arrays.toString(timestampHistogram)); sb.append('}'); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java index 7bb0c028c75d9..ee50ea26abe7d 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java @@ -541,7 +541,7 @@ private static UriStatHistogram createHistogram(int[] elapsedTimes, int sample) } uriStatHistogram.setCount(count); - uriStatHistogram.setAvg(totalElapsed / count); + uriStatHistogram.setTotal(totalElapsed); uriStatHistogram.setMax(max); uriStatHistogram.setTimestampHistogram(histogramBucket); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2Test.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2Test.java index 348f768476750..526ef6471d242 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2Test.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/AgentUriStatCodecV2Test.java @@ -19,7 +19,6 @@ import com.navercorp.pinpoint.common.server.bo.codec.stat.AgentStatCodec; import com.navercorp.pinpoint.common.server.bo.codec.stat.AgentStatCodecTestBase; import com.navercorp.pinpoint.common.server.bo.codec.stat.TestAgentStatFactory; -import com.navercorp.pinpoint.common.server.bo.serializer.stat.AgentStatUtils; import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.UriStatHistogram; @@ -82,7 +81,7 @@ private void assertUriStatHistogram(UriStatHistogram expected, UriStatHistogram return; } Assertions.assertEquals(expected.getCount(), actual.getCount()); - Assertions.assertEquals(AgentStatUtils.convertDoubleToLong(expected.getAvg()), AgentStatUtils.convertDoubleToLong(actual.getAvg())); + Assertions.assertEquals(expected.getTotal(), actual.getTotal()); Assertions.assertEquals(expected.getMax(), actual.getMax()); Assertions.assertArrayEquals(expected.getTimestampHistogram(), actual.getTimestampHistogram()); } diff --git a/grpc/grpc-idl b/grpc/grpc-idl index 8214406e2bfe9..1722bd42a2645 160000 --- a/grpc/grpc-idl +++ b/grpc/grpc-idl @@ -1 +1 @@ -Subproject commit 8214406e2bfe944e7da00a39c1a07ee59f63d40b +Subproject commit 1722bd42a2645b44498577ba86c8ec03efa9a8ad diff --git a/metric-module/collector-starter/src/main/java/com/navercorp/pinpoint/collector/service/PinotAgentUriStatService.java b/metric-module/collector-starter/src/main/java/com/navercorp/pinpoint/collector/service/PinotAgentUriStatService.java new file mode 100644 index 0000000000000..dd79df9834578 --- /dev/null +++ b/metric-module/collector-starter/src/main/java/com/navercorp/pinpoint/collector/service/PinotAgentUriStatService.java @@ -0,0 +1,74 @@ +/* + * Copyright 2022 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.common.server.bo.stat.AgentUriStatBo; + +import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; +import com.navercorp.pinpoint.common.server.bo.stat.UriStatHistogram; +import com.navercorp.pinpoint.metric.collector.MetricAppPropertySources; +import com.navercorp.pinpoint.metric.collector.dao.UriStatDao; +import com.navercorp.pinpoint.metric.common.model.UriStat; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportResource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Objects; + +@Service +@ComponentScan("com.navercorp.pinpoint.metric.collector.dao.pinot") +@ImportResource({"classpath:pinot-collector/applicationContext-collector-pinot.xml", "classpath:pinot-collector/servlet-context-collector-pinot.xml"}) +@Import({MetricAppPropertySources.class}) +public class PinotAgentUriStatService implements AgentUriStatService { + + private final int BUCKET_SIZE = 8; + private final int[] EMPTY_BUCKETS = new int[BUCKET_SIZE]; + private final UriStatDao uriStatDao; + + public PinotAgentUriStatService(UriStatDao uriStatDao) { + this.uriStatDao = Objects.requireNonNull(uriStatDao, "uriStatDao"); + } + + @Override + public void save(AgentUriStatBo agentUriStatBo) { + ArrayList data = new ArrayList<>(); + final String serviceName = agentUriStatBo.getServiceName(); + final String applicationName = agentUriStatBo.getApplicationName(); + final String agentId = agentUriStatBo.getAgentId(); + final long timestamp = agentUriStatBo.getTimestamp(); + final int version = agentUriStatBo.getBucketVersion(); + + for (EachUriStatBo eachUriStatBo : agentUriStatBo.getEachUriStatBoList()) { + final String uri = eachUriStatBo.getUri(); + final UriStatHistogram totalHistogram = eachUriStatBo.getTotalHistogram(); + final UriStatHistogram failureHistogram = eachUriStatBo.getFailedHistogram(); + data.add(new UriStat(timestamp, serviceName, applicationName, agentId, uri, totalHistogram.getCount(), totalHistogram.getMax(), + totalHistogram.getTotal(), getHistogramArray(totalHistogram), getHistogramArray(failureHistogram), version)); + } + uriStatDao.insert(data); + } + + public int[] getHistogramArray(UriStatHistogram histogram) { + if (histogram != null) { + return histogram.getTimestampHistogram(); + } + return EMPTY_BUCKETS; + } + +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/UriStatDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/UriStatDao.java new file mode 100644 index 0000000000000..cb92d58445887 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/UriStatDao.java @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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.metric.collector.dao; + +import com.navercorp.pinpoint.metric.common.model.UriStat; + +import java.util.List; + +public interface UriStatDao { + void insert(List data); +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/pinot/PinotUriStatDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/pinot/PinotUriStatDao.java new file mode 100644 index 0000000000000..4ac131b7ad92a --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/collector/dao/pinot/PinotUriStatDao.java @@ -0,0 +1,35 @@ +package com.navercorp.pinpoint.metric.collector.dao.pinot; + +import com.navercorp.pinpoint.metric.collector.dao.UriStatDao; +import com.navercorp.pinpoint.metric.common.model.StringPrecondition; +import com.navercorp.pinpoint.metric.common.model.UriStat; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Objects; + +@Repository +public class PinotUriStatDao implements UriStatDao { + + private final KafkaTemplate kafkaUriStatTemplate; + + private final String topic; + + public PinotUriStatDao(KafkaTemplate kafkaUriStatTemplate, + @Value("${kafka.uri.topic}") String topic) { + this.kafkaUriStatTemplate = Objects.requireNonNull(kafkaUriStatTemplate, "kafkaUriStatTemplate"); + this.topic = StringPrecondition.requireHasLength(topic, "topic"); + } + + @Override + public void insert(List data) { + Objects.requireNonNull(data); + + for(UriStat uriStat : data) { + this.kafkaUriStatTemplate.send(topic, uriStat.getApplicationName(), uriStat); + } + + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/common/model/UriStat.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/common/model/UriStat.java new file mode 100644 index 0000000000000..4c385dc180456 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/common/model/UriStat.java @@ -0,0 +1,141 @@ +/* + * Copyright 2022 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.metric.common.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; + +public class UriStat { + private final long EMPTY_NUMBER = 0L; + private final String serviceName; + private final String applicationName; + private final String agentId; + private final String uri; + private final long count; + private final long maxLatencyMs; + private final long totalTimeMs; + private final int[] totalHistogram; + private final int[] failureHistogram; + private final long timestamp; + private final int version; + + public UriStat(long timestamp, String serviceName, String applicationName, String agentId, String uri, long count, long maxLatencyMs, long totalTimeMs, int[] totalHistogram, int[] failureHistogram, int version) { + this.timestamp = timestamp; + this.serviceName = Objects.requireNonNull(serviceName, "serviceName"); + this.applicationName = StringPrecondition.requireHasLength(applicationName, "applicationName"); + this.agentId = StringPrecondition.requireHasLength(agentId, "agentId"); + this.uri = StringPrecondition.requireHasLength(uri, "uri"); + this.count = count; + this.maxLatencyMs = maxLatencyMs; + this.totalTimeMs = totalTimeMs; + this.totalHistogram = Objects.requireNonNull(totalHistogram, "totalHistogram"); + this.failureHistogram = Objects.requireNonNull(failureHistogram, "totalHistogram"); + this.version = version; + } + + public UriStat(long timestamp, double totalHistogram0, double totalHistogram1, double totalHistogram2, double totalHistogram3, + double totalHistogram4, double totalHistogram5, double totalHistogram6, double totalHistogram7, + double failureHistogram0, double failureHistogram1, double failureHistogram2, double failureHistogram3, + double failureHistogram4, double failureHistogram5, double failureHistogram6, double failureHistogram7, int version) { + this.timestamp = timestamp; + this.serviceName = StringUtils.EMPTY; + this.applicationName = StringUtils.EMPTY; + this.agentId = StringUtils.EMPTY; + this.uri = StringUtils.EMPTY; + this.count = EMPTY_NUMBER; + this.maxLatencyMs = EMPTY_NUMBER; + this.totalTimeMs = EMPTY_NUMBER; + this.totalHistogram = new int[]{(int)totalHistogram0, (int)totalHistogram1, (int)totalHistogram2, (int)totalHistogram3, (int)totalHistogram4, (int)totalHistogram5, (int)totalHistogram6, (int)totalHistogram7}; + this.failureHistogram = new int[]{(int)failureHistogram0, (int)failureHistogram1, (int)failureHistogram2, (int)failureHistogram3, (int)failureHistogram4, (int)failureHistogram5, (int)failureHistogram6, (int)failureHistogram7}; + this.version = version; + } + + public String getServiceName() { + return serviceName; + } + + public String getApplicationName() { + return applicationName; + } + + public String getAgentId() { return agentId; } + + public String getUri() { + return uri; + } + + public long getCount() { + return count; + } + + public long getMaxLatencyMs() { + return maxLatencyMs; + } + + public long getTotalTimeMs() { + return totalTimeMs; + } + + public long getTimestamp() { + return timestamp; + } + + public int getVersion() { return version; } + + public int getTotalHistogram0() { return totalHistogram[0]; } + public int getTotalHistogram1() { return totalHistogram[1]; } + public int getTotalHistogram2() { return totalHistogram[2]; } + public int getTotalHistogram3() { return totalHistogram[3]; } + public int getTotalHistogram4() { return totalHistogram[4]; } + public int getTotalHistogram5() { return totalHistogram[5]; } + public int getTotalHistogram6() { return totalHistogram[6]; } + public int getTotalHistogram7() { return totalHistogram[7]; } + + public int getFailureHistogram0() { return failureHistogram[0]; } + public int getFailureHistogram1() { return failureHistogram[1]; } + public int getFailureHistogram2() { return failureHistogram[2]; } + public int getFailureHistogram3() { return failureHistogram[3]; } + public int getFailureHistogram4() { return failureHistogram[4]; } + public int getFailureHistogram5() { return failureHistogram[5]; } + public int getFailureHistogram6() { return failureHistogram[6]; } + public int getFailureHistogram7() { return failureHistogram[7]; } + + @JsonIgnore + public int[] getTotalHistogram() { return totalHistogram; } + + @JsonIgnore + public int[] getFailureHistogram() { return failureHistogram; } + + @Override + public String toString() { + return "UriStat{" + + "serviceName='" + serviceName + '\'' + + ", applicationName='" + applicationName + '\'' + + ", agentId='" + agentId + '\'' + + ", uri=" + uri + + ", count=" + count + + ", maxLatencyMs=" + maxLatencyMs + + ", totalTimeMs=" + totalTimeMs + + ", totalHistogram=" + totalHistogram + + ", failureHistogram=" + failureHistogram + + ", timestamp=" + timestamp + + '}'; + } + +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/SystemMetricController.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/SystemMetricController.java index 8910c4b66fcd1..4b3bfe1e9b7a4 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/SystemMetricController.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/SystemMetricController.java @@ -23,7 +23,7 @@ import com.navercorp.pinpoint.metric.web.service.SystemMetricDataService; import com.navercorp.pinpoint.metric.web.service.SystemMetricHostInfoService; import com.navercorp.pinpoint.metric.web.service.YMLSystemMetricBasicGroupManager; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.util.Range; import com.navercorp.pinpoint.metric.web.util.TagParser; import com.navercorp.pinpoint.metric.web.util.TimePrecision; @@ -71,14 +71,14 @@ public List getSystemMetricBoList( @RequestParam("from") long from, @RequestParam("to") long to) { - QueryParameter.Builder builder = new QueryParameter.Builder(); + MetricsQueryParameter.Builder builder = new MetricsQueryParameter.Builder(); builder.setHostGroupName(hostGroupName); builder.setHostName(hostName); builder.setMetricName(metricName); builder.setFieldName(fieldName); builder.setTagList(tagParser.parseTags(tags)); builder.setRange(Range.newRange(from, to)); - QueryParameter queryParameter = builder.build(); + MetricsQueryParameter queryParameter = builder.build(); return systemMetricDataService.getSystemMetricBoList(queryParameter); } @@ -95,7 +95,7 @@ public SystemMetricChart getSystemMetricChart( @RequestParam("to") long to) { TimeWindow timeWindow = new TimeWindow(Range.newRange(from, to), DEFAULT_TIME_WINDOW_SAMPLER); - QueryParameter.Builder builder = new QueryParameter.Builder(); + MetricsQueryParameter.Builder builder = new MetricsQueryParameter.Builder(); builder.setHostGroupName(hostGroupName); builder.setHostName(hostName); builder.setMetricName(metricName); @@ -103,7 +103,7 @@ public SystemMetricChart getSystemMetricChart( builder.setTagList(tagParser.parseTags(tags)); builder.setRange(Range.newRange(from, to)); builder.setTimeSize((int) timeWindow.getWindowSlotSize()); - QueryParameter queryParameter = builder.build(); + MetricsQueryParameter queryParameter = builder.build(); return systemMetricDataService.getSystemMetricChart(timeWindow, queryParameter); } @@ -128,7 +128,7 @@ public SystemMetricChart getSystemMetricChart( TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(interval, 200); TimeWindow timeWindow = new TimeWindow(Range.newRange(from, to), sampler); - QueryParameter.Builder builder = new QueryParameter.Builder(); + MetricsQueryParameter.Builder builder = new MetricsQueryParameter.Builder(); builder.setHostGroupName(hostGroupName); builder.setHostName(hostName); builder.setMetricName(metricName); @@ -136,7 +136,7 @@ public SystemMetricChart getSystemMetricChart( builder.setTagList(tagParser.parseTags(tags)); builder.setRange(Range.newRange(from, to)); builder.setTimePrecision(timePrecision); - QueryParameter queryParameter = builder.build(); + MetricsQueryParameter queryParameter = builder.build(); return systemMetricDataService.getSystemMetricChart(timeWindow, queryParameter); } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/UriStatController.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/UriStatController.java new file mode 100644 index 0000000000000..0eb1c421265f4 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/controller/UriStatController.java @@ -0,0 +1,85 @@ +/* + * Copyright 2022 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.metric.web.controller; + +import com.navercorp.pinpoint.common.util.StringUtils; +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.model.UriStatSummary; +import com.navercorp.pinpoint.metric.web.service.UriStatService; +import com.navercorp.pinpoint.metric.web.util.*; +import com.navercorp.pinpoint.metric.web.view.UriStatView; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +@RestController +@RequestMapping(value = "/uriStat") +public class UriStatController { + private final UriStatService uriStatService; + private final TimeWindowSampler DEFAULT_TIME_WINDOW_SAMPLER = new TimeWindowSlotCentricSampler(30000L, 200); + + public UriStatController(UriStatService uriStatService) { + this.uriStatService = Objects.requireNonNull(uriStatService); + } + + @GetMapping("top50") + public List getUriStatSummary(@RequestParam("applicationName") String applicationName, + @RequestParam(value = "agentId", required = false) String agentId, + @RequestParam("from") long from, + @RequestParam("to") long to) { + UriStatQueryParameter.Builder builder = new UriStatQueryParameter.Builder(); + builder.setApplicationName(applicationName); + builder.setRange(Range.newRange(from, to)); + + if (StringUtils.isEmpty(agentId)) { + return uriStatService.getUriStatApplicationSummary(builder.build()); + } else { + builder.setAgentId(agentId); + return uriStatService.getUriStatAgentSummary(builder.build()); + } + } + + @GetMapping("chart") + public UriStatView getCollectedUriStat(@RequestParam("applicationName") String applicationName, + @RequestParam(value = "agentId", required = false) String agentId, + @RequestParam("uri") String uri, + @RequestParam("from") long from, + @RequestParam("to") long to) { + TimeWindow timeWindow = new TimeWindow(Range.newRange(from, to), DEFAULT_TIME_WINDOW_SAMPLER); + UriStatQueryParameter.Builder builder = new UriStatQueryParameter.Builder(); + builder.setApplicationName(applicationName); + builder.setUri(uri); + builder.setRange(timeWindow.getWindowRange()); + builder.setTimeSize((int) timeWindow.getWindowSlotSize()); + builder.setTimePrecision(TimePrecision.newTimePrecision(TimeUnit.MILLISECONDS, (int) timeWindow.getWindowSlotSize())); + + List uriStats; + if (StringUtils.isEmpty(agentId)) { + uriStats = uriStatService.getCollectedUriStatApplication(builder.build()); + } else { + builder.setAgentId(agentId); + uriStats = uriStatService.getCollectedUriStatAgent(builder.build()); + } + + return new UriStatView(uri, uriStats); + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/SystemMetricDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/SystemMetricDao.java index fb0cadd17564f..9fe343df7d18f 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/SystemMetricDao.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/SystemMetricDao.java @@ -20,7 +20,7 @@ import com.navercorp.pinpoint.metric.common.model.SystemMetric; import com.navercorp.pinpoint.metric.web.model.MetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricPoint; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.model.SampledSystemMetric; import java.util.List; @@ -30,8 +30,8 @@ * @author Hyunjoon Cho */ public interface SystemMetricDao { - List getSystemMetric(QueryParameter queryParameter); - List> getSampledSystemMetric(QueryParameter queryParameter); + List getSystemMetric(MetricsQueryParameter queryParameter); + List> getSampledSystemMetric(MetricsQueryParameter queryParameter); List> getSampledSystemMetricData(MetricDataSearchKey metricDataSearchKey, MetricTag metricTag); Future>> getAsyncSampledSystemMetricData(MetricDataSearchKey metricDataSearchKey, MetricTag metricTag); diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/UriStatDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/UriStatDao.java new file mode 100644 index 0000000000000..e2df1c7eb8c8c --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/UriStatDao.java @@ -0,0 +1,30 @@ +/* + * Copyright 2022 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.metric.web.dao; + +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.model.UriStatSummary; +import com.navercorp.pinpoint.metric.web.util.UriStatQueryParameter; + +import java.util.List; + +public interface UriStatDao { + List getUriStatApplication(UriStatQueryParameter queryParameter); + List getUriStatAgent(UriStatQueryParameter queryParameter); + List getUriStatApplicationSummary(UriStatQueryParameter uriStatQueryParameter); + List getUriStatAgentSummary(UriStatQueryParameter uriStatQueryParameter); +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricDoubleDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricDoubleDao.java index 2ef15ad3fea96..a238c774a4208 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricDoubleDao.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricDoubleDao.java @@ -23,7 +23,7 @@ import com.navercorp.pinpoint.metric.web.dao.model.SystemMetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.MetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricPoint; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.model.SampledSystemMetric; import org.apache.commons.lang3.time.StopWatch; import org.apache.logging.log4j.LogManager; @@ -64,12 +64,12 @@ public void log() { } @Override - public List getSystemMetric(QueryParameter queryParameter) { + public List getSystemMetric(MetricsQueryParameter queryParameter) { return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectSystemMetric", queryParameter); } @Override - public List> getSampledSystemMetric(QueryParameter queryParameter) { + public List> getSampledSystemMetric(MetricsQueryParameter queryParameter) { return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectSampledSystemMetric", queryParameter); } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricLongDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricLongDao.java index ba1163a811202..b2ef958c5e79e 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricLongDao.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotSystemMetricLongDao.java @@ -23,7 +23,7 @@ import com.navercorp.pinpoint.metric.web.dao.model.SystemMetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.MetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricPoint; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.model.SampledSystemMetric; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,12 +53,12 @@ public PinotSystemMetricLongDao(SqlSessionTemplate sqlPinotSessionTemplate, } @Override - public List getSystemMetric(QueryParameter queryParameter) { + public List getSystemMetric(MetricsQueryParameter queryParameter) { return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectSystemMetric", queryParameter); } @Override - public List> getSampledSystemMetric(QueryParameter queryParameter) { + public List> getSampledSystemMetric(MetricsQueryParameter queryParameter) { return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectSampledSystemMetric", queryParameter); } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotUriStatDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotUriStatDao.java new file mode 100644 index 0000000000000..9b0fdc9810a81 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/dao/pinot/PinotUriStatDao.java @@ -0,0 +1,62 @@ +/* + * Copyright 2022 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.metric.web.dao.pinot; + +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.dao.UriStatDao; +import com.navercorp.pinpoint.metric.web.model.UriStatSummary; +import com.navercorp.pinpoint.metric.web.util.UriStatQueryParameter; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Objects; + +@Repository +public class PinotUriStatDao implements UriStatDao { + private final Logger logger = LogManager.getLogger(this.getClass()); + + private static final String NAMESPACE = PinotUriStatDao.class.getName() + "."; + + private final SqlSessionTemplate sqlPinotSessionTemplate; + + public PinotUriStatDao(SqlSessionTemplate sqlPinotSessionTemplate) { + this.sqlPinotSessionTemplate = Objects.requireNonNull(sqlPinotSessionTemplate, "sqlPinotSessionTemplate"); + } + + @Override + public List getUriStatApplication(UriStatQueryParameter queryParameter) { + return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectUriStatApplication", queryParameter); + } + + @Override + public List getUriStatAgent(UriStatQueryParameter queryParameter) { + return sqlPinotSessionTemplate.selectList(NAMESPACE + "selectUriStatAgentId", queryParameter); + } + + @Override + public List getUriStatApplicationSummary(UriStatQueryParameter queryParameter) { + return sqlPinotSessionTemplate.selectList(NAMESPACE + "top50UriStatApplication", queryParameter); + } + + @Override + public List getUriStatAgentSummary(UriStatQueryParameter queryParameter) { + return sqlPinotSessionTemplate.selectList(NAMESPACE + "top50UriStatAgent", queryParameter); + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatGroup.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatGroup.java new file mode 100644 index 0000000000000..07e1dea0176d6 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatGroup.java @@ -0,0 +1,92 @@ +/* + * Copyright 2022 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.metric.web.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.navercorp.pinpoint.metric.common.model.StringPrecondition; +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.view.TimeSeriesValueView; +import com.navercorp.pinpoint.metric.web.view.TimeseriesValueGroupView; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class UriStatGroup implements TimeseriesValueGroupView { + private final String uri; + + private final List values; + + public static final UriStatGroup EMPTY_URI_STAT_GROUP = new UriStatGroup(); + + public UriStatGroup() { + this.uri = StringUtils.EMPTY; + this.values = Collections.EMPTY_LIST; + } + + public UriStatGroup(String uri, List uriStats) { + this.uri = uri; + this.values = UriStatValue.createValueList(uriStats); + } + + @Override + public String getGroupName() { + return uri; + } + + @Override + public List getMetricValues() { + return values; + } + + public static class UriStatValue implements TimeSeriesValueView { + private static final String FIELD_PREFIX = "histogram"; + private final String fieldName; + private final List values; + + public static List createValueList(List uriStats) { + Objects.requireNonNull(uriStats); + List values = new ArrayList<>(); + + final int bucketSize = uriStats.get(0).getTotalHistogram().length; + for (int i = 0 ; i < bucketSize; i++) { + final int histogramIndex = i; + values.add(new UriStatValue(FIELD_PREFIX + histogramIndex, + uriStats.stream().map(e -> e.getTotalHistogram()[histogramIndex]).collect(Collectors.toList()))); + } + return values; + } + + public UriStatValue(String fieldName, List values) { + this.fieldName = StringPrecondition.requireHasLength(fieldName, "fieldName"); + this.values = Objects.requireNonNull(values); + } + + @Override + public String getFieldName() { return fieldName; } + + @Override + @JsonInclude(JsonInclude.Include.NON_NULL) + public List getTags() { return null; } + + @Override + public List getValues() { return values; } + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatSummary.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatSummary.java new file mode 100644 index 0000000000000..c3db65ea64990 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/model/UriStatSummary.java @@ -0,0 +1,58 @@ +/* + * Copyright 2022 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.metric.web.model; + +public class UriStatSummary { + private final String uri; + private final double totalCount; + private final double failureCount; + private final double maxTimeMs; + private final double avgTimeMs; + private final int version; + + public UriStatSummary(String uri, double totalCount, double failureCount, double maxTimeMs, double totalTimeMs, int version) { + this.uri = uri; + this.totalCount = totalCount; + this.failureCount = failureCount; + this.maxTimeMs = maxTimeMs; + this.avgTimeMs = (totalCount > 0 ? totalTimeMs / totalCount : 0.0d); + this.version = version; + } + + + public String getUri() { + return uri; + } + + public double getTotalCount() { + return totalCount; + } + + public double getFailureCount() { + return failureCount; + } + + public double getMaxTimeMs() { + return maxTimeMs; + } + + public double getAvgTimeMs() { + return avgTimeMs; + } + + public int getVersion() { return version; } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/mybatis/typehandler/HistogramTypeHandler.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/mybatis/typehandler/HistogramTypeHandler.java new file mode 100644 index 0000000000000..98bef9c426227 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/mybatis/typehandler/HistogramTypeHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 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.metric.web.mybatis.typehandler; + +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.TypeHandler; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class HistogramTypeHandler implements TypeHandler> { + @Override + public void setParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setObject(i, parameter); + } + + @Override + public List getResult(ResultSet rs, String columnName) throws SQLException { + return (List) rs.getObject(columnName); + } + + @Override + public List getResult(ResultSet rs, int columnIndex) throws SQLException { + return (List) rs.getObject(columnIndex); + } + + @Override + public List getResult(CallableStatement cs, int columnIndex) throws SQLException { + return (List) cs.getObject(columnIndex); + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataService.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataService.java index afcda09961db3..c87cffef483bf 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataService.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataService.java @@ -20,7 +20,7 @@ import com.navercorp.pinpoint.metric.web.model.MetricDataSearchKey; import com.navercorp.pinpoint.metric.web.model.SystemMetricData; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricChart; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.util.TimeWindow; import java.util.List; @@ -30,9 +30,9 @@ */ public interface SystemMetricDataService { - List getSystemMetricBoList(QueryParameter queryParameter); + List getSystemMetricBoList(MetricsQueryParameter queryParameter); - SystemMetricChart getSystemMetricChart(TimeWindow timeWindow, QueryParameter queryParameter); + SystemMetricChart getSystemMetricChart(TimeWindow timeWindow, MetricsQueryParameter queryParameter); SystemMetricData getCollectedMetricData(MetricDataSearchKey metricDataSearchKey, TimeWindow timeWindow); } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataServiceImpl.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataServiceImpl.java index ef70c496f7aa3..6a82e28bcac55 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataServiceImpl.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/SystemMetricDataServiceImpl.java @@ -32,7 +32,7 @@ import com.navercorp.pinpoint.metric.web.model.basic.metric.group.GroupingRule; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricPoint; import com.navercorp.pinpoint.metric.web.util.TimeWindow; -import com.navercorp.pinpoint.metric.web.util.QueryParameter; +import com.navercorp.pinpoint.metric.web.util.MetricsQueryParameter; import com.navercorp.pinpoint.metric.web.model.SampledSystemMetric; import com.navercorp.pinpoint.metric.web.model.chart.SystemMetricChart; import com.navercorp.pinpoint.metric.web.util.metric.DoubleUncollectedDataCreator; @@ -81,7 +81,7 @@ public SystemMetricDataServiceImpl(SystemMetricDao systemMetricLongDao, } @Override - public List getSystemMetricBoList(QueryParameter queryParameter) { + public List getSystemMetricBoList(MetricsQueryParameter queryParameter) { MetricDataName metricDataName = new MetricDataName(queryParameter.getMetricName(), queryParameter.getFieldName()); MetricDataType metricDataType = systemMetricDataTypeService.getMetricDataType(metricDataName); @@ -97,7 +97,7 @@ public List getSystemMetricBoList(QueryParameter queryParameter) { } @Override - public SystemMetricChart getSystemMetricChart(TimeWindow timeWindow, QueryParameter queryParameter) { + public SystemMetricChart getSystemMetricChart(TimeWindow timeWindow, MetricsQueryParameter queryParameter) { String metricName = queryParameter.getMetricName(); String fieldName = queryParameter.getFieldName(); diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatService.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatService.java new file mode 100644 index 0000000000000..224ca433511fc --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatService.java @@ -0,0 +1,30 @@ +/* + * Copyright 2022 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.metric.web.service; + +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.model.UriStatSummary; +import com.navercorp.pinpoint.metric.web.util.UriStatQueryParameter; + +import java.util.List; + +public interface UriStatService { + List getCollectedUriStatApplication(UriStatQueryParameter queryParameter); + List getCollectedUriStatAgent(UriStatQueryParameter queryParameter); + List getUriStatApplicationSummary(UriStatQueryParameter queryParameter); + List getUriStatAgentSummary(UriStatQueryParameter queryParameter); +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatServiceImpl.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatServiceImpl.java new file mode 100644 index 0000000000000..d57513267226e --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/service/UriStatServiceImpl.java @@ -0,0 +1,56 @@ +/* + * Copyright 2022 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.metric.web.service; + +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.dao.UriStatDao; +import com.navercorp.pinpoint.metric.web.model.UriStatSummary; +import com.navercorp.pinpoint.metric.web.util.UriStatQueryParameter; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; + +@Service +public class UriStatServiceImpl implements UriStatService { + + private UriStatDao uriStatDao; + + public UriStatServiceImpl(UriStatDao uriStatDao) { + this.uriStatDao = Objects.requireNonNull(uriStatDao); + } + + @Override + public List getCollectedUriStatApplication(UriStatQueryParameter queryParameter) { + return uriStatDao.getUriStatApplication(queryParameter); + } + + @Override + public List getCollectedUriStatAgent(UriStatQueryParameter queryParameter) { + return uriStatDao.getUriStatAgent(queryParameter); + } + + @Override + public List getUriStatApplicationSummary(UriStatQueryParameter queryParameter) { + return uriStatDao.getUriStatApplicationSummary(queryParameter); + } + + @Override + public List getUriStatAgentSummary(UriStatQueryParameter queryParameter) { + return uriStatDao.getUriStatAgentSummary(queryParameter); + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/MetricsQueryParameter.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/MetricsQueryParameter.java new file mode 100644 index 0000000000000..8b6174e8aabf9 --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/MetricsQueryParameter.java @@ -0,0 +1,102 @@ +/* + * Copyright 2021 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.metric.web.util; + + +import com.navercorp.pinpoint.metric.common.model.Tag; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * @author Hyunjoon Cho + */ +public class MetricsQueryParameter extends QueryParameter { + private final String hostGroupName; + private final String hostName; + private final String metricName; + private final String fieldName; + + private final List tagList; + + public MetricsQueryParameter(Builder builder) { + super(builder.range, builder.timePrecision, builder.limit); + this.hostGroupName = builder.hostGroupName; + this.hostName = builder.hostName; + this.metricName = builder.metricName; + this.fieldName = builder.fieldName; + this.tagList = builder.tagList; + } + + public String getHostGroupName() { + return hostGroupName; + } + + public String getHostName() { + return hostName; + } + + public String getMetricName() { + return metricName; + } + + public String getFieldName() { + return fieldName; + } + + public List getTagList() { + return tagList; + } + + public static class Builder extends QueryParameter.Builder { + private String hostGroupName; + private String hostName; + private String metricName; + private String fieldName; + private List tagList; + + public void setHostGroupName(String hostGroupName) { + this.hostGroupName = Objects.requireNonNull(hostGroupName, "hostGroupName"); + } + + public void setHostName(String hostName) { + this.hostName = Objects.requireNonNull(hostName, "hostName"); + } + + public void setMetricName(String metricName) { + this.metricName = Objects.requireNonNull(metricName, "metricName"); + } + + public void setFieldName(String fieldName) { + this.fieldName = Objects.requireNonNull(fieldName, "fieldName"); + } + + public void setTagList(List tagList) { + this.tagList = tagList; + } + + public MetricsQueryParameter build() { + if (timePrecision == null) { + this.timePrecision = TimePrecision.newTimePrecision(TimeUnit.MILLISECONDS, 10000); + } + this.limit = estimateLimit(); + + return new MetricsQueryParameter(this); + } + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/QueryParameter.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/QueryParameter.java index 851e80437560b..dc839d30aba1d 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/QueryParameter.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/QueryParameter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 NAVER Corp. + * Copyright 2022 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 + * 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, @@ -16,62 +16,19 @@ package com.navercorp.pinpoint.metric.web.util; +public abstract class QueryParameter { + protected static final int TAG_SET_COUNT = 10; + protected final Range range; + protected final TimePrecision timePrecision; + protected final long limit; -import com.navercorp.pinpoint.metric.common.model.Tag; - -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * @author Hyunjoon Cho - */ -public class QueryParameter { - private static final int TAG_SET_COUNT = 10; - - private final String hostGroupName; - private final String hostName; - private final String metricName; - private final String fieldName; - private final List tagList; - private final Range range; - private final TimePrecision timePrecision; - private final long limit; - - public QueryParameter(Builder builder) { - this.hostGroupName = builder.hostGroupName; - this.hostName = builder.hostName; - this.metricName = builder.metricName; - this.fieldName = builder.fieldName; - this.tagList = builder.tagList; - this.range = builder.range; - this.timePrecision = builder.timePrecision; - this.limit = builder.limit; - } - - public String getHostGroupName() { - return hostGroupName; + protected QueryParameter(Range range, TimePrecision timePrecision, long limit) { + this.range = range; + this.timePrecision = timePrecision; + this.limit = limit; } - public String getHostName() { - return hostName; - } - - public String getMetricName() { - return metricName; - } - - public String getFieldName() { - return fieldName; - } - - public List getTagList() { - return tagList; - } - - public Range getRange() { - return range; - } + public Range getRange() { return range; } public TimePrecision getTimePrecision() { return timePrecision; @@ -81,36 +38,11 @@ public long getLimit() { return limit; } - public static class Builder { - private String hostGroupName; - private String hostName; - private String metricName; - private String fieldName; - private List tagList; - private Range range; - private TimePrecision timePrecision; - private int timeSize = 10000; - private long limit; - - public void setHostGroupName(String hostGroupName) { - this.hostGroupName = Objects.requireNonNull(hostGroupName, "hostGroupName"); - } - - public void setHostName(String hostName) { - this.hostName = Objects.requireNonNull(hostName, "hostName"); - } - - public void setMetricName(String metricName) { - this.metricName = Objects.requireNonNull(metricName, "metricName"); - } - - public void setFieldName(String fieldName) { - this.fieldName = Objects.requireNonNull(fieldName, "fieldName"); - } - - public void setTagList(List tagList) { - this.tagList = tagList; - } + public static abstract class Builder { + protected Range range; + protected TimePrecision timePrecision; + protected int timeSize = 10000; + protected long limit; public void setRange(Range range) { this.range = range; @@ -120,21 +52,12 @@ public void setTimePrecision(TimePrecision timePrecision) { this.timePrecision = timePrecision; } - public void setTimeSize(int timeSize) { - this.timeSize = timeSize; - } + public void setTimeSize(int timeSize) { this.timeSize = timeSize; } public long estimateLimit() { return (range.getRange() / timePrecision.getInterval() + 1) * TAG_SET_COUNT; } - public QueryParameter build() { - if (timePrecision == null) { - this.timePrecision = TimePrecision.newTimePrecision(TimeUnit.MILLISECONDS, timeSize); - } - this.limit = estimateLimit(); - - return new QueryParameter(this); - } + abstract public QueryParameter build(); } } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/UriStatQueryParameter.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/UriStatQueryParameter.java new file mode 100644 index 0000000000000..526fe898fcb2a --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/util/UriStatQueryParameter.java @@ -0,0 +1,64 @@ +/* + * Copyright 2022 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.metric.web.util; + +import java.util.concurrent.TimeUnit; + +public class UriStatQueryParameter extends QueryParameter { + private final String serviceName; + private final String applicationName; + private final String agentId; + private final String uri; + + protected UriStatQueryParameter(Builder builder) { + super(builder.range, builder.timePrecision, builder.limit); + this.serviceName = builder.serviceName; + this.applicationName = builder.applicationName; + this.agentId = builder.agentId; + this.uri = builder.uri; + } + + public static class Builder extends QueryParameter.Builder { + private String serviceName; + private String applicationName; + private String agentId; + private String uri; + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public void setUri(String uri) { this.uri = uri; } + + @Override + public UriStatQueryParameter build() { + if (timePrecision == null) { + this.timePrecision = TimePrecision.newTimePrecision(TimeUnit.MILLISECONDS, 30000); + } + this.limit = estimateLimit(); + return new UriStatQueryParameter(this); + } + } +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/SystemMetricView.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/SystemMetricView.java index 139a2a58b3021..b4006d7e166d6 100644 --- a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/SystemMetricView.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/SystemMetricView.java @@ -9,44 +9,50 @@ import java.util.Objects; import java.util.stream.Collectors; -public class SystemMetricView { +public class SystemMetricView implements TimeSeriesView { private final SystemMetricData systemMetricData; public SystemMetricView(SystemMetricData systemMetricData) { this.systemMetricData = Objects.requireNonNull(systemMetricData, "systemMetricData"); } + @Override public String getTitle() { return systemMetricData.getTitle(); } + @Override public String getUnit() { return systemMetricData.getUnit(); } + @Override public List getTimestamp() { return systemMetricData.getTimeStampList(); } - public List getMetricValueGroups() { + @Override + public List getMetricValueGroups() { return systemMetricData.getMetricValueGroupList() .stream() .map(MetricValueGroupView::new) .collect(Collectors.toList()); } - public static class MetricValueGroupView { + public static class MetricValueGroupView implements TimeseriesValueGroupView { private final MetricValueGroup value; public MetricValueGroupView(MetricValueGroup value) { this.value = Objects.requireNonNull(value, "value"); } + @Override public String getGroupName() { return value.getGroupName(); } - public List getMetricValues() { + @Override + public List getMetricValues() { return value.getMetricValueList() .stream() .map(MetricValueView::new) @@ -54,7 +60,7 @@ public List getMetricValues() { } } - public static class MetricValueView { + public static class MetricValueView implements TimeSeriesValueView { private final MetricValue value; public MetricValueView(MetricValue value) { diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesValueView.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesValueView.java new file mode 100644 index 0000000000000..57e50621ed5de --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesValueView.java @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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.metric.web.view; + +import java.util.List; + +public interface TimeSeriesValueView { + String getFieldName(); + List getTags(); + List getValues(); +} diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesView.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesView.java new file mode 100644 index 0000000000000..9cc3504966bef --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeSeriesView.java @@ -0,0 +1,29 @@ +/* + * Copyright 2022 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.metric.web.view; + +import java.util.List; + +public interface TimeSeriesView { + String getTitle(); + + String getUnit(); + + List getTimestamp(); + + List getMetricValueGroups(); + +} diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentUriStatDao.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeseriesValueGroupView.java similarity index 68% rename from collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentUriStatDao.java rename to metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeseriesValueGroupView.java index 124643a037cc8..3cb3013d70072 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/dao/AgentUriStatDao.java +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/TimeseriesValueGroupView.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 NAVER Corp. + * Copyright 2022 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.navercorp.pinpoint.metric.web.view; -package com.navercorp.pinpoint.collector.dao; +import java.util.List; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; +public interface TimeseriesValueGroupView { + String getGroupName(); -/** - * @author Taejin Koo - */ -public interface AgentUriStatDao { - - void insert(AgentUriStatBo agentUriStatBo); + List getMetricValues(); } diff --git a/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/UriStatView.java b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/UriStatView.java new file mode 100644 index 0000000000000..e16310147838d --- /dev/null +++ b/metric-module/metric/src/main/java/com/navercorp/pinpoint/metric/web/view/UriStatView.java @@ -0,0 +1,58 @@ +/* + * Copyright 2022 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.metric.web.view; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.navercorp.pinpoint.metric.common.model.UriStat; +import com.navercorp.pinpoint.metric.web.model.UriStatGroup; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class UriStatView implements TimeSeriesView { + + private final List timestampList; + + private final List uriStats = new ArrayList<>(); + + public UriStatView(String uri, List uriStats) { + Objects.requireNonNull(uriStats, "uriStats"); + this.timestampList = uriStats.stream().map(UriStat::getTimestamp).collect(Collectors.toList()); + if (uriStats.isEmpty()) { + this.uriStats.add(UriStatGroup.EMPTY_URI_STAT_GROUP); + } else { + this.uriStats.add(new UriStatGroup(uri, uriStats)); + } + } + + @Override + public String getTitle() { return "uriStat"; } + + @Override + @JsonInclude(JsonInclude.Include.NON_NULL) + public String getUnit() { return null; } + + @Override + public List getTimestamp() { return timestampList;} + + @Override + public List getMetricValueGroups() { + return uriStats; + } + +} diff --git a/metric-module/metric/src/main/pinot/pinot-urlStat-schema.json b/metric-module/metric/src/main/pinot/pinot-urlStat-schema.json new file mode 100644 index 0000000000000..d6439c9df0926 --- /dev/null +++ b/metric-module/metric/src/main/pinot/pinot-urlStat-schema.json @@ -0,0 +1,112 @@ +{ + "schemaName": "urlStat", + "dimensionFieldSpecs": [ + { + "name": "serviceName", + "dataType": "STRING", + "defaultNullValue": "" + }, + { + "name": "applicationName", + "dataType": "STRING" + }, + { + "name": "agentId", + "dataType": "STRING" + }, + { + "name": "uri", + "dataType": "STRING" + }, + { + "name": "version", + "dataType": "INT" + } + ], + "metricFieldSpecs": [ + { + "name": "count", + "dataType": "LONG" + }, + { + "name": "maxLatencyMs", + "dataType": "LONG" + }, + { + "name": "totalTimeMs", + "dataType": "LONG" + }, + { + "name": "totalHistogram0", + "dataType": "INT" + }, + { + "name": "totalHistogram1", + "dataType": "INT" + }, + { + "name": "totalHistogram2", + "dataType": "INT" + }, + { + "name": "totalHistogram3", + "dataType": "INT" + }, + { + "name": "totalHistogram4", + "dataType": "INT" + }, + { + "name": "totalHistogram5", + "dataType": "INT" + }, + { + "name": "totalHistogram6", + "dataType": "INT" + }, + { + "name": "totalHistogram7", + "dataType": "INT" + }, + { + "name": "failureHistogram0", + "dataType": "INT" + }, + { + "name": "failureHistogram1", + "dataType": "INT" + }, + { + "name": "failureHistogram2", + "dataType": "INT" + }, + { + "name": "failureHistogram3", + "dataType": "INT" + }, + { + "name": "failureHistogram4", + "dataType": "INT" + }, + { + "name": "failureHistogram5", + "dataType": "INT" + }, + { + "name": "failureHistogram6", + "dataType": "INT" + }, + { + "name": "failureHistogram7", + "dataType": "INT" + } + ], + "dateTimeFieldSpecs": [ + { + "name": "timestamp", + "dataType": "LONG", + "format": "1:MILLISECONDS:EPOCH", + "granularity": "1:MILLISECONDS" + } + ] +} \ No newline at end of file diff --git a/metric-module/metric/src/main/pinot/pinot-urlStat-table.json b/metric-module/metric/src/main/pinot/pinot-urlStat-table.json new file mode 100644 index 0000000000000..1eaa28566028c --- /dev/null +++ b/metric-module/metric/src/main/pinot/pinot-urlStat-table.json @@ -0,0 +1,33 @@ +{ + "tableName": "uriStat", + "tableType": "REALTIME", + "segmentsConfig": { + "timeColumnName": "timestamp", + "timeType": "MILLISECONDS", + "schemaName": "uriStat", + "replicasPerPartition": "1", + "retentionTimeUnit": "DAYS", + "retentionTimeValue": "21" + }, + "tenants": {}, + "tableIndexConfig": { + "sortedColumn": ["serviceName", "applicationName", "agentId", "uri"], + "invertedIndexColumns": ["totalHistogram0", "totalHistogram1", "totalHistogram2", "totalHistogram3", "totalHistogram4", "totalHistogram5", "totalHistogram6", "totalHistogram7", "failureHistogram0", "failureHistogram1", "failureHistogram2", "failureHistogram3", "failureHistogram4", "failureHistogram5", "failureHistogram6", "failureHistogram7"], + "loadMode": "MMAP", + "nullHandlingEnabled": true, + "streamConfigs": { + "streamType": "kafka", + "stream.kafka.consumer.type": "lowlevel", + "stream.kafka.topic.name": "url-stat", + "stream.kafka.decoder.class.name": "org.apache.pinot.plugin.inputformat.json.StreamJSONMessageDecoder", + "stream.kafka.consumer.factory.class.name": "org.apache.pinot.plugin.stream.kafka20.KafkaConsumerFactory", + "stream.kafka.broker.list": "localhost:19092", + "realtime.segment.flush.threshold.rows": "0", + "realtime.segment.flush.threshold.time": "24h", + "realtime.segment.flush.threshold.segment.size": "64M", + "stream.kafka.consumer.prop.auto.offset.reset": "smallest" + } + }, + "metadata": { + } +} diff --git a/metric-module/metric/src/main/resources/pinot-collector/applicationContext-collector-pinot-kafka.xml b/metric-module/metric/src/main/resources/pinot-collector/applicationContext-collector-pinot-kafka.xml index 1c270e223c0e5..06aa1970c7fb2 100644 --- a/metric-module/metric/src/main/resources/pinot-collector/applicationContext-collector-pinot-kafka.xml +++ b/metric-module/metric/src/main/resources/pinot-collector/applicationContext-collector-pinot-kafka.xml @@ -31,4 +31,8 @@ + + + + \ No newline at end of file diff --git a/metric-module/metric/src/main/resources/pinot-collector/kafka-topic.properties b/metric-module/metric/src/main/resources/pinot-collector/kafka-topic.properties index 38ea8bfccdb33..29ba290f3cffd 100644 --- a/metric-module/metric/src/main/resources/pinot-collector/kafka-topic.properties +++ b/metric-module/metric/src/main/resources/pinot-collector/kafka-topic.properties @@ -1,4 +1,5 @@ kafka.long.topic=system-metric-long kafka.double.topic=system-metric-double kafka.metadata.tag.topic=system-metric-tag -kafka.metadata.data.type.topic=system-metric-data-type \ No newline at end of file +kafka.metadata.data.type.topic=system-metric-data-type +kafka.uri.topic=url-stat \ No newline at end of file diff --git a/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricDoubleMapper.xml b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricDoubleMapper.xml index 3cbbd5c1dbc25..2a065a01b52e3 100644 --- a/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricDoubleMapper.xml +++ b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricDoubleMapper.xml @@ -14,7 +14,7 @@ - SELECT metricName, hostName, fieldName, @@ -47,7 +47,7 @@ - SELECT AVG(fieldValue) AS avgValue, DATETIME_CONVERT(eventTime, '1:MILLISECONDS:EPOCH', '1:MILLISECONDS:EPOCH', '#{timePrecision.timeSize}:${timePrecision.timeUnit}') AS avgTime, diff --git a/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricLongMapper.xml b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricLongMapper.xml index 1b80bc0b79621..3d1c019603fd8 100644 --- a/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricLongMapper.xml +++ b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/SystemMetricLongMapper.xml @@ -14,7 +14,7 @@ - SELECT metricName, hostName, @@ -48,7 +48,7 @@ - SELECT AVG(fieldValue) AS avgValue, DATETIME_CONVERT(eventTime, '1:MILLISECONDS:EPOCH', '1:MILLISECONDS:EPOCH', '#{timePrecision.timeSize}:${timePrecision.timeUnit}') AS avgTime, diff --git a/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/UriStatMapper.xml b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/UriStatMapper.xml new file mode 100644 index 0000000000000..2c86362b5ae8c --- /dev/null +++ b/metric-module/metric/src/main/resources/pinot-web/mapper/pinot/UriStatMapper.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/metric-module/metric/src/main/resources/pinot-web/mybatis-pinot-config.xml b/metric-module/metric/src/main/resources/pinot-web/mybatis-pinot-config.xml index 06e1e1b262ca4..92699c2712da0 100644 --- a/metric-module/metric/src/main/resources/pinot-web/mybatis-pinot-config.xml +++ b/metric-module/metric/src/main/resources/pinot-web/mybatis-pinot-config.xml @@ -32,12 +32,13 @@ - + + @@ -52,6 +53,10 @@ + + + + @@ -62,6 +67,7 @@ + diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverter.java index bf0578da4d218..c3b8c4008d446 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverter.java @@ -90,7 +90,7 @@ private PUriHistogram createPUriHistogram(UriStatHistogram uriStatHistogram) { long max = uriStatHistogram.getMax(); builder.setCount(count); - builder.setAvg(total / count); + builder.setTotal(total); builder.setMax(max); int[] timestampHistograms = uriStatHistogram.getTimestampHistogram(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/AsyncQueueingUriStatStorage.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/AsyncQueueingUriStatStorage.java index f08604d7b3278..5e6ec67c512bb 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/AsyncQueueingUriStatStorage.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/storage/AsyncQueueingUriStatStorage.java @@ -77,7 +77,7 @@ protected void pollTimeout(long timeout) { private static class ExecutorListener implements AsyncQueueingExecutorListener { - private static final int DEFAULT_COLLECT_INTERVAL = 60000; // 1minute + private static final int DEFAULT_COLLECT_INTERVAL = 30000; // 30s private final Object lock = new Object(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverterTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverterTest.java index 633b726b22f6b..f5e084049e195 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverterTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/grpc/GrpcUriStatMessageConverterTest.java @@ -83,7 +83,7 @@ private void assertData(List uriStatInfoList, List ea private void assertData(List expected, PUriHistogram actual) { Assertions.assertEquals(expected.size(), actual.getCount()); Assertions.assertEquals(getMax(expected), actual.getMax()); - Assertions.assertEquals(new Double(getAvg(expected)).longValue(), new Double(actual.getAvg()).longValue()); + Assertions.assertEquals(getTotal(expected), actual.getTotal()); List histogramList = actual.getHistogramList(); for (int i = 0; i < histogramList.size(); i++) { @@ -101,12 +101,8 @@ private long getMax(List expected) { return max; } - private double getAvg(List expected) { - long total = 0l; - for (UriStatInfo uriStatInfo : expected) { - total += uriStatInfo.getElapsed(); - } - return total / expected.size(); + private long getTotal(List expected) { + return expected.stream().mapToLong(e -> e.getElapsed()).sum(); } private int getBucketCount(List uriStatInfoList, UriStatHistogramBucket type) { diff --git a/quickstart/testapp/src/main/java/com/navercorp/pinpoint/testapp/controller/SimpleController.java b/quickstart/testapp/src/main/java/com/navercorp/pinpoint/testapp/controller/SimpleController.java index c88dabed10e00..17f446e958915 100644 --- a/quickstart/testapp/src/main/java/com/navercorp/pinpoint/testapp/controller/SimpleController.java +++ b/quickstart/testapp/src/main/java/com/navercorp/pinpoint/testapp/controller/SimpleController.java @@ -54,4 +54,26 @@ public Map sleep7() throws InterruptedException { return map; } + + @RequestMapping("/randomResponseTime/**") + @Description("Waits for random time and then returns") + public Map randomResponseTime() throws InterruptedException { + double a = Math.random() * 10000; + double fail = Math.random() * 10; + + Thread.sleep(Math.round(a)); + + if ( fail < 2.0 ) { + throw new RuntimeException(); + } + Map map = new HashMap(); + map.put("message", "ok"); + + return map; + } + + @RequestMapping("/fails") + public void fails() throws Exception { + throw new RuntimeException(); + } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/config/SampledAgentStatDaoConfiguration.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/config/SampledAgentStatDaoConfiguration.java index b768bd3fefd15..b0a298efb02b2 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/config/SampledAgentStatDaoConfiguration.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/config/SampledAgentStatDaoConfiguration.java @@ -4,13 +4,11 @@ import com.navercorp.pinpoint.common.server.bo.stat.ActiveTraceBo; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatType; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.CpuLoadBo; import com.navercorp.pinpoint.common.server.bo.stat.DataSourceBo; import com.navercorp.pinpoint.common.server.bo.stat.DataSourceListBo; import com.navercorp.pinpoint.common.server.bo.stat.DeadlockThreadCountBo; import com.navercorp.pinpoint.common.server.bo.stat.DirectBufferBo; -import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.FileDescriptorBo; import com.navercorp.pinpoint.common.server.bo.stat.JvmGcBo; import com.navercorp.pinpoint.common.server.bo.stat.JvmGcDetailedBo; @@ -21,20 +19,17 @@ import com.navercorp.pinpoint.web.dao.SampledAgentStatDao; import com.navercorp.pinpoint.web.dao.hbase.stat.DefaultSampledAgentStatDao; import com.navercorp.pinpoint.web.dao.hbase.stat.HbaseAgentStatDaoOperations; -import com.navercorp.pinpoint.web.dao.hbase.stat.HbaseSampledAgentUriStatDao; import com.navercorp.pinpoint.web.dao.hbase.stat.HbaseSampledDataSourceDao; import com.navercorp.pinpoint.web.dao.hbase.stat.SampledAgentStatResultExtractorSupplier; import com.navercorp.pinpoint.web.dao.hbase.stat.SampledResultsExtractorSupplier; import com.navercorp.pinpoint.web.mapper.stat.sampling.sampler.AgentStatSampler; import com.navercorp.pinpoint.web.vo.stat.SampledActiveTrace; import com.navercorp.pinpoint.web.vo.stat.SampledAgentStatDataPoint; -import com.navercorp.pinpoint.web.vo.stat.SampledAgentUriStat; import com.navercorp.pinpoint.web.vo.stat.SampledCpuLoad; import com.navercorp.pinpoint.web.vo.stat.SampledDataSource; import com.navercorp.pinpoint.web.vo.stat.SampledDataSourceList; import com.navercorp.pinpoint.web.vo.stat.SampledDeadlock; import com.navercorp.pinpoint.web.vo.stat.SampledDirectBuffer; -import com.navercorp.pinpoint.web.vo.stat.SampledEachUriStatBo; import com.navercorp.pinpoint.web.vo.stat.SampledFileDescriptor; import com.navercorp.pinpoint.web.vo.stat.SampledJvmGc; import com.navercorp.pinpoint.web.vo.stat.SampledJvmGcDetailed; @@ -42,7 +37,6 @@ import com.navercorp.pinpoint.web.vo.stat.SampledResponseTime; import com.navercorp.pinpoint.web.vo.stat.SampledTotalThreadCount; import com.navercorp.pinpoint.web.vo.stat.SampledTransaction; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -145,10 +139,4 @@ public SampledAgentStatDao getSampledLoadedClassCountDa return newSampledDao(AgentStatType.LOADED_CLASS, decoder, sampler); } -// @Bean - public SampledAgentStatDao getSampledAgentUriStatDao(@Qualifier("agentUriDaoOperations") HbaseAgentStatDaoOperations operations, - AgentStatDecoder decoder, - AgentStatSampler sampler) { - return new HbaseSampledAgentUriStatDao(operations, decoder, sampler); - } } \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/stat/HbaseSampledAgentUriStatDao.java b/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/stat/HbaseSampledAgentUriStatDao.java deleted file mode 100644 index 511607362d9af..0000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/dao/hbase/stat/HbaseSampledAgentUriStatDao.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2020 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.dao.hbase.stat; - -import com.navercorp.pinpoint.common.hbase.ResultsExtractor; -import com.navercorp.pinpoint.common.server.bo.codec.stat.AgentStatDecoder; -import com.navercorp.pinpoint.common.server.bo.stat.AgentStatType; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; -import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; -import com.navercorp.pinpoint.common.server.util.time.Range; -import com.navercorp.pinpoint.web.dao.SampledAgentStatDao; -import com.navercorp.pinpoint.web.mapper.stat.AgentStatMapperV2; -import com.navercorp.pinpoint.web.mapper.stat.SampledUriStatResultExtractor; -import com.navercorp.pinpoint.web.mapper.stat.sampling.sampler.AgentStatSampler; -import com.navercorp.pinpoint.web.util.TimeWindow; -import com.navercorp.pinpoint.web.vo.stat.SampledAgentUriStat; -import com.navercorp.pinpoint.web.vo.stat.SampledEachUriStatBo; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -@Repository -public class HbaseSampledAgentUriStatDao implements SampledAgentStatDao { - - private final AgentStatType statType = AgentStatType.URI; - private final HbaseAgentStatDaoOperations operations; - - private final AgentStatDecoder decoder; - private final AgentStatSampler sampler; - - public HbaseSampledAgentUriStatDao(@Qualifier("agentUriDaoOperations") HbaseAgentStatDaoOperations operations, - AgentStatDecoder decoder, - AgentStatSampler sampler) { - this.operations = Objects.requireNonNull(operations, "operations"); - this.decoder = Objects.requireNonNull(decoder, "decoder"); - this.sampler = Objects.requireNonNull(sampler, "sampler"); - } - - @Override - public List getSampledAgentStatList(String agentId, TimeWindow timeWindow) { - Range range = timeWindow.getWindowSlotRange(); - - AgentStatMapperV2 mapper = operations.createRowMapper(decoder, range); - ResultsExtractor> resultExtractor = getResultExtractor(timeWindow, mapper); - return operations.getSampledAgentStatList(statType, resultExtractor, agentId, range); - } - - private ResultsExtractor> getResultExtractor(TimeWindow timeWindow, AgentStatMapperV2 mapper) { - return new SampledUriStatResultExtractor(timeWindow, mapper, sampler); - } - - @Override - public String getChartType() { - return statType.getChartType(); - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/SampledUriStatResultExtractor.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/SampledUriStatResultExtractor.java deleted file mode 100644 index ca4d167b69d42..0000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/SampledUriStatResultExtractor.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2020 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.mapper.stat; - -import com.navercorp.pinpoint.common.hbase.ResultsExtractor; -import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; -import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; -import com.navercorp.pinpoint.common.util.CollectionUtils; -import com.navercorp.pinpoint.web.mapper.stat.sampling.AgentStatSamplingHandler; -import com.navercorp.pinpoint.web.mapper.stat.sampling.EagerSamplingHandler; -import com.navercorp.pinpoint.web.mapper.stat.sampling.sampler.AgentStatSampler; -import com.navercorp.pinpoint.web.util.TimeWindow; -import com.navercorp.pinpoint.web.vo.stat.SampledAgentUriStat; -import com.navercorp.pinpoint.web.vo.stat.SampledEachUriStatBo; - -import org.apache.hadoop.hbase.client.Result; -import org.apache.hadoop.hbase.client.ResultScanner; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Taejin Koo - */ -public class SampledUriStatResultExtractor implements ResultsExtractor> { - - private final TimeWindow timeWindow; - private final AgentStatMapper rowMapper; - private final AgentStatSampler sampler; - - public SampledUriStatResultExtractor(TimeWindow timeWindow, AgentStatMapper rowMapper, AgentStatSampler sampler) { - if (timeWindow.getWindowRangeCount() > Integer.MAX_VALUE) { - throw new IllegalArgumentException("range yields too many timeslots"); - } - this.timeWindow = timeWindow; - this.rowMapper = rowMapper; - this.sampler = sampler; - } - - @Override - public List extractData(ResultScanner results) throws Exception { - // divide by uri - Map> eachUriStatBoListMap = divideByUri(results); - - List result = new ArrayList<>(eachUriStatBoListMap.size()); - - for (List eachUriStatBoList : eachUriStatBoListMap.values()) { - result.add(getSampleData(eachUriStatBoList)); - } - - return result; - } - - private Map> divideByUri(ResultScanner results) throws Exception { - Map> eachUriStatBoListMap = new HashMap<>(); - - int rowNum = 0; - for (Result result : results) { - for (AgentUriStatBo agentUriStatBo : this.rowMapper.mapRow(result, rowNum++)) { - List eachUriStatBoList = agentUriStatBo.getEachUriStatBoList(); - if (CollectionUtils.isEmpty(eachUriStatBoList)) { - continue; - } - - final String agentId = agentUriStatBo.getAgentId(); - final long startTimestamp = agentUriStatBo.getStartTimestamp(); - final long timestamp = agentUriStatBo.getTimestamp(); - - for (EachUriStatBo eachUriStatBo : eachUriStatBoList) { - String uri = eachUriStatBo.getUri(); - - List eachUriStatBos = eachUriStatBoListMap.computeIfAbsent(uri, k -> new ArrayList<>()); - setAgentStatDataPointBaseData(eachUriStatBo, agentId, startTimestamp, timestamp); - - eachUriStatBos.add(eachUriStatBo); - } - } - } - return eachUriStatBoListMap; - } - - private void setAgentStatDataPointBaseData(AgentStatDataPoint statDataPoint, String agentId, long startTimestamp, long timestamp) { - statDataPoint.setAgentId(agentId); - statDataPoint.setStartTimestamp(startTimestamp); - statDataPoint.setTimestamp(timestamp); - } - - private SampledAgentUriStat getSampleData(List eachUriStatBos) { - eachUriStatBos.sort(Comparator.comparingLong(EachUriStatBo::getTimestamp).reversed()); - - AgentStatSamplingHandler samplingHandler = new EagerSamplingHandler<>(timeWindow, sampler); - for (EachUriStatBo eachUriStatBo : eachUriStatBos) { - samplingHandler.addDataPoint(eachUriStatBo); - } - - List sampledDataPoints = samplingHandler.getSampledDataPoints(); - - SampledAgentUriStat sampledAgentUriStat = new SampledAgentUriStat(sampledDataPoints); - return sampledAgentUriStat; - } - -} - diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSampler.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSampler.java deleted file mode 100644 index 907865bd02a42..0000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSampler.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2020 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.mapper.stat.sampling.sampler; - -import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; -import com.navercorp.pinpoint.common.server.bo.stat.UriStatHistogram; -import com.navercorp.pinpoint.common.trace.UriStatHistogramBucket; -import com.navercorp.pinpoint.web.vo.stat.SampledEachUriStatBo; -import com.navercorp.pinpoint.web.vo.stat.SampledUriStatHistogramBo; -import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentStatPoint; - -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.Collections; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * @author Taejin Koo - */ -@Component -public class AgentUriStatSampler implements AgentStatSampler { - - private static final AgentStatPointFactory AGENT_STAT_POINT_FACTORY = new AgentStatPointFactory(0, 0L, 0D); - - private static Map EMPTY_URI_STAT_HISTOGRAM_MAP; - - private static final EnumSet BUCKETS = EnumSet.allOf(UriStatHistogramBucket.class); - - static { - Map map = new HashMap<>(); - for (UriStatHistogramBucket value : UriStatHistogramBucket.values()) { - map.put(value, 0); - } - EMPTY_URI_STAT_HISTOGRAM_MAP = Collections.unmodifiableMap(map); - } - - @Override - public SampledEachUriStatBo sampleDataPoints(int index, long timestamp, List eachUriStatBoList, EachUriStatBo previousDataPoint) { - if (CollectionUtils.isEmpty(eachUriStatBoList)) { - return null; - } - - final String uri = getUri(eachUriStatBoList); - - List totalUriStatHistogramList = eachUriStatBoList.stream() - .map(EachUriStatBo::getTotalHistogram) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - SampledUriStatHistogramBo sampledTotalUriStatHistogramBo = create(timestamp, totalUriStatHistogramList); - - List failedUriStatHistogramList = eachUriStatBoList.stream() - .map(EachUriStatBo::getFailedHistogram) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - SampledUriStatHistogramBo failedSampledUriStatHistogramBo = create(timestamp, failedUriStatHistogramList); - - SampledEachUriStatBo sampledEachUriStatBo = new SampledEachUriStatBo(uri, sampledTotalUriStatHistogramBo, failedSampledUriStatHistogramBo); - return sampledEachUriStatBo; - } - - private String getUri(List eachUriStatBoList) { - EachUriStatBo representative = CollectionUtils.firstElement(eachUriStatBoList); - return representative.getUri(); - } - - private SampledUriStatHistogramBo create(long timestamp, List uriStatHistogramList) { - if (CollectionUtils.isEmpty(uriStatHistogramList)) { - return createEmptySampledUriStatHistogramBo(timestamp); - } - - final List countList = uriStatHistogramList.stream().map(UriStatHistogram::getCount).collect(Collectors.toList()); - final AgentStatPoint countPoint = AGENT_STAT_POINT_FACTORY.createIntPoint(timestamp, countList); - - final List maxElapsedTimeList = uriStatHistogramList.stream().map(UriStatHistogram::getMax).collect(Collectors.toList()); - final AgentStatPoint maxElapsedTimePoint = AGENT_STAT_POINT_FACTORY.createLongPoint(timestamp, maxElapsedTimeList); - - final List avgElapsedTimeList = uriStatHistogramList.stream().map(UriStatHistogram::getAvg).collect(Collectors.toList()); - final AgentStatPoint avgElapsedTimePoint = AGENT_STAT_POINT_FACTORY.createDoublePoint(timestamp, avgElapsedTimeList, 3); - - final Map uriStatHistogramCountMap = createHistogramBucketCountMap(uriStatHistogramList); - - long totalElapsedTime = 0; - for (int i = 0; i < countList.size(); i++) { - totalElapsedTime += (countList.get(i) * avgElapsedTimeList.get(i)); - } - - SampledUriStatHistogramBo sampledUriStatHistogramBo = new SampledUriStatHistogramBo(countPoint, maxElapsedTimePoint, avgElapsedTimePoint, uriStatHistogramCountMap, totalElapsedTime); - return sampledUriStatHistogramBo; - } - - private Map createHistogramBucketCountMap(List uriStatHistogramList) { - int[] mergedHistogramValue = new int[UriStatHistogramBucket.getBucketSize()]; - for (UriStatHistogram uriStatHistogram : uriStatHistogramList) { - int[] timestampHistogram = uriStatHistogram.getTimestampHistogram(); - for (int i = 0; i < mergedHistogramValue.length; i++) { - mergedHistogramValue[i] += timestampHistogram[i]; - } - } - - Map uriStatHistogramBucketCountMap = new EnumMap<>(UriStatHistogramBucket.class); - for (UriStatHistogramBucket value : BUCKETS) { - int eachBucketTotalCount = mergedHistogramValue[value.getIndex()]; - uriStatHistogramBucketCountMap.put(value, eachBucketTotalCount); - } - return uriStatHistogramBucketCountMap; - } - - private SampledUriStatHistogramBo createEmptySampledUriStatHistogramBo(long timestamp) { - AgentStatPoint emptyIntegerPoint = AGENT_STAT_POINT_FACTORY.createIntPoint(timestamp, Collections.emptyList()); - AgentStatPoint emptyLongPoint = AGENT_STAT_POINT_FACTORY.createLongPoint(timestamp, Collections.emptyList()); - AgentStatPoint emptyDoublePoint = AGENT_STAT_POINT_FACTORY.createDoublePoint(timestamp, Collections.emptyList()); - - SampledUriStatHistogramBo sampledUriStatHistogramBo = new SampledUriStatHistogramBo(emptyIntegerPoint, emptyLongPoint, emptyDoublePoint, EMPTY_URI_STAT_HISTOGRAM_MAP, 0L); - return sampledUriStatHistogramBo; - } - -} - diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentStatServiceConfiguration.java b/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentStatServiceConfiguration.java index fb405e3a6421f..108fd099988fc 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentStatServiceConfiguration.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentStatServiceConfiguration.java @@ -2,7 +2,6 @@ import com.navercorp.pinpoint.common.server.bo.stat.ActiveTraceBo; import com.navercorp.pinpoint.common.server.bo.stat.AgentStatDataPoint; -import com.navercorp.pinpoint.common.server.bo.stat.AgentUriStatBo; import com.navercorp.pinpoint.common.server.bo.stat.CpuLoadBo; import com.navercorp.pinpoint.common.server.bo.stat.DataSourceListBo; import com.navercorp.pinpoint.common.server.bo.stat.DeadlockThreadCountBo; @@ -18,7 +17,6 @@ import com.navercorp.pinpoint.web.dao.SampledAgentStatDao; import com.navercorp.pinpoint.web.dao.stat.AgentStatDao; import com.navercorp.pinpoint.web.vo.stat.SampledActiveTrace; -import com.navercorp.pinpoint.web.vo.stat.SampledAgentUriStat; import com.navercorp.pinpoint.web.vo.stat.SampledCpuLoad; import com.navercorp.pinpoint.web.vo.stat.SampledDataSourceList; import com.navercorp.pinpoint.web.vo.stat.SampledDeadlock; @@ -31,7 +29,6 @@ import com.navercorp.pinpoint.web.vo.stat.SampledTotalThreadCount; import com.navercorp.pinpoint.web.vo.stat.SampledTransaction; import com.navercorp.pinpoint.web.vo.stat.chart.agent.ActiveTraceChart; -import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentUriStatChart; import com.navercorp.pinpoint.web.vo.stat.chart.agent.CpuLoadChart; import com.navercorp.pinpoint.web.vo.stat.chart.agent.DataSourceChart; import com.navercorp.pinpoint.web.vo.stat.chart.agent.DeadlockChart; @@ -183,18 +180,6 @@ public AgentStatService getDataSourceService(AgentStatDao getAgentUriStatChartService(SampledAgentStatDao statDao) { - return new AgentUriStatChartService(statDao); - } - - @Bean - public AgentStatService getAgentUriChartService(AgentStatDao statDao) { - return new DefaultStatService<>(statDao); - } - - //----------------------- - @Bean public AgentStatChartService getTransactionChartService(SampledAgentStatDao statDao) { return new DefaultAgentStatChartService<>(statDao, TransactionChart::new); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentUriStatChartService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentUriStatChartService.java deleted file mode 100644 index 42f24329f3415..0000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/stat/AgentUriStatChartService.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 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.stat; - -import com.navercorp.pinpoint.web.dao.SampledAgentStatDao; -import com.navercorp.pinpoint.web.util.TimeWindow; -import com.navercorp.pinpoint.web.vo.stat.SampledAgentUriStat; -import com.navercorp.pinpoint.web.vo.stat.chart.StatChart; -import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentUriStatChart; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -@Service -public class AgentUriStatChartService implements AgentStatChartService { - - private final SampledAgentStatDao sampledAgentUriStatDao; - - public AgentUriStatChartService(SampledAgentStatDao sampledAgentUriStatDao) { - this.sampledAgentUriStatDao = Objects.requireNonNull(sampledAgentUriStatDao, "sampledAgentUriStatDao"); - } - - @Override - public AgentUriStatChart selectAgentChart(String agentId, TimeWindow timeWindow) { - Objects.requireNonNull(agentId, "agentId"); - Objects.requireNonNull(timeWindow, "timeWindow"); - - List sampledAgentUriStatList = sampledAgentUriStatDao.getSampledAgentStatList(agentId, timeWindow); - - if (CollectionUtils.isEmpty(sampledAgentUriStatList)) { - return new AgentUriStatChart(timeWindow, Collections.emptyList()); - } else { - SampledAgentUriStat first = CollectionUtils.firstElement(sampledAgentUriStatList); - return new AgentUriStatChart(timeWindow, first.getSampledEachUriStatBoList()); - } - } - - @Override - public List selectAgentChartList(String agentId, TimeWindow timeWindow) { - Objects.requireNonNull(agentId, "agentId"); - Objects.requireNonNull(timeWindow, "timeWindow"); - - List sampledAgentUriStatList = sampledAgentUriStatDao.getSampledAgentStatList(agentId, timeWindow); - - if (CollectionUtils.isEmpty(sampledAgentUriStatList)) { - return List.of(new AgentUriStatChart(timeWindow, Collections.emptyList())); - } else { - List result = new ArrayList<>(sampledAgentUriStatList.size()); - for (SampledAgentUriStat sampledAgentUriStat : sampledAgentUriStatList) { - result.add(new AgentUriStatChart(timeWindow, sampledAgentUriStat.getSampledEachUriStatBoList())); - } - result.sort(Comparator.comparing(this::getTotalCount).reversed()); - return result; - } - } - - private long getTotalCount(StatChart statChart) { - AgentUriStatChart chart = (AgentUriStatChart) statChart; - return chart.getTotalCount(); - } - - @Override - public String getChartType() { - return sampledAgentUriStatDao.getChartType(); - } -} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledAgentUriStat.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledAgentUriStat.java deleted file mode 100644 index 87f236f03893f..0000000000000 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledAgentUriStat.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 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.vo.stat; - -import java.util.List; -import java.util.Objects; - -/** - * @author Taejin Koo - */ -public class SampledAgentUriStat implements SampledAgentStatDataPoint { - - private final List sampledEachUriStatBoList; - - public SampledAgentUriStat(List sampledEachUriStatBoList) { - this.sampledEachUriStatBoList = Objects.requireNonNull(sampledEachUriStatBoList, "sampledEachUriStatBoList"); - } - - public List getSampledEachUriStatBoList() { - return sampledEachUriStatBoList; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - SampledAgentUriStat that = (SampledAgentUriStat) o; - - return sampledEachUriStatBoList != null ? sampledEachUriStatBoList.equals(that.sampledEachUriStatBoList) : that.sampledEachUriStatBoList == null; - } - - @Override - public int hashCode() { - return sampledEachUriStatBoList != null ? sampledEachUriStatBoList.hashCode() : 0; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("SampledAgentUriStat{"); - sb.append("sampledEachUriStatBoList=").append(sampledEachUriStatBoList); - sb.append('}'); - return sb.toString(); - } -} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSamplerTest.java b/web/src/test/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSamplerTest.java deleted file mode 100644 index d5b360a844905..0000000000000 --- a/web/src/test/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/AgentUriStatSamplerTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2020 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.mapper.stat.sampling.sampler; - -import com.navercorp.pinpoint.common.server.bo.stat.EachUriStatBo; -import com.navercorp.pinpoint.common.server.bo.stat.UriStatHistogram; -import com.navercorp.pinpoint.common.trace.UriStatHistogramBucket; -import com.navercorp.pinpoint.web.vo.stat.SampledEachUriStatBo; -import com.navercorp.pinpoint.web.vo.stat.SampledUriStatHistogramBo; -import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentStatPoint; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; - -/** - * @author Taejin Koo - */ -public class AgentUriStatSamplerTest { - - @Test - public void sampleTest() { - AgentUriStatSampler sampler = new AgentUriStatSampler(); - - long currentTimeMillis = System.currentTimeMillis(); - long startTimestamp = currentTimeMillis - TimeUnit.DAYS.toMillis(30); - - List eachUriStatBoList = new ArrayList<>(); - eachUriStatBoList.add(createEachUriStatBo("agentId", startTimestamp, currentTimeMillis, "/index.html")); - eachUriStatBoList.add(createEachUriStatBo("agentId", startTimestamp, currentTimeMillis, "/index.html")); - - SampledEachUriStatBo sampledEachUriStatBo = sampler.sampleDataPoints(0, System.currentTimeMillis(), eachUriStatBoList, null); - - SampledUriStatHistogramBo totalSampledUriStatHistogramBo = sampledEachUriStatBo.getTotalSampledUriStatHistogramBo(); - - AgentStatPoint maxTimePoint = totalSampledUriStatHistogramBo.getMaxTimePoint(); - assertMaxValue(maxTimePoint, eachUriStatBoList); - - AgentStatPoint countPoint = totalSampledUriStatHistogramBo.getCountPoint(); - assertCountValue(countPoint, eachUriStatBoList); - - int[] uriStatHistogramValue = totalSampledUriStatHistogramBo.getUriStatHistogramValue(); - assertHistogramValue(uriStatHistogramValue, eachUriStatBoList); - } - - private EachUriStatBo createEachUriStatBo(String agentId, long startTimestamp, long timestamp, String uri) { - EachUriStatBo eachUriStatBo = new EachUriStatBo(); - eachUriStatBo.setAgentId(agentId); - eachUriStatBo.setStartTimestamp(startTimestamp); - eachUriStatBo.setTimestamp(timestamp); - eachUriStatBo.setUri(uri); - eachUriStatBo.setTotalHistogram(createUriStatHistogram(ThreadLocalRandom.current().nextInt(1, 10))); - return eachUriStatBo; - } - - private UriStatHistogram createUriStatHistogram(int count) { - long totalElapsed = 0; - long max = 0; - int[] bucketValues = new int[UriStatHistogramBucket.getBucketSize()]; - for (int i = 0; i < count; i++) { - int elapsed = ThreadLocalRandom.current().nextInt(10000); - totalElapsed += elapsed; - max = Math.max(max, elapsed); - - UriStatHistogramBucket bucket = UriStatHistogramBucket.getValue(elapsed); - bucketValues[bucket.getIndex()] += 1; - } - - UriStatHistogram uriStatHistogram = new UriStatHistogram(); - uriStatHistogram.setCount(count); - uriStatHistogram.setAvg(totalElapsed / count); - uriStatHistogram.setMax(max); - uriStatHistogram.setTimestampHistogram(bucketValues); - - return uriStatHistogram; - } - - private void assertMaxValue(AgentStatPoint expected, List actual) { - Long max = actual.stream().mapToLong(o -> o.getTotalHistogram().getMax()).max().getAsLong(); - Assertions.assertEquals(expected.getMaxYVal(), max); - } - - private void assertCountValue(AgentStatPoint expected, List actual) { - Integer count = actual.stream().mapToInt(o -> o.getTotalHistogram().getCount()).sum(); - Assertions.assertEquals(expected.getSumYVal(), count); - } - - private void assertHistogramValue(int[] uriStatHistogramValue, List actual) { - int[] newArrayValue = new int[UriStatHistogramBucket.getBucketSize()]; - for (EachUriStatBo eachUriStatBo : actual) { - int[] timestampHistogram = eachUriStatBo.getTotalHistogram().getTimestampHistogram(); - for (int i = 0; i < timestampHistogram.length; i++) { - newArrayValue[i] += timestampHistogram[i]; - } - } - - Assertions.assertTrue(Arrays.equals(uriStatHistogramValue, newArrayValue)); - } - -}