Skip to content

Commit 28bc6e0

Browse files
authored
Feature/add bottleneck span insight (#145)
1 parent 9edb25e commit 28bc6e0

File tree

9 files changed

+114
-11
lines changed

9 files changed

+114
-11
lines changed

ide-common/src/main/java/org/digma/intellij/plugin/insights/view/BuildersHolder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.digma.intellij.plugin.model.rest.insights.SlowEndpointInsight;
1111
import org.digma.intellij.plugin.model.rest.insights.SlowestSpansInsight;
1212
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsInsight;
13+
import org.digma.intellij.plugin.model.rest.insights.SpanSlowEndpointsInsight;
1314
import org.digma.intellij.plugin.model.rest.insights.SpanUsagesInsight;
1415
import org.digma.intellij.plugin.model.rest.insights.UnmappedInsight;
1516
import org.digma.intellij.plugin.ui.model.insights.InsightGroupType;
@@ -49,6 +50,8 @@ private ListViewItemBuilder<? extends CodeObjectInsight> newBuilder(InsightType
4950
return new GroupListViewItemBuilder<SpanUsagesInsight>(InsightGroupType.Span, SpanUsagesInsight::getSpan);
5051
case SpanDurations:
5152
return new GroupListViewItemBuilder<SpanDurationsInsight>(InsightGroupType.Span, spanDurationsInsight -> spanDurationsInsight.getSpan().getName());
53+
case SpanEndpointBottleneck:
54+
return new GroupListViewItemBuilder<SpanSlowEndpointsInsight>(InsightGroupType.Span, insight -> insight.getSpan().getName());
5255
case SlowestSpans:
5356
return new GroupListViewItemBuilder<SlowestSpansInsight>(InsightGroupType.HttpEndpoint, SlowestSpansInsight::getRoute);
5457
case LowUsage:

model/src/main/kotlin/org/digma/intellij/plugin/model/model.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ enum class InsightType {
3030
SlowEndpoint,
3131
Unmapped,
3232
TopErrorFlows,
33-
SpanDurationChange
33+
SpanDurationChange,
34+
SpanEndpointBottleneck,
35+
;
3436
}

model/src/main/kotlin/org/digma/intellij/plugin/model/rest/insights/CodeObjectInsight.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import org.digma.intellij.plugin.model.InsightType
2323
JsonSubTypes.Type(value = NormalUsageInsight::class, name = "NormalUsage"),
2424
JsonSubTypes.Type(value = HighUsageInsight::class, name = "HighUsage"),
2525
JsonSubTypes.Type(value = SlowEndpointInsight::class, name = "SlowEndpoint"),
26-
JsonSubTypes.Type(value = SpanDurationsInsight::class, name = "SpanDurations")
26+
JsonSubTypes.Type(value = SpanDurationsInsight::class, name = "SpanDurations"),
27+
JsonSubTypes.Type(value = SpanSlowEndpointsInsight::class, name = "SpanEndpointBottleneck"),
2728
)
2829
interface CodeObjectInsight {
2930
val type: InsightType
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.digma.intellij.plugin.model.rest.insights
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
5+
import java.beans.ConstructorProperties
6+
7+
@JsonIgnoreProperties(ignoreUnknown = true)
8+
data class EndpointInfo
9+
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
10+
@ConstructorProperties("route", "serviceName", "instrumentationLibrary")
11+
constructor(
12+
val route: String,
13+
val serviceName: String,
14+
val instrumentationLibrary: String,
15+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.digma.intellij.plugin.model.rest.insights
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
5+
import java.beans.ConstructorProperties
6+
7+
@JsonIgnoreProperties(ignoreUnknown = true)
8+
data class SlowEndpointInfo
9+
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
10+
@ConstructorProperties("endpointInfo", "p50", "p95", "p99")
11+
constructor(
12+
val endpointInfo: EndpointInfo,
13+
val p50: Percentile,
14+
val p95: Percentile,
15+
val p99: Percentile,
16+
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.digma.intellij.plugin.model.rest.insights
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
5+
import org.digma.intellij.plugin.model.InsightType
6+
import java.beans.ConstructorProperties
7+
8+
@JsonIgnoreProperties(ignoreUnknown = true)
9+
data class SpanSlowEndpointsInsight@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
10+
@ConstructorProperties("codeObjectId", "span", "slowEndpoints")
11+
constructor(
12+
override val codeObjectId: String,
13+
val span: SpanInfo,
14+
val slowEndpoints: List<SlowEndpointInfo>,
15+
) : CodeObjectInsight {
16+
override val type: InsightType = InsightType.SpanEndpointBottleneck
17+
}

model/src/main/kotlin/org/digma/intellij/plugin/ui/model/insights/InsightListViewItem.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ open class InsightListViewItem<INSIGHT : CodeObjectInsight>(insight: INSIGHT) :
1818
InsightType.SpanUsages -> 60
1919
InsightType.SpanDurations -> 65
2020
InsightType.SpanDurationChange -> 66
21+
InsightType.SpanEndpointBottleneck -> 67
2122
// HTTP Endpoints
2223
InsightType.SlowestSpans -> 40
2324
InsightType.LowUsage -> 30

src/main/kotlin/org/digma/intellij/plugin/ui/list/insights/InsightsListCellRenderer.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.digma.intellij.plugin.model.rest.insights.NormalUsageInsight
1717
import org.digma.intellij.plugin.model.rest.insights.SlowEndpointInsight
1818
import org.digma.intellij.plugin.model.rest.insights.SlowestSpansInsight
1919
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsInsight
20+
import org.digma.intellij.plugin.model.rest.insights.SpanSlowEndpointsInsight
2021
import org.digma.intellij.plugin.model.rest.insights.SpanUsagesInsight
2122
import org.digma.intellij.plugin.model.rest.insights.UnmappedInsight
2223
import org.digma.intellij.plugin.ui.common.CopyableLabelHtml
@@ -65,6 +66,8 @@ class InsightsListCellRenderer : AbstractPanelListCellRenderer() {
6566
is SpanUsagesInsight -> spanUsagesPanel(project, value.modelObject as SpanUsagesInsight)
6667
is SpanDurationsInsight -> spanDurationPanel(project, value.modelObject as SpanDurationsInsight,
6768
panelsLayoutHelper)
69+
is SpanSlowEndpointsInsight -> spanSlowEndpointsPanel(project, value.modelObject as SpanSlowEndpointsInsight,
70+
panelsLayoutHelper)
6871
is UnmappedInsight -> unmappedInsightPanel(value.modelObject as UnmappedInsight,
6972
panelsLayoutHelper)
7073
else -> genericPanelForSingleInsight(value.modelObject, panelsLayoutHelper)

src/main/kotlin/org/digma/intellij/plugin/ui/list/insights/SlowestSpansPanel.kt

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,24 @@ package org.digma.intellij.plugin.ui.list.insights
33
import com.intellij.openapi.project.Project
44
import com.intellij.ui.components.ActionLink
55
import com.intellij.ui.components.JBLabel
6-
import com.intellij.ui.components.JBPanel
7-
import com.intellij.ui.dsl.builder.RowLayout
8-
import com.intellij.ui.dsl.builder.panel
9-
import com.intellij.ui.dsl.gridLayout.HorizontalAlign
106
import com.intellij.util.ui.JBUI
117
import org.digma.intellij.plugin.document.CodeObjectsUtil
8+
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema
129
import org.digma.intellij.plugin.model.rest.insights.Percentile
10+
import org.digma.intellij.plugin.model.rest.insights.SlowEndpointInfo
1311
import org.digma.intellij.plugin.model.rest.insights.SlowSpanInfo
1412
import org.digma.intellij.plugin.model.rest.insights.SlowestSpansInsight
13+
import org.digma.intellij.plugin.model.rest.insights.SpanSlowEndpointsInsight
1514
import org.digma.intellij.plugin.service.InsightsActionsService
16-
import org.digma.intellij.plugin.ui.common.*
15+
import org.digma.intellij.plugin.ui.common.Laf
16+
import org.digma.intellij.plugin.ui.common.asHtml
17+
import org.digma.intellij.plugin.ui.common.buildBoldTitleGrayedComment
18+
import org.digma.intellij.plugin.ui.common.buildLinkTextWithTitleAndGrayedComment
1719
import org.digma.intellij.plugin.ui.list.PanelsLayoutHelper
18-
import java.awt.BorderLayout
1920
import java.awt.GridLayout
2021
import java.math.BigDecimal
2122
import java.math.RoundingMode
22-
import javax.swing.BorderFactory
23-
import javax.swing.JLabel
2423
import javax.swing.JPanel
25-
import javax.swing.SwingConstants
2624

2725
fun slowestSpansPanel(project: Project, insight: SlowestSpansInsight, moreData: HashMap<String, Any>, panelsLayoutHelper: PanelsLayoutHelper): JPanel {
2826

@@ -63,6 +61,48 @@ fun slowestSpansPanel(project: Project, insight: SlowestSpansInsight, moreData:
6361
panelsLayoutHelper)
6462
}
6563

64+
fun spanSlowEndpointsPanel(project: Project, insight: SpanSlowEndpointsInsight, panelsLayoutHelper: PanelsLayoutHelper): JPanel {
65+
val endpointsListPanel = JPanel()
66+
endpointsListPanel.layout = GridLayout(insight.slowEndpoints.size, 1, 0, 3)
67+
endpointsListPanel.border = JBUI.Borders.empty()
68+
endpointsListPanel.isOpaque = false
69+
70+
insight.slowEndpoints.forEach {slowEndpointInfo ->
71+
val currContainerPanel = JPanel(GridLayout(2, 1, 0, 3))
72+
endpointsListPanel.border = JBUI.Borders.empty()
73+
currContainerPanel.isOpaque = false
74+
75+
val routeInfo = EndpointSchema.getRouteInfo(slowEndpointInfo.endpointInfo.route)
76+
val shortRouteName = routeInfo.shortName
77+
78+
val line1 = JBLabel(asHtml("${slowEndpointInfo.endpointInfo.serviceName}: <b>$shortRouteName</b>"))
79+
val line2 = JBLabel(asHtml(descriptionOf(slowEndpointInfo)))
80+
81+
currContainerPanel.add(line1)
82+
currContainerPanel.add(line2)
83+
endpointsListPanel.add(currContainerPanel);
84+
}
85+
86+
return createInsightPanel(
87+
"Bottleneck",
88+
"The following trace sources spend a significant portion here:",
89+
Laf.Icons.Insight.BOTTLENECK,
90+
endpointsListPanel,
91+
null,
92+
panelsLayoutHelper)
93+
}
94+
95+
fun descriptionOf(sei: SlowEndpointInfo): String {
96+
if (sei.p95.fraction > 0) {
97+
return "Up to ~${percentageForDisplaySlowSpanInfo(sei.p95)} of entire of the entire request time ${durationText(sei.p95)}"
98+
}
99+
100+
return "Up to ~${percentageForDisplaySlowSpanInfo(sei.p50)} of entire of the entire request time ${durationText(sei.p50)}"
101+
}
102+
103+
fun durationText(percentile: Percentile): String {
104+
return "${percentile.maxDuration.value}${percentile.maxDuration.unit}"
105+
}
66106

67107
fun descriptionOf(span: SlowSpanInfo): String {
68108
if (span.p50.fraction > 0.4)
@@ -74,6 +114,11 @@ fun descriptionOf(span: SlowSpanInfo): String {
74114
return "1% of the users by up to ${span.p99.maxDuration.value}${span.p99.maxDuration.unit}"
75115
}
76116

117+
private fun percentageForDisplaySlowSpanInfo(percentile: Percentile): String {
118+
val decimal = BigDecimal(percentile.fraction * 100).setScale(3, RoundingMode.HALF_DOWN)
119+
return decimal.toPlainString()
120+
}
121+
77122
fun genToolTip(span: SlowSpanInfo): String {
78123
return asHtml(
79124
"""

0 commit comments

Comments
 (0)