diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java index c41d61190b5a..87a470e2b269 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogram.java @@ -16,15 +16,23 @@ package com.navercorp.pinpoint.web.applicationmap.histogram; +import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.web.applicationmap.rawdata.AgentHistogram; import com.navercorp.pinpoint.web.applicationmap.rawdata.AgentHistogramList; +import com.navercorp.pinpoint.web.util.TimeWindow; import com.navercorp.pinpoint.web.view.AgentResponseTimeViewModel; import com.navercorp.pinpoint.web.view.TimeViewModel; import com.navercorp.pinpoint.web.vo.Application; import com.navercorp.pinpoint.common.server.util.time.Range; +import com.navercorp.pinpoint.web.vo.stat.SampledApdexScore; +import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentStatPoint; +import com.navercorp.pinpoint.web.vo.stat.chart.application.DoubleApplicationStatPoint; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -36,6 +44,9 @@ */ public class AgentTimeHistogram { + private static final Double DEFAULT_MIN_APDEX_SCORE = 2D; + private static final Double DEFAULT_MAX_APDEX_SCORE = -2D; + private static final String DEFAULT_AGENT_ID = "defaultAgentId"; private static final Comparator AGENT_NAME_COMPARATOR = Comparator.comparing(AgentResponseTimeViewModel::getAgentName); @@ -83,4 +94,91 @@ private AgentResponseTimeViewModel createAgentResponseTimeViewModel(Application private List createResponseTimeViewModel(List timeHistogramList, TimeHistogramFormat timeHistogramFormat) { return new TimeViewModel.TimeViewModelBuilder(application, timeHistogramList).setTimeHistogramFormat(timeHistogramFormat).build(); } + + public List getSampledAgentApdexScoreList(String agentName) { + AgentHistogram agentHistogram = selectAgentHistogram(agentName); + if (agentHistogram == null) { + return Collections.emptyList(); + } + + List result = new ArrayList<>(); + for(TimeHistogram timeHistogram : agentHistogram.getTimeHistogram()) { + if (timeHistogram.getTotalCount() != 0) { + AgentStatPoint agentStatPoint = new AgentStatPoint(timeHistogram.getTimeStamp(), ApdexScore.toDoubleFromHistogram(timeHistogram)); + result.add(new SampledApdexScore(agentStatPoint)); + } + } + return result; + } + + private AgentHistogram selectAgentHistogram(String agentName) { + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + Application agentId = agentHistogram.getAgentId(); + if (agentId.getName().equals(agentName)){ + return agentHistogram; + } + } + return null; + } + + public List getApplicationApdexScoreList(TimeWindow window) { + int size = (int) window.getWindowRangeCount(); + List min = new ArrayList<>(Arrays.asList(new Double[size])); + List minAgentId = new ArrayList<>(Arrays.asList(new String[size])); + List max = new ArrayList<>(Arrays.asList(new Double[size])); + List maxAgentId = new ArrayList<>(Arrays.asList(new String[size])); + Collections.fill(min, DEFAULT_MIN_APDEX_SCORE); + Collections.fill(minAgentId, DEFAULT_AGENT_ID); + Collections.fill(max, DEFAULT_MAX_APDEX_SCORE); + Collections.fill(maxAgentId, DEFAULT_AGENT_ID); + List sumHistogram = getDefaultHistograms(window, application.getServiceType()); + + for (AgentHistogram agentHistogram : agentHistogramList.getAgentHistogramList()) { + for (TimeHistogram timeHistogram: agentHistogram.getTimeHistogram()){ + if (timeHistogram.getTotalCount() != 0){ + int index = window.getWindowIndex(timeHistogram.getTimeStamp()); + double apdex = ApdexScore.toDoubleFromHistogram(timeHistogram); + String agentId = agentHistogram.getId(); + + updateMinMaxValue(index, apdex, agentId, min, minAgentId, max, maxAgentId); + sumHistogram.get(index).add(timeHistogram); + } + } + } + + return createDoubleApplicationStatPoints(window, min, minAgentId, max, maxAgentId, sumHistogram); + } + + private void updateMinMaxValue(int index, double apdex, String agentId, + List min, List minAgentId, List max, List maxAgentId) { + if (min.get(index) > apdex) { + min.set(index, apdex); + minAgentId.set(index, agentId); + } + if (max.get(index) < apdex) { + max.set(index, apdex); + maxAgentId.set(index, agentId); + } + } + + private List createDoubleApplicationStatPoints(TimeWindow window, List min, List minAgentId, List max, List maxAgentId, List sumHistrogram) { + List applicationStatPoints = new ArrayList<>(); + for (long timestamp : window) { + int index = window.getWindowIndex(timestamp); + Histogram histogram = sumHistrogram.get(index); + if (histogram.getTotalCount() != 0){ + double avg = ApdexScore.toDoubleFromHistogram(histogram); + applicationStatPoints.add(new DoubleApplicationStatPoint(timestamp, min.get(index), minAgentId.get(index), max.get(index), maxAgentId.get(index), avg)); + } + } + return applicationStatPoints; + } + + private List getDefaultHistograms(TimeWindow window, ServiceType serviceType) { + List sum = new ArrayList<>((int) window.getWindowRangeCount()); + for (long timestamp : window){ + sum.add(new TimeHistogram(serviceType, timestamp)); + } + return sum; + } } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java index de5ea4b22715..d353c7978545 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramBuilder.java @@ -48,6 +48,11 @@ public AgentTimeHistogramBuilder(Application application, Range range) { this.window = new TimeWindow(range, TimeWindowDownSampler.SAMPLER); } + public AgentTimeHistogramBuilder(Application application, Range range, TimeWindow window) { + this.application = Objects.requireNonNull(application, "application"); + this.range = Objects.requireNonNull(range, "range"); + this.window = Objects.requireNonNull(window, "window");; + } public AgentTimeHistogram build(List responseHistogramList) { AgentHistogramList agentHistogramList = new AgentHistogramList(application, responseHistogramList); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApdexScore.java b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApdexScore.java index e0240b03a196..792f48c9f78d 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApdexScore.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/applicationmap/histogram/ApdexScore.java @@ -15,6 +15,15 @@ public class ApdexScore { private final double apdexScore; + public static double toDoubleFromHistogram(Histogram histogram) { + Objects.requireNonNull(histogram, "histogram"); + final long satisfiedCount = histogram.getFastCount(); + final long toleratingCount = histogram.getNormalCount(); + final long totalCount = histogram.getTotalCount(); + + return calculateApdexScore(satisfiedCount, toleratingCount, totalCount); + } + public static ApdexScore newApdexScore(Histogram histogram) { Objects.requireNonNull(histogram, "histogram"); final long satisfiedCount = histogram.getFastCount(); @@ -28,7 +37,7 @@ public ApdexScore(long satisfiedCount, long toleratingCount, long totalSamples) this.apdexScore = calculateApdexScore(satisfiedCount, toleratingCount, totalSamples); } - private double calculateApdexScore(long satisfiedCount, long toleratingCount, long totalSamples) { + private static double calculateApdexScore(long satisfiedCount, long toleratingCount, long totalSamples) { // divide by zero if (totalSamples == 0) { return 0; diff --git a/web/src/main/java/com/navercorp/pinpoint/web/controller/ApdexScoreController.java b/web/src/main/java/com/navercorp/pinpoint/web/controller/ApdexScoreController.java new file mode 100644 index 000000000000..69e5b3f12b3e --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/controller/ApdexScoreController.java @@ -0,0 +1,185 @@ +package com.navercorp.pinpoint.web.controller; + +import com.navercorp.pinpoint.common.server.util.time.Range; +import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore; +import com.navercorp.pinpoint.web.service.ApdexScoreService; +import com.navercorp.pinpoint.web.service.ApplicationFactory; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.util.TimeWindowSampler; +import com.navercorp.pinpoint.web.util.TimeWindowSlotCentricSampler; +import com.navercorp.pinpoint.web.view.InspectorView; +import com.navercorp.pinpoint.web.vo.Application; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChart; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Objects; + +@RestController +public class ApdexScoreController { + private final ApplicationFactory applicationFactory; + private final ApdexScoreService apdexScoreService; + + public ApdexScoreController(ApplicationFactory applicationFactory, ApdexScoreService apdexScoreService) { + this.applicationFactory = Objects.requireNonNull(applicationFactory, "applicationFactory"); + this.apdexScoreService = Objects.requireNonNull(apdexScoreService, "apdexScoreService"); + } + + @GetMapping(value = "/getApdexScore") + public ApdexScore getApdexScore( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") Short serviceTypeCode, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + + Application application = applicationFactory.createApplication(applicationName, serviceTypeCode); + final ApdexScore apdexScore = apdexScoreService.selectApdexScoreData(application, range); + + return apdexScore; + } + + @GetMapping(value = "/getApdexScore", params = "serviceTypeName") + public ApdexScore getApdexScore( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeName") String serviceTypeName, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + + Application application = applicationFactory.createApplicationByTypeName(applicationName, serviceTypeName); + final ApdexScore apdexScore = apdexScoreService.selectApdexScoreData(application, range); + + return apdexScore; + } + + @GetMapping(value = "/getApplicaionStat/apdexScore/chart") + public StatChart getApplicationApdexScoreChart( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") Short serviceTypeCode, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplication(applicationName, serviceTypeCode); + + return apdexScoreService.selectApplicationChart(application, range, timeWindow); + } + + @GetMapping(value = "/getApplicationStat/apdexScore/chart", params = "serviceTypeName") + public StatChart getAgentApdexScoreScoreChart( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeName") String serviceTypeName, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplicationByTypeName(applicationName, serviceTypeName); + + return apdexScoreService.selectApplicationChart(application, range, timeWindow); + } + + @GetMapping(value = "/getAgentStat/apdexScore/chart") + public StatChart getAgentApdexScoreChartData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") Short serviceTypeCode, + @RequestParam("agentId") String agentId, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplication(applicationName, serviceTypeCode); + + return apdexScoreService.selectAgentChart(application, range, timeWindow, agentId); + } + + @GetMapping(value = "/getAgentStat/apdexScore/chart", params = "serviceTypeName") + public StatChart getAgentApdexScoreChartData( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeName") String serviceTypeName, + @RequestParam("agentId") String agentId, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplicationByTypeName(applicationName, serviceTypeName); + + return apdexScoreService.selectAgentChart(application, range, timeWindow, agentId); + } + + @GetMapping(value = "/getApplicaionStat/apdexScore/inspectorView") + public InspectorView getApplicationApdexScoreView( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") Short serviceTypeCode, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplication(applicationName, serviceTypeCode); + + InspectorData inspectorData = apdexScoreService.selectApplicationInspectorData(application, range, timeWindow); + return new InspectorView(inspectorData); + } + + @GetMapping(value = "/getApplicationStat/apdexScore/inspectorView", params = "serviceTypeName") + public InspectorView getApplicationApdexScoreView( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeName") String serviceTypeName, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplicationByTypeName(applicationName, serviceTypeName); + + InspectorData inspectorData = apdexScoreService.selectApplicationInspectorData(application, range, timeWindow); + return new InspectorView(inspectorData); + } + + @GetMapping(value = "/getAgentStat/apdexScore/inspectorView") + public InspectorView getAgentApdexScoreView( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeCode") Short serviceTypeCode, + @RequestParam("agentId") String agentId, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplication(applicationName, serviceTypeCode); + + InspectorData inspectorData = apdexScoreService.selectAgentInspectorData(application, range, timeWindow, agentId); + return new InspectorView(inspectorData); + } + + @GetMapping(value = "/getAgentStat/apdexScore/inspectorView", params = "serviceTypeName") + public InspectorView getAgentApdexScoreView( + @RequestParam("applicationName") String applicationName, + @RequestParam("serviceTypeName") String serviceTypeName, + @RequestParam("agentId") String agentId, + @RequestParam("from") long from, + @RequestParam("to") long to) { + final Range range = Range.between(from, to); + TimeWindowSampler sampler = new TimeWindowSlotCentricSampler(); + TimeWindow timeWindow = new TimeWindow(range, sampler); + + Application application = applicationFactory.createApplicationByTypeName(applicationName, serviceTypeName); + + InspectorData inspectorData = apdexScoreService.selectAgentInspectorData(application, range, timeWindow, agentId); + return new InspectorView(inspectorData); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/metric/common/model/Tag.java b/web/src/main/java/com/navercorp/pinpoint/web/metric/common/model/Tag.java new file mode 100644 index 000000000000..5a4d79bddcff --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/metric/common/model/Tag.java @@ -0,0 +1,74 @@ +/* + * 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.metric.common.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Objects; + +/** + * @author Hyunjoon Cho + */ +public class Tag { + private final String name; + private final String value; + + @JsonCreator + public Tag(@JsonProperty("name") String name, + @JsonProperty("value") String value) { + this.name = Objects.requireNonNull(name); + this.value = Objects.requireNonNull(value); + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(name); + sb.append(":").append(value); + return sb.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Tag tag = (Tag) o; + + if (!name.equals(tag.name)) return false; + return value.equals(tag.value); + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + value.hashCode(); + return result; + } + + public Tag copy() { + return new Tag(this.name, this.value); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreService.java b/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreService.java new file mode 100644 index 000000000000..e369bcf125b0 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreService.java @@ -0,0 +1,21 @@ +package com.navercorp.pinpoint.web.service; + +import com.navercorp.pinpoint.common.server.util.time.Range; +import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.Application; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChart; + +public interface ApdexScoreService { + + ApdexScore selectApdexScoreData(Application application, Range range); + + StatChart selectApplicationChart(Application application, Range range, TimeWindow timeWindow); + + StatChart selectAgentChart(Application application, Range range, TimeWindow timeWindow, String agentId); + + InspectorData selectApplicationInspectorData(Application application, Range range, TimeWindow timeWindow); + + InspectorData selectAgentInspectorData(Application application, Range range, TimeWindow timeWindow, String agentId); +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreServiceImpl.java new file mode 100644 index 000000000000..2d141b1aea49 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/ApdexScoreServiceImpl.java @@ -0,0 +1,107 @@ +package com.navercorp.pinpoint.web.service; + +import com.navercorp.pinpoint.common.server.util.time.Range; +import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.web.applicationmap.histogram.AgentTimeHistogram; +import com.navercorp.pinpoint.web.applicationmap.histogram.AgentTimeHistogramBuilder; +import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore; +import com.navercorp.pinpoint.web.applicationmap.histogram.Histogram; +import com.navercorp.pinpoint.web.applicationmap.histogram.TimeHistogram; +import com.navercorp.pinpoint.web.dao.MapResponseDao; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.Application; +import com.navercorp.pinpoint.web.vo.ResponseTime; +import com.navercorp.pinpoint.web.vo.stat.SampledApdexScore; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChart; +import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentApdexScoreChart; +import com.navercorp.pinpoint.web.vo.stat.chart.application.ApplicationApdexScoreChart; +import com.navercorp.pinpoint.web.vo.stat.chart.application.DoubleApplicationStatPoint; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +@Service +public class ApdexScoreServiceImpl implements ApdexScoreService { + private final Logger logger = LogManager.getLogger(this.getClass()); + + private final MapResponseDao mapResponseDao; + + public ApdexScoreServiceImpl(MapResponseDao mapResponseDao) { + this.mapResponseDao = mapResponseDao; + } + + private AgentTimeHistogram createAgentTimeHistogram(Application application, Range range, TimeWindow timeWindow, List responseHistogramList) { + AgentTimeHistogramBuilder builder = new AgentTimeHistogramBuilder(application, range, timeWindow); + AgentTimeHistogram timeHistogram = builder.build(responseHistogramList); + return timeHistogram; + } + + @Override + public ApdexScore selectApdexScoreData(Application application, Range range) { + ServiceType applicationServiceType = application.getServiceType(); + + if (applicationServiceType.isWas()) { + List responseTimeList = mapResponseDao.selectResponseTime(application, range); + Histogram applicationHistogram = createApplicationHistogram(responseTimeList, applicationServiceType); + + return ApdexScore.newApdexScore(applicationHistogram); + } else { + logger.debug("application service type isWas:{}", applicationServiceType.isWas()); + return ApdexScore.newApdexScore(new Histogram(applicationServiceType)); + } + } + + private Histogram createApplicationHistogram(List responseHistogram, ServiceType applicationServiceType) { + final Histogram applicationHistogram = new Histogram(applicationServiceType); + for (ResponseTime responseTime : responseHistogram) { + final Collection histogramList = responseTime.getAgentResponseHistogramList(); + for (Histogram histogram : histogramList) { + applicationHistogram.add(histogram); + } + } + return applicationHistogram; + } + + @Override + public StatChart selectApplicationChart(Application application, Range range, TimeWindow timeWindow){ + List responseTimeList = mapResponseDao.selectResponseTime(application, range); + AgentTimeHistogram timeHistogram = createAgentTimeHistogram(application, range, timeWindow, responseTimeList); + + List applicationStatPoints = timeHistogram.getApplicationApdexScoreList(timeWindow); + + return new ApplicationApdexScoreChart(timeWindow, applicationStatPoints); + } + + @Override + public StatChart selectAgentChart(Application application, Range range, TimeWindow timeWindow, String agentId){ + List responseTimeList = mapResponseDao.selectResponseTime(application, range); + AgentTimeHistogram timeHistogram = createAgentTimeHistogram(application, range, timeWindow, responseTimeList); + + List sampledPoints = timeHistogram.getSampledAgentApdexScoreList(agentId); + return new AgentApdexScoreChart(timeWindow, sampledPoints); + } + + @Override + public InspectorData selectApplicationInspectorData(Application application, Range range, TimeWindow timeWindow) { + List responseTimeList = mapResponseDao.selectResponseTime(application, range); + AgentTimeHistogram timeHistogram = createAgentTimeHistogram(application, range, timeWindow, responseTimeList); + List applicationStatPoints = timeHistogram.getApplicationApdexScoreList(timeWindow); + + ApplicationApdexScoreChart chart = new ApplicationApdexScoreChart(timeWindow, applicationStatPoints); + return chart.getInspectorData(timeWindow, applicationStatPoints); + } + + @Override + public InspectorData selectAgentInspectorData(Application application, Range range, TimeWindow timeWindow, String agentId) { + List responseTimeList = mapResponseDao.selectResponseTime(application, range); + AgentTimeHistogram timeHistogram = createAgentTimeHistogram(application, range, timeWindow, responseTimeList); + List sampledPoints = timeHistogram.getSampledAgentApdexScoreList(agentId); + + AgentApdexScoreChart chart = new AgentApdexScoreChart(timeWindow, sampledPoints); + return chart.getInspectorData(timeWindow, sampledPoints); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/InspectorView.java b/web/src/main/java/com/navercorp/pinpoint/web/view/InspectorView.java new file mode 100644 index 000000000000..1d99a27dfe2b --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/InspectorView.java @@ -0,0 +1,79 @@ +package com.navercorp.pinpoint.web.view; + +import com.navercorp.pinpoint.web.metric.common.model.Tag; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorValue; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorValueGroup; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class InspectorView { + private final InspectorData inspectorData; + + public InspectorView(InspectorData inspectorData) { + this.inspectorData = Objects.requireNonNull(inspectorData, "systemMetricData"); + } + + public String getTitle() { + return inspectorData.getTitle(); + } + + public String getUnit() { + return inspectorData.getUnit(); + } + + public List getTimestamp() { + return inspectorData.getTimeStampList(); + } + + public List getMetricValueGroups() { + return inspectorData.getMetricValueGroupList() + .stream() + .map(InspectorValueGroupView::new) + .collect(Collectors.toList()); + } + + public static class InspectorValueGroupView { + private final InspectorValueGroup value; + + public InspectorValueGroupView(InspectorValueGroup value) { + this.value = Objects.requireNonNull(value, "value"); + } + + public String getGroupName() { + return value.getGroupName(); + } + + public List getMetricValues() { + return value.getMetricValueList() + .stream() + .map(InspectorValueView::new) + .collect(Collectors.toList()); + } + } + + public static class InspectorValueView { + private final InspectorValue value; + + public InspectorValueView(InspectorValue value) { + this.value = Objects.requireNonNull(value, "value"); + } + + public String getFieldName() { + return value.getFieldName(); + } + + public List getTags() { + return value.getTagList() + .stream() + .map(Tag::toString) + .collect(Collectors.toList()); + } + + public List getValues() { + return value.getValueList(); + } + } +} \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledApdexScore.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledApdexScore.java new file mode 100644 index 000000000000..8d049e105548 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledApdexScore.java @@ -0,0 +1,46 @@ +package com.navercorp.pinpoint.web.vo.stat; + +import com.navercorp.pinpoint.web.vo.chart.Point; +import com.navercorp.pinpoint.web.vo.chart.UncollectedPointCreatorFactory; +import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentStatPoint; + +import java.util.Objects; + +public class SampledApdexScore implements SampledAgentStatDataPoint{ + + public static final Double UNCOLLECTED_SCORE = -1D; + public static final Point.UncollectedPointCreator> UNCOLLECTED_POINT_CREATOR = UncollectedPointCreatorFactory.createDoublePointCreator(UNCOLLECTED_SCORE); + + private final AgentStatPoint apdexScore; + + public SampledApdexScore(AgentStatPoint apdexScore) { + this.apdexScore = Objects.requireNonNull(apdexScore, "apdexScore"); + } + + public AgentStatPoint getApdexScore() { + return apdexScore; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SampledApdexScore that = (SampledApdexScore) o; + + return Objects.equals(apdexScore, that.apdexScore); + } + + @Override + public int hashCode() { + return apdexScore.hashCode(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("SampledApdexScore{"); + sb.append("apdexScore=").append(apdexScore); + sb.append('}'); + return sb.toString(); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorData.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorData.java new file mode 100644 index 000000000000..9e7fb7ba3362 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorData.java @@ -0,0 +1,39 @@ +package com.navercorp.pinpoint.web.vo.stat.chart; + +import org.springframework.util.Assert; + +import java.util.List; +import java.util.Objects; + +public class InspectorData { + private final String title; + private final String unit; + private final List timeStampList; + private final List inspectorValueGroupList; + + public InspectorData(String title, String unit, List timeStampList, List inspectorValueGroupList) { + Assert.hasLength(title, "title must not be empty"); + Assert.hasLength(unit, "unit must not be empty"); + this.title = title; + this.unit = unit; + this.timeStampList = Objects.requireNonNull(timeStampList, "timeStampList"); + this.inspectorValueGroupList = Objects.requireNonNull(inspectorValueGroupList, "inspectorValueGroupList"); + } + + public String getUnit() { + return unit; + } + + public String getTitle() { + return title; + } + + public List getTimeStampList() { + return timeStampList; + } + + public List getMetricValueGroupList() { + return inspectorValueGroupList; + } + +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorDataBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorDataBuilder.java new file mode 100644 index 000000000000..131c0c6fb937 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorDataBuilder.java @@ -0,0 +1,72 @@ +package com.navercorp.pinpoint.web.vo.stat.chart; + +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.chart.Point; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class InspectorDataBuilder { + + private final InspectorValueGroupBuilder inspectorValueGroupBuilder; + private final List>> pointFunctions = new ArrayList<>(); + private final String title; + private final String unit; + + public InspectorDataBuilder(Point.UncollectedPointCreator

uncollectedPointCreator, String title, String unit) { + inspectorValueGroupBuilder = new InspectorValueGroupBuilder<>(uncollectedPointCreator); + this.title = Objects.requireNonNull(title, "title");; + this.unit = Objects.requireNonNull(unit, "unit"); + } + + private InspectorData build(TimeWindow timeWindow, List sampledPoints, List>> entries) { + Objects.requireNonNull(entries, "entries"); + + List inspectorValueGroupList = new ArrayList<>(entries.size()); + for (Map.Entry> entry : entries) { + String groupName = entry.getKey().toString(); + Function function = entry.getValue(); + List

points = sampledPoints.stream() + .map(function) + .collect(Collectors.toList()); + + InspectorValueGroup inspectorValueGroup = inspectorValueGroupBuilder.build(timeWindow, groupName, points); + inspectorValueGroupList.add(inspectorValueGroup); + } + List timestampList = getTimestampList(timeWindow); + return new InspectorData(title, unit, timestampList, inspectorValueGroupList); + } + + public InspectorData build(TimeWindow timeWindow, List sampledPoints) { + Objects.requireNonNull(timeWindow, "timeWindow"); + Objects.requireNonNull(sampledPoints, "sampledPointList"); + + return build(timeWindow, sampledPoints, pointFunctions); + } + + public void addPointFunction(StatChartGroup.ChartType inspectorValueType, Function function) { + Objects.requireNonNull(inspectorValueType, "inspectorValueType"); + Objects.requireNonNull(function, "function"); + + this.pointFunctions.add(Map.entry(inspectorValueType, function)); + } + + public void addValueFunction(String FieldName, Function function) { + Objects.requireNonNull(FieldName, "FieldName"); + Objects.requireNonNull(function, "function"); + + this.inspectorValueGroupBuilder.addValueFunction(FieldName, function); + } + + private List getTimestampList(TimeWindow timeWindow) { + List timestampList = new ArrayList<>((int) timeWindow.getWindowSlotSize()); + for(Long timeStamp : timeWindow){ + timestampList.add(timeStamp); + } + return timestampList; + } +} \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValue.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValue.java new file mode 100644 index 000000000000..d5df59d7678e --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValue.java @@ -0,0 +1,32 @@ +package com.navercorp.pinpoint.web.vo.stat.chart; + +import com.navercorp.pinpoint.web.metric.common.model.Tag; +import org.springframework.util.Assert; + +import java.util.List; +import java.util.Objects; + +public class InspectorValue { + private final String fieldName; + private final List tagList; + private final List valueList; + + public InspectorValue(String fieldName, List tagList, List valueList) { + Assert.hasLength(fieldName, "fieldName must not be empty"); + this.fieldName = fieldName; + this.tagList = Objects.requireNonNull(tagList, "tagList"); + this.valueList = Objects.requireNonNull(valueList, "valueList"); + } + + public List getTagList() { + return tagList; + } + + public List getValueList() { + return valueList; + } + + public String getFieldName() { + return fieldName; + } +} \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroup.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroup.java new file mode 100644 index 000000000000..e64e3e643a31 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroup.java @@ -0,0 +1,26 @@ +package com.navercorp.pinpoint.web.vo.stat.chart; + +import org.springframework.util.Assert; + +import java.util.List; +import java.util.Objects; + +public class InspectorValueGroup { + + private final String groupName; + private final List> inspectorValueList; + + public InspectorValueGroup(List> inspectorValueList, String groupName) { + Assert.hasLength(groupName, "groupName must not be empty"); + this.groupName = groupName; + this.inspectorValueList = Objects.requireNonNull(inspectorValueList, "metricValueList");; + } + + public List> getMetricValueList() { + return inspectorValueList; + } + + public String getGroupName() { + return groupName; + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroupBuilder.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroupBuilder.java new file mode 100644 index 000000000000..427f6331a67f --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/InspectorValueGroupBuilder.java @@ -0,0 +1,71 @@ +package com.navercorp.pinpoint.web.vo.stat.chart; + +import com.navercorp.pinpoint.web.metric.common.model.Tag; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.chart.Point; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class InspectorValueGroupBuilder { + + private final Point.UncollectedPointCreator

uncollectedPointCreator; + private final Map> functions = new HashMap<>(); + + public InspectorValueGroupBuilder(Point.UncollectedPointCreator

uncollectedPointCreator) { + this.uncollectedPointCreator = Objects.requireNonNull(uncollectedPointCreator, "uncollectedPointCreator"); + } + + public InspectorValueGroup build(TimeWindow timeWindow, String groupName, List

sampledPoints){ + List

points = createInitialPoints(timeWindow); + for (P sampledPoint : sampledPoints) { + int timeslotIndex = timeWindow.getWindowIndex(sampledPoint.getXVal()); + if (timeslotIndex < 0 || timeslotIndex >= timeWindow.getWindowRangeCount()) { + continue; + } + points.set(timeslotIndex, sampledPoint); + } + + List> inspectorValueList = getInspectorValueList(points); + return new InspectorValueGroup(inspectorValueList, groupName); + } + + private List> getInspectorValueList(List

points) { + List> inspectorValueList = new ArrayList<>(); + for (Map.Entry> e : functions.entrySet()) { + String fieldName = e.getKey(); + Function function = e.getValue(); + InspectorValue inspectorValue = getMetricValue(points, fieldName, function); + inspectorValueList.add(inspectorValue); + } + return inspectorValueList; + } + + private InspectorValue getMetricValue(List

statPoints, String fieldName, Function function) { + List valueList = statPoints.stream() + .map(function) + .collect(Collectors.toList()); + List emptyTagList = Collections.emptyList(); + InspectorValue inspectorValue = new InspectorValue<>(fieldName, emptyTagList, valueList); + return inspectorValue; + } + + public void addValueFunction(String fieldName, Function function) { + functions.put(fieldName, function); + } + + private List

createInitialPoints(TimeWindow timeWindow) { + int numTimeslots = (int) timeWindow.getWindowRangeCount(); + List

points = new ArrayList<>(numTimeslots); + for (long timestamp : timeWindow) { + points.add(uncollectedPointCreator.createUnCollectedPoint(timestamp)); + } + return points; + } +} \ No newline at end of file diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/agent/AgentApdexScoreChart.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/agent/AgentApdexScoreChart.java new file mode 100644 index 000000000000..4f2b5cc86b5c --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/agent/AgentApdexScoreChart.java @@ -0,0 +1,46 @@ +package com.navercorp.pinpoint.web.vo.stat.chart.agent; + +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.stat.SampledApdexScore; +import com.navercorp.pinpoint.web.vo.stat.chart.ChartGroupBuilder; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorDataBuilder; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChartGroup; + +import java.util.List; + +public class AgentApdexScoreChart extends DefaultAgentChart{ + + public enum ApdexScoreChartType implements StatChartGroup.AgentChartType{ + APDEX_SCORE; + } + + private static final ChartGroupBuilder> BUILDER = newChartBuilder(); + private static final InspectorDataBuilder> INSPECTOR_VIEW_DATA_BUILDER = newViewBuilder(); + + static ChartGroupBuilder> newChartBuilder() { + ChartGroupBuilder> builder = new ChartGroupBuilder<>(SampledApdexScore.UNCOLLECTED_POINT_CREATOR); + builder.addPointFunction(ApdexScoreChartType.APDEX_SCORE, SampledApdexScore::getApdexScore); + + return builder; + } + + static InspectorDataBuilder> newViewBuilder(){ + InspectorDataBuilder> builder = new InspectorDataBuilder(SampledApdexScore.UNCOLLECTED_POINT_CREATOR, "agentApdexScore", "noUnit"); + builder.addValueFunction("min", AgentStatPoint::getMinYVal); + builder.addValueFunction("max", AgentStatPoint::getMaxYVal); + builder.addValueFunction("avg", AgentStatPoint::getAvgYVal); + builder.addValueFunction("sum", AgentStatPoint::getSumYVal); + builder.addPointFunction(ApdexScoreChartType.APDEX_SCORE, SampledApdexScore::getApdexScore); + + return builder; + } + + public AgentApdexScoreChart(TimeWindow timeWindow, List statList) { + super(timeWindow, statList, BUILDER); + } + + public InspectorData getInspectorData(TimeWindow timeWindow, List statList){ + return INSPECTOR_VIEW_DATA_BUILDER.build(timeWindow, statList); + } +} diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/application/ApplicationApdexScoreChart.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/application/ApplicationApdexScoreChart.java new file mode 100644 index 000000000000..f44016cf4ec2 --- /dev/null +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/application/ApplicationApdexScoreChart.java @@ -0,0 +1,53 @@ +package com.navercorp.pinpoint.web.vo.stat.chart.application; + +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.vo.chart.Point; +import com.navercorp.pinpoint.web.vo.stat.chart.ChartGroupBuilder; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorDataBuilder; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChartGroup; + +import java.util.List; + +public class ApplicationApdexScoreChart extends DefaultApplicationChart { + + private static final Point.UncollectedPointCreator> UNCOLLECTED_POINT + = new DoubleApplicationStatPoint.UncollectedCreator(-1D); + + public enum ApdexScoreChartType implements StatChartGroup.ApplicationChartType { + APDEX_SCORE + } + + private static final ChartGroupBuilder> BUILDER = newChartBuilder(); + private static final InspectorDataBuilder> INSPECTOR_VIEW_DATA_BUILDER = newViewBuilder(); + + static ChartGroupBuilder> newChartBuilder() { + ChartGroupBuilder> builder = new ChartGroupBuilder<>(UNCOLLECTED_POINT); + builder.addPointFunction(ApdexScoreChartType.APDEX_SCORE, ApplicationApdexScoreChart::newApdexScorePoint); + return builder; + } + + static InspectorDataBuilder> newViewBuilder(){ + InspectorDataBuilder> builder = new InspectorDataBuilder(UNCOLLECTED_POINT, "applicationApdexScore", "noUnit"); + builder.addValueFunction("min", ApplicationStatPoint::getYValForMin); + builder.addValueFunction("minAgentId", ApplicationStatPoint::getAgentIdForMin); + builder.addValueFunction("max", ApplicationStatPoint::getYValForMax); + builder.addValueFunction("maxAgentId", ApplicationStatPoint::getAgentIdForMax); + builder.addValueFunction("avg", ApplicationStatPoint::getYValForAvg); + builder.addPointFunction(ApdexScoreChartType.APDEX_SCORE, ApplicationApdexScoreChart::newApdexScorePoint); + + return builder; + } + + public ApplicationApdexScoreChart(TimeWindow timeWindow, List statList) { + super(timeWindow, statList, BUILDER); + } + + private static ApplicationStatPoint newApdexScorePoint(DoubleApplicationStatPoint apdexScore) { + return apdexScore; + } + + public InspectorData getInspectorData(TimeWindow timeWindow, List statList) { + return INSPECTOR_VIEW_DATA_BUILDER.build(timeWindow, statList); + } +} diff --git a/web/src/test/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramTest.java b/web/src/test/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramTest.java index 6dace2cef975..4264701ccc1d 100644 --- a/web/src/test/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramTest.java +++ b/web/src/test/java/com/navercorp/pinpoint/web/applicationmap/histogram/AgentTimeHistogramTest.java @@ -20,11 +20,16 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.util.TimeWindowSlotCentricSampler; import com.navercorp.pinpoint.web.view.AgentResponseTimeViewModel; import com.navercorp.pinpoint.web.vo.Application; import com.navercorp.pinpoint.common.server.util.time.Range; import com.navercorp.pinpoint.web.vo.ResponseTime; +import com.navercorp.pinpoint.web.vo.stat.SampledApdexScore; +import com.navercorp.pinpoint.web.vo.stat.chart.application.DoubleApplicationStatPoint; +import org.junit.Assert; import org.junit.Test; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; @@ -68,6 +73,42 @@ public void testViewModel() throws IOException { } + @Test + public void getSampledAgentApdexScoreListTest() { + Application app = new Application("test", ServiceType.STAND_ALONE); + Range range = Range.between(0, 1000*60); + TimeWindow timeWindow = new TimeWindow(range, new TimeWindowSlotCentricSampler()); + AgentTimeHistogramBuilder builder = new AgentTimeHistogramBuilder(app, range, timeWindow); + List responseHistogramList = createResponseTime(app, "test1", "test2"); + AgentTimeHistogram histogram = builder.build(responseHistogramList); + + List sampledApdexScore1 = histogram.getSampledAgentApdexScoreList("test1"); + Assert.assertEquals(sampledApdexScore1.size(), 2); + + List sampledApdexScore2 = histogram.getSampledAgentApdexScoreList("test2"); + Assert.assertEquals(sampledApdexScore2.size(), 2); + + List wrongSampledApdexScore = histogram.getSampledAgentApdexScoreList("wrongAgentName"); + Assert.assertEquals(wrongSampledApdexScore.size(), 0); + } + + @Test + public void getApplicationApdexScoreListTest() { + Application app = new Application("test", ServiceType.STAND_ALONE); + Range range = Range.between(0, 1000*60); + TimeWindow timeWindow = new TimeWindow(range, new TimeWindowSlotCentricSampler()); + AgentTimeHistogramBuilder builder = new AgentTimeHistogramBuilder(app, range, timeWindow); + List responseHistogramList = createResponseTime(app, "test1", "test2"); + AgentTimeHistogram histogram = builder.build(responseHistogramList); + + List applicationStatPointList = histogram.getApplicationApdexScoreList(timeWindow); + Assert.assertEquals(applicationStatPointList.size(), 2); + Assert.assertEquals(applicationStatPointList.get(0).getXVal(), 0); + Assert.assertEquals(applicationStatPointList.get(0).getYValForAvg(), 1.0, 0.001); + Assert.assertEquals(applicationStatPointList.get(1).getXVal(), 1000*60); + Assert.assertEquals(applicationStatPointList.get(1).getYValForAvg(), 0.5, 0.001); + } + private List createResponseTime(Application app, String agentName1, String agentName2) { List responseTimeList = new ArrayList(); diff --git a/web/src/test/java/com/navercorp/pinpoint/web/view/InspectorViewTest.java b/web/src/test/java/com/navercorp/pinpoint/web/view/InspectorViewTest.java new file mode 100644 index 000000000000..f715884f4e5a --- /dev/null +++ b/web/src/test/java/com/navercorp/pinpoint/web/view/InspectorViewTest.java @@ -0,0 +1,79 @@ +package com.navercorp.pinpoint.web.view; + +import com.navercorp.pinpoint.common.server.util.time.Range; +import com.navercorp.pinpoint.web.util.TimeWindow; +import com.navercorp.pinpoint.web.util.TimeWindowSlotCentricSampler; +import com.navercorp.pinpoint.web.vo.chart.Point; +import com.navercorp.pinpoint.web.vo.chart.UncollectedPointCreatorFactory; +import com.navercorp.pinpoint.web.vo.stat.SampledAgentStatDataPoint; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorData; +import com.navercorp.pinpoint.web.vo.stat.chart.InspectorDataBuilder; +import com.navercorp.pinpoint.web.vo.stat.chart.StatChartGroup; +import com.navercorp.pinpoint.web.vo.stat.chart.agent.AgentStatPoint; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class InspectorViewTest { + + private enum TestChartType implements StatChartGroup.AgentChartType{ + TEST_CHART_TYPE; + } + + private static class TestAgentStatDataPoint implements SampledAgentStatDataPoint { + + public static final Point.UncollectedPointCreator> UNCOLLECTED_POINT_CREATOR = UncollectedPointCreatorFactory.createIntPointCreator(-1); + + private final AgentStatPoint agentStatPoint; + + public TestAgentStatDataPoint(AgentStatPoint agentStatPoint) { + this.agentStatPoint = agentStatPoint; + } + + public AgentStatPoint getAgentStatPoint() { + return agentStatPoint; + } + } + + @Test + public void inspectorViewTest(){ + String title = "testTitle"; + String unit = "testUnit"; + Map, ?>> valueFunctionMap = new HashMap<>(); + valueFunctionMap.put("function1", P -> P.getMinYVal()); + valueFunctionMap.put("function2", P -> P.getMinYVal()); + valueFunctionMap.put("function3", P -> P.getMinYVal()); + Range range = Range.between(0, 1000*60); + TimeWindow timeWindow = new TimeWindow(range, new TimeWindowSlotCentricSampler()); + List testAgentStatDataPoints = createTestAgentStatDataPoint(); + + InspectorDataBuilder> inspectorDataBuilder = new InspectorDataBuilder<>(TestAgentStatDataPoint.UNCOLLECTED_POINT_CREATOR, title, unit); + for (Map.Entry, ?>> e : valueFunctionMap.entrySet()){ + inspectorDataBuilder.addValueFunction(e.getKey(), e.getValue()); + } + inspectorDataBuilder.addPointFunction(TestChartType.TEST_CHART_TYPE, TestAgentStatDataPoint::getAgentStatPoint); + + InspectorData inspectorData = inspectorDataBuilder.build(timeWindow, testAgentStatDataPoints); + InspectorView inspectorView = new InspectorView(inspectorData); + + Assert.assertEquals(inspectorView.getTitle(), title); + Assert.assertEquals(inspectorView.getUnit(), unit); + Assert.assertEquals(inspectorView.getTimestamp().size(), timeWindow.getWindowRangeCount()); + Assert.assertEquals(inspectorView.getMetricValueGroups().size(), TestChartType.values().length); + InspectorView.InspectorValueGroupView inspectorValueGroupView = inspectorView.getMetricValueGroups().get(0); + Assert.assertEquals(inspectorValueGroupView.getMetricValues().size(), valueFunctionMap.size()); + } + + private List createTestAgentStatDataPoint() { + List testAgentStatDataPoints = new ArrayList<>(); + testAgentStatDataPoints.add(new TestAgentStatDataPoint(new AgentStatPoint(0, 1))); + testAgentStatDataPoints.add(new TestAgentStatDataPoint(new AgentStatPoint(1000*60, 2))); + + return testAgentStatDataPoints; + } +}