Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package org.digma.intellij.plugin.insights.view;

import org.digma.intellij.plugin.model.InsightType;
import org.digma.intellij.plugin.model.rest.insights.*;
import org.digma.intellij.plugin.model.rest.insights.CodeObjectInsight;
import org.digma.intellij.plugin.model.rest.insights.ErrorInsight;
import org.digma.intellij.plugin.model.rest.insights.HighUsageInsight;
import org.digma.intellij.plugin.model.rest.insights.HotspotInsight;
import org.digma.intellij.plugin.model.rest.insights.LowUsageInsight;
import org.digma.intellij.plugin.model.rest.insights.NormalUsageInsight;
import org.digma.intellij.plugin.model.rest.insights.SlowEndpointInsight;
import org.digma.intellij.plugin.model.rest.insights.SlowestSpansInsight;
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsInsight;
import org.digma.intellij.plugin.model.rest.insights.SpanUsagesInsight;
import org.digma.intellij.plugin.model.rest.insights.UnmappedInsight;
import org.digma.intellij.plugin.ui.model.insights.InsightGroupType;
import org.digma.intellij.plugin.view.EmptyListViewItemBuilder;
import org.digma.intellij.plugin.view.ListViewItemBuilder;
Expand Down Expand Up @@ -36,7 +46,7 @@ private ListViewItemBuilder<? extends CodeObjectInsight> newBuilder(InsightType
case Errors:
return new NoGroupListViewItemBuilder<ErrorInsight>();
case SpanUsages:
return new GroupListViewItemBuilder<SpanInsight>(InsightGroupType.Span, SpanInsight::getSpan);
return new GroupListViewItemBuilder<SpanUsagesInsight>(InsightGroupType.Span, SpanUsagesInsight::getSpan);
case SpanDurations:
return new GroupListViewItemBuilder<SpanDurationsInsight>(InsightGroupType.Span, spanDurationsInsight -> spanDurationsInsight.getSpan().getName());
case SlowestSpans:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import org.digma.intellij.plugin.model.InsightType
@JsonSubTypes(
JsonSubTypes.Type(value = HotspotInsight::class, name = "HotSpot"),
JsonSubTypes.Type(value = ErrorInsight::class, name = "Errors"),
JsonSubTypes.Type(value = SpanInsight::class, name = "SpanUsages"),
JsonSubTypes.Type(value = SpanUsagesInsight::class, name = "SpanUsages"),
JsonSubTypes.Type(value = SlowestSpansInsight::class, name = "SlowestSpans"),
JsonSubTypes.Type(value = LowUsageInsight::class, name = "LowUsage"),
JsonSubTypes.Type(value = NormalUsageInsight::class, name = "NormalUsage"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ import java.beans.ConstructorProperties
@JsonIgnoreProperties(ignoreUnknown = true)
data class SpanFlow
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
@ConstructorProperties("percentage", "intermediateSpan", "lastServiceSpan", "firstService", "lastService")
constructor(val percentage: Float,
val intermediateSpan: String?,
val lastServiceSpan: String?,
val firstService: Service?,
val lastService: Service?) {

@ConstructorProperties("percentage", "intermediateSpan", "lastServiceSpan", "firstService", "lastService", "sampleTraceIds")
constructor(
val percentage: Float,
val intermediateSpan: String?,
val lastServiceSpan: String?,
val firstService: Service?,
val lastService: Service?,
val sampleTraceIds: List<String>,
) {

data class Service
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
@ConstructorProperties("service", "span")
constructor(val service: String,
val span: String)
constructor(
val service: String,
val span: String,
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator
import org.digma.intellij.plugin.model.InsightType
import java.beans.ConstructorProperties

data class SpanInsight
data class SpanUsagesInsight
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
@ConstructorProperties("codeObjectId", "span", "flows")
constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@ import com.intellij.openapi.project.Project
import com.intellij.ui.dsl.builder.RightGap
import com.intellij.ui.dsl.builder.panel
import com.intellij.ui.dsl.gridLayout.HorizontalAlign
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.CONSUMER_SCHEMA
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.HTTP_SCHEMA
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.RPC_SCHEMA
import org.digma.intellij.plugin.model.rest.insights.ErrorInsight
import org.digma.intellij.plugin.model.rest.insights.GroupViewModel
import org.digma.intellij.plugin.model.rest.insights.HighUsageInsight
import org.digma.intellij.plugin.model.rest.insights.HotspotInsight
import org.digma.intellij.plugin.model.rest.insights.LowUsageInsight
import org.digma.intellij.plugin.model.rest.insights.NormalUsageInsight
import org.digma.intellij.plugin.model.rest.insights.SlowEndpointInsight
import org.digma.intellij.plugin.model.rest.insights.SlowestSpansInsight
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsInsight
import org.digma.intellij.plugin.model.rest.insights.SpanInsight
import org.digma.intellij.plugin.model.rest.insights.SpanUsagesInsight
import org.digma.intellij.plugin.model.rest.insights.UnmappedInsight
import org.digma.intellij.plugin.ui.common.CopyableLabelHtml
import org.digma.intellij.plugin.ui.common.Laf
import org.digma.intellij.plugin.ui.common.asHtml
import org.digma.intellij.plugin.ui.common.span
import org.digma.intellij.plugin.ui.common.spanBold
import org.digma.intellij.plugin.ui.common.spanGrayed
import org.digma.intellij.plugin.model.rest.insights.*
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.CONSUMER_SCHEMA
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.HTTP_SCHEMA
import org.digma.intellij.plugin.model.rest.insights.EndpointSchema.Companion.RPC_SCHEMA
import org.digma.intellij.plugin.ui.list.AbstractPanelListCellRenderer
import org.digma.intellij.plugin.ui.list.PanelsLayoutHelper
import org.digma.intellij.plugin.ui.model.insights.InsightGroupType.HttpEndpoint
Expand Down Expand Up @@ -61,7 +62,7 @@ class InsightsListCellRenderer : AbstractPanelListCellRenderer() {
panelsLayoutHelper)
is SlowestSpansInsight -> slowestSpansPanel(project,
value.modelObject as SlowestSpansInsight, value.moreData, panelsLayoutHelper)
is SpanInsight -> spanPanel(value.modelObject as SpanInsight)
is SpanUsagesInsight -> spanUsagesPanel(project, value.modelObject as SpanUsagesInsight)
is SpanDurationsInsight -> spanDurationPanel(project, value.modelObject as SpanDurationsInsight,
panelsLayoutHelper)
is UnmappedInsight -> unmappedInsightPanel(value.modelObject as UnmappedInsight,
Expand Down Expand Up @@ -96,7 +97,7 @@ class InsightsListCellRenderer : AbstractPanelListCellRenderer() {
}

private fun endpointGroupTitle(value: InsightsList.GroupTitleModel): JPanel {
val groupViewModel = createEndpointGroupViewModel(value.groupId);
val groupViewModel = createEndpointGroupViewModel(value.groupId)
return groupTitlePanel(groupViewModel.titleText, groupViewModel.labelText,groupViewModel.icon)
}

Expand All @@ -116,7 +117,7 @@ class InsightsListCellRenderer : AbstractPanelListCellRenderer() {
}

private fun createEndpointGroupViewModel(fullRouteName: String): GroupViewModel{
val routeInfo = EndpointSchema.getRouteInfo(fullRouteName);
val routeInfo = EndpointSchema.getRouteInfo(fullRouteName)
val endpoint = routeInfo.shortName
if(routeInfo.schema == HTTP_SCHEMA){
val split =endpoint.split(' ')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import com.intellij.ui.dsl.builder.panel
import com.intellij.ui.dsl.gridLayout.HorizontalAlign
import com.intellij.util.containers.isNullOrEmpty
import com.intellij.util.ui.JBUI.Borders.empty
import com.intellij.util.ui.WrapLayout
import org.digma.intellij.plugin.analytics.AnalyticsService
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsInsight
import org.digma.intellij.plugin.model.rest.insights.SpanDurationsPercentile
import org.digma.intellij.plugin.model.rest.insights.SpanFlow
import org.digma.intellij.plugin.model.rest.insights.SpanInfo
import org.digma.intellij.plugin.model.rest.insights.SpanInsight
import org.digma.intellij.plugin.model.rest.insights.SpanUsagesInsight
import org.digma.intellij.plugin.settings.SettingsState
import org.digma.intellij.plugin.ui.common.CopyableLabel
import org.digma.intellij.plugin.ui.common.CopyableLabelHtml
Expand All @@ -31,6 +32,7 @@ import org.ocpsoft.prettytime.PrettyTime
import org.threeten.extra.AmountFormats
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.FlowLayout
import java.awt.GridLayout
import java.io.InputStreamReader
import java.sql.Timestamp
Expand Down Expand Up @@ -58,29 +60,34 @@ class SpanPanels {

}

fun spanPanel(spanInsight: SpanInsight): JPanel {
fun spanUsagesPanel(project: Project, spanUsagesInsight: SpanUsagesInsight): JPanel {

val title = JLabel(asHtml(spanBold("Top Usage")), SwingConstants.LEFT)
title.isOpaque = false

val flowsListPanel = JBPanel<JBPanel<*>>()
flowsListPanel.layout = GridLayout(spanInsight.flows.size, 1, 0, 3)
flowsListPanel.layout = GridLayout(spanUsagesInsight.flows.size, 1, 0, 3)
flowsListPanel.border = empty()
flowsListPanel.isOpaque = false

spanInsight.flows.forEach { spanFlow: SpanFlow ->
spanUsagesInsight.flows.forEach { spanFlow: SpanFlow ->

val builder =
StringBuilder("${span(String.format("%.1f", spanFlow.percentage))}% " +
"${spanGrayed(spanFlow.firstService?.service.toString())}: " +
" ${span(spanFlow.firstService?.span.toString())}")
val builder = StringBuilder("${span(String.format("%.1f", spanFlow.percentage))}% ")

var spanName = spanUsagesInsight.span // default, just in case first service is not found
spanFlow.firstService?.let { firstService ->
builder.append(spanGrayed(firstService.service + ": "))
builder.append(span(firstService.span))
spanName = firstService.span
}
spanFlow.intermediateSpan?.let { intermediateSpan ->
builder.append(" ${spanGrayed(ARROW_RIGHT)} ")
builder.append(span(intermediateSpan))
}
spanFlow.lastService?.let { lastService ->
builder.append(" ${spanGrayed(ARROW_RIGHT)} ")
builder.append(span("${lastService.service}: ${lastService.span}"))
builder.append(spanGrayed(lastService.service + ": "))
builder.append(span(lastService.span))
}
spanFlow.lastServiceSpan?.let { lastServiceSpan ->
builder.append(" ${spanGrayed(ARROW_RIGHT)} ")
Expand All @@ -89,7 +96,24 @@ fun spanPanel(spanInsight: SpanInsight): JPanel {

val label = CopyableLabelHtml(asHtml(builder.toString()))
label.alignmentX = 0.0f
flowsListPanel.add(label)

var traceSample: TraceSample? = null
spanFlow.sampleTraceIds.firstOrNull()?.let { sampleTraceId ->
traceSample = TraceSample(spanName, sampleTraceId)
}
val buttonToJaeger = buildButtonToJaeger(project, "Trace", spanName, traceSample)
if (buttonToJaeger == null) {
flowsListPanel.add(label)
} else {
val wrapperPanel = JBPanel<JBPanel<*>>()
wrapperPanel.andTransparent()
wrapperPanel.layout = WrapLayout(FlowLayout.LEFT, 3, 3)
wrapperPanel.add(label)
wrapperPanel.add(buttonToJaeger)

flowsListPanel.add(wrapperPanel)
}

}


Expand Down Expand Up @@ -193,7 +217,7 @@ fun spanDurationPanel(
}

val buttonToGraph = buildButtonToPercentilesGraph(project, spanDurationsInsight.span)
val buttonToJaeger = buildButtonToJaeger(project, spanDurationsInsight.span, traceSamples)
val buttonToJaeger = buildButtonToJaeger(project, "Compare", spanDurationsInsight.span.name, traceSamples)
val iconPanel = buildIconPanelWithLinks(buttonToGraph, buttonToJaeger)

val result = JBPanel<JBPanel<*>>()
Expand Down Expand Up @@ -226,9 +250,10 @@ fun buildIconPanelWithLinks(
return iconPanel
}


// if cannot create the button then would return null
fun buildButtonToJaeger(
project: Project, spanInfo: SpanInfo, traceSamples: List<TraceSample>
project: Project, linkCaption: String, spanName: String, traceSamples: List<TraceSample>
): JButton? {

val settingsState = SettingsState.getInstance(project)
Expand Down Expand Up @@ -261,16 +286,26 @@ fun buildButtonToJaeger(
.replace("__JAEGER_EMBEDDED_URL__", jaegerUrl)
.replace("__CAPTION__", caption)

val editorTitle = "Jaeger sample traces of Span ${spanInfo.name}"
val editorTitle = "Jaeger sample traces of Span ${spanName}"

val button = ActionLink("Compare")
val button = ActionLink(linkCaption)
button.addActionListener {
HTMLEditorProvider.openEditor(project, editorTitle, htmlContent)
}

return button
}

// if cannot create the button then would return null
fun buildButtonToJaeger(
project: Project, linkCaption: String, spanName: String, traceSample: TraceSample?
): JButton? {
if (traceSample == null) {
return null
}
return buildButtonToJaeger(project, linkCaption, spanName, listOf(traceSample))
}

fun buildButtonToPercentilesGraph(project: Project, span: SpanInfo): ActionLink {
val analyticsService = AnalyticsService.getInstance(project)
val button = ActionLink("Histogram")
Expand Down