Skip to content

Commit 47ef881

Browse files
Add EndpointScaling insight (#1344)
* Add EndpointScaling insight
1 parent 624b9d5 commit 47ef881

File tree

53 files changed

+1364
-167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1364
-167
lines changed

dependencies.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"jetBrainsPluginVersion": "2.0.411",
33
"visualStudioExtensionVersion": "1.2.4",
4-
"jaegerUIVersion": "1.29.1-digma.1.1.2",
4+
"jaegerUIVersion": "1.29.1-digma.1.2.0",
55
"jaegerVersion": "1.45.0"
66
}

src/components/Admin/common/MainSidebarOverlay/MainSidebar/Issues/index.tsx

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,46 +19,26 @@ import {
1919
setIssuesInsightInfoToOpenTicket
2020
} from "../../../../../../redux/slices/repositorySlice";
2121
import { isUndefined } from "../../../../../../typeGuards/isUndefined";
22-
import { InsightType } from "../../../../../../types";
2322
import type { ChangeScopePayload } from "../../../../../../utils/actions/changeScope";
2423
import { sendUserActionTrackingEvent } from "../../../../../../utils/actions/sendUserActionTrackingEvent";
2524
import { EyeIcon } from "../../../../../common/icons/16px/EyeIcon";
2625
import { Pagination } from "../../../../../common/Pagination";
2726
import { NewButton } from "../../../../../common/v3/NewButton";
2827
import { EmptyState } from "../../../../../Insights/EmptyState";
28+
import { getInsightToShowJiraHint } from "../../../../../Insights/InsightsCatalog/InsightsPage";
2929
import { EmptyState as InsightsPageEmptyState } from "../../../../../Insights/InsightsCatalog/InsightsPage/EmptyState";
3030
import { InsightCardRenderer } from "../../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer";
3131
import { actions } from "../../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/hooks/useDismissal";
3232
import { ViewMode } from "../../../../../Insights/InsightsCatalog/types";
3333
import { InsightTicketRenderer } from "../../../../../Insights/InsightTicketRenderer";
34-
import {
35-
type CodeObjectInsight,
36-
type GenericCodeObjectInsight
37-
} from "../../../../../Insights/types";
34+
import { type GenericCodeObjectInsight } from "../../../../../Insights/types";
3835
import { trackingEvents } from "../../../../tracking";
3936
import { SuggestionBar } from "../SuggestionBar";
4037
import * as s from "./styles";
4138
import type { IssuesProps } from "./types";
4239

4340
const PAGE_SIZE = 10;
4441

45-
const getInsightToShowJiraHint = (insights: CodeObjectInsight[]): number => {
46-
const insightsWithJiraButton = [
47-
InsightType.EndpointSpanNPlusOne,
48-
InsightType.SpaNPlusOne,
49-
InsightType.SpanEndpointBottleneck,
50-
InsightType.EndpointBottleneck,
51-
InsightType.SpanQueryOptimization,
52-
InsightType.EndpointHighNumberOfQueries,
53-
InsightType.EndpointQueryOptimizationV2,
54-
InsightType.SpanScaling
55-
];
56-
57-
return insights.findIndex((insight) =>
58-
insightsWithJiraButton.includes(insight.type)
59-
);
60-
};
61-
6242
export const Issues = ({
6343
isTransitioning,
6444
query,

src/components/Dashboard/Report/Cards/DiscoveredCard/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const DiscoveredCard = ({ options, title }: DiscoveredCardProps) => {
1818
<CardOption
1919
key={option.title}
2020
{...option}
21-
isActive={selected == option.title}
21+
isActive={selected === option.title}
2222
/>
2323
))}
2424
</s.Row>

src/components/Errors/ErrorDetails/ErrorDetailsCardContent/FlowStack/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export const FlowStack = ({ data }: FlowStackProps) => {
137137
: frames;
138138

139139
const spanGroups = visibleFrames.reduce((acc, frame, i) => {
140-
if (i == 0 || frame.spanName !== frames[i - 1].spanName) {
140+
if (i === 0 || frame.spanName !== frames[i - 1].spanName) {
141141
acc.push([frame]);
142142
} else {
143143
acc[acc.length - 1].push(frame);

src/components/Highlights/TopIssues/HighlightCardRenderer/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
isEndpointChattyApiV2Highlight,
44
isEndpointHighNumberOfQueriesHighlight,
55
isEndpointQueryOptimizationV2Highlight,
6+
isEndpointScalingHighlight,
67
isEndpointSessionInViewHighlight,
78
isEndpointSlowdownSourceHighlight,
89
isEndpointSpanNPlusOneHighlight,
@@ -17,6 +18,7 @@ import { EndpointBottleneckHighlightCard } from "../highlightCards/EndpointBottl
1718
import { EndpointChattyApiV2HighlightCard } from "../highlightCards/EndpointChattyApiV2HighlightCard";
1819
import { EndpointHighNumberOfQueriesHighlightCard } from "../highlightCards/EndpointHighNumberOfQueriesHighlightCard";
1920
import { EndpointQueryOptimizationV2HighlightCard } from "../highlightCards/EndpointQueryOptimizationV2HighlightCard";
21+
import { EndpointScalingHighlightCard } from "../highlightCards/EndpointScalingHighlightCard";
2022
import { EndpointSessionInViewHighlightCard } from "../highlightCards/EndpointSessionInViewHighlightCard";
2123
import { EndpointSlowdownSourceHighlightCard } from "../highlightCards/EndpointSlowdownSourceHighlightCard";
2224
import { EndpointSpanNPlusOneHighlightCard } from "../highlightCards/EndpointSpanNPlusOneHighlightCard";
@@ -82,4 +84,8 @@ export const HighlightCardRenderer = ({
8284
if (isSpanPerformanceAnomalyHighlight(highlight)) {
8385
return <SpanPerformanceAnomalyHighlightCard data={highlight} />;
8486
}
87+
88+
if (isEndpointScalingHighlight(highlight)) {
89+
return <EndpointScalingHighlightCard data={highlight} />;
90+
}
8591
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { EndpointScalingHighlightCard } from ".";
3+
import { mockedEndpointScalingHighlightData } from "./mockData";
4+
5+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
6+
const meta: Meta<typeof EndpointScalingHighlightCard> = {
7+
title: "Highlights/TopIssues/highlightCards/EndpointScalingHighlightCard",
8+
component: EndpointScalingHighlightCard,
9+
parameters: {
10+
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
11+
layout: "fullscreen"
12+
}
13+
};
14+
15+
export default meta;
16+
17+
type Story = StoryObj<typeof meta>;
18+
19+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
20+
21+
export const Default: Story = {
22+
args: {
23+
data: mockedEndpointScalingHighlightData
24+
}
25+
};
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import type { Row } from "@tanstack/react-table";
2+
import { createColumnHelper } from "@tanstack/react-table";
3+
import type {
4+
EndpointScalingMetrics,
5+
EnvironmentData
6+
} from "../../../../../redux/services/types";
7+
import { useConfigSelector } from "../../../../../store/config/useConfigSelector";
8+
import { ScopeChangeEvent } from "../../../../../types";
9+
import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent";
10+
import { Table } from "../../../common/Table";
11+
import { TableText } from "../../../common/TableText";
12+
import { handleEnvironmentTableRowClick } from "../../../handleEnvironmentTableRowClick";
13+
import { trackingEvents } from "../../../tracking";
14+
import { HighlightCard } from "../../common/HighlightCard";
15+
import { addEnvironmentColumns } from "../addEnvironmentColumns";
16+
import type { EndpointScalingHighlightCardProps } from "./types";
17+
18+
export const EndpointScalingHighlightCard = ({
19+
data
20+
}: EndpointScalingHighlightCardProps) => {
21+
const { scope, environments } = useConfigSelector();
22+
23+
const columnHelper =
24+
createColumnHelper<EnvironmentData<EndpointScalingMetrics>>();
25+
26+
const metricsColumns = [
27+
columnHelper.accessor(
28+
(x) => x.metrics.find((x) => x.id === "IncreasePercentage"),
29+
{
30+
header: "Increased by",
31+
cell: (info) => {
32+
const metric = info.getValue();
33+
const value = metric ? `${String(metric.value)}%` : "";
34+
return metric ? <TableText title={value}>{value}</TableText> : null;
35+
}
36+
}
37+
)
38+
];
39+
40+
const columns = addEnvironmentColumns(columnHelper, metricsColumns);
41+
42+
const handleTableRowClick = (
43+
row: Row<EnvironmentData<EndpointScalingMetrics>>
44+
) => {
45+
sendUserActionTrackingEvent(
46+
trackingEvents.TOP_ISSUES_CARD_TABLE_ROW_CLICKED,
47+
{
48+
insightType: data.insightType
49+
}
50+
);
51+
handleEnvironmentTableRowClick(
52+
scope,
53+
environments,
54+
row.original.environmentId,
55+
ScopeChangeEvent.HighlightsTopIssuesCardItemClicked
56+
);
57+
};
58+
59+
return (
60+
<HighlightCard
61+
highlight={data}
62+
content={
63+
<Table<EnvironmentData<EndpointScalingMetrics>>
64+
columns={columns}
65+
data={data.environments}
66+
onRowClick={handleTableRowClick}
67+
/>
68+
}
69+
/>
70+
);
71+
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import type {
2+
EndpointScalingMetrics,
3+
HighlightData
4+
} from "../../../../../redux/services/types";
5+
import { InsightType } from "../../../../../types";
6+
import { InsightStatus } from "../../../../Insights/types";
7+
8+
export const mockedEndpointScalingMetrics: EndpointScalingMetrics = [
9+
{
10+
id: "IncreasePercentage",
11+
value: 50
12+
}
13+
];
14+
15+
export const mockedEndpointScalingHighlightData: HighlightData<EndpointScalingMetrics> =
16+
{
17+
insightType: InsightType.EndpointScaling,
18+
asset: {
19+
name: "spanName",
20+
displayName: "displayName",
21+
instrumentationLibrary: "instrumentationLibrary",
22+
spanCodeObjectId: "spanCodeObjectId",
23+
methodCodeObjectId: "methodCodeObjectId",
24+
kind: "kind"
25+
},
26+
environments: [
27+
{
28+
environmentId: "1",
29+
environmentName: "Dev",
30+
insightStatus: InsightStatus.Active,
31+
insightCriticality: 0.8,
32+
metrics: mockedEndpointScalingMetrics
33+
},
34+
{
35+
environmentId: "2",
36+
environmentName: "Staging",
37+
insightStatus: InsightStatus.Active,
38+
insightCriticality: 0.8,
39+
metrics: mockedEndpointScalingMetrics
40+
},
41+
{
42+
environmentId: "3",
43+
environmentName: "Production",
44+
insightStatus: InsightStatus.Active,
45+
insightCriticality: 0.8,
46+
metrics: mockedEndpointScalingMetrics
47+
},
48+
{
49+
environmentId: "4",
50+
environmentName: "Env1",
51+
insightStatus: InsightStatus.Active,
52+
insightCriticality: 0.8,
53+
metrics: mockedEndpointScalingMetrics
54+
},
55+
{
56+
environmentId: "5",
57+
environmentName: "Env2",
58+
insightStatus: InsightStatus.Active,
59+
insightCriticality: 0.8,
60+
metrics: mockedEndpointScalingMetrics
61+
},
62+
{
63+
environmentId: "6",
64+
environmentName: "Env3",
65+
insightStatus: InsightStatus.Active,
66+
insightCriticality: 0.8,
67+
metrics: mockedEndpointScalingMetrics
68+
}
69+
]
70+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type {
2+
EndpointScalingMetrics,
3+
HighlightData
4+
} from "../../../../../redux/services/types";
5+
6+
export interface EndpointScalingHighlightCardProps {
7+
data: HighlightData<EndpointScalingMetrics>;
8+
}

src/components/Insights/InsightTicketRenderer/index.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
isEndpointBottleneckInsight,
33
isEndpointHighNumberOfQueriesInsight,
44
isEndpointQueryOptimizationV2Insight,
5+
isEndpointScalingInsight,
56
isEndpointSpanNPlusOneInsight,
67
isSpanEndpointBottleneckInsight,
78
isSpanNPlusOneInsight,
@@ -13,6 +14,7 @@ import type {
1314
EndpointBottleneckInsight,
1415
EndpointHighNumberOfQueriesInsight,
1516
EndpointQueryOptimizationV2Insight,
17+
EndpointScalingInsight,
1618
EndpointSpanNPlusOneInsight,
1719
InsightTicketInfo,
1820
SpanEndpointBottleneckInsight,
@@ -24,6 +26,8 @@ import type {
2426
import { EndpointBottleneckInsightTicket } from "./insightTickets/EndpointBottleneckInsightTicket";
2527
import { EndpointHighNumberOfQueriesInsightTicket } from "./insightTickets/EndpointHighNumberOfQueriesInsightTicket";
2628
import { EndpointQueryOptimizationV2InsightTicket } from "./insightTickets/EndpointQueryOptimizationV2InsightTicket";
29+
import { EndpointScalingInsightTicket } from "./insightTickets/EndpointScalingInsightTicket";
30+
import { EndpointScalingWithSpanInsightTicket } from "./insightTickets/EndpointScalingWithSpanInsightTicket";
2731
import { EndpointSpanNPlusOneInsightTicket } from "./insightTickets/EndpointSpanNPlusOneInsightTicket";
2832
import { SpanEndpointBottleneckInsightTicket } from "./insightTickets/SpanEndpointBottleneckInsightTicket";
2933
import { SpanPerformanceAnomalyInsightTicket } from "./insightTickets/SpanPerformanceAnomalyInsightTicket";
@@ -121,7 +125,7 @@ export const InsightTicketRenderer = ({
121125
if (isSpanScalingBadlyInsight(data.insight)) {
122126
const ticketData = data as InsightTicketInfo<SpanScalingInsight>;
123127
const selectedRootCause = data.insight.rootCauseSpans.find(
124-
(r) => r.spanCodeObjectId == data.spanCodeObjectId
128+
(r) => r.spanCodeObjectId === data.spanCodeObjectId
125129
);
126130
if (selectedRootCause) {
127131
return (
@@ -143,6 +147,30 @@ export const InsightTicketRenderer = ({
143147
}
144148
}
145149

150+
if (isEndpointScalingInsight(data.insight)) {
151+
const ticketData = data as InsightTicketInfo<EndpointScalingInsight>;
152+
153+
switch (data.insight.issueLocation) {
154+
case "SpanRootCause":
155+
case "Span":
156+
return (
157+
<EndpointScalingWithSpanInsightTicket
158+
data={ticketData}
159+
onClose={onClose}
160+
backendInfo={backendInfo}
161+
/>
162+
);
163+
case "Endpoint":
164+
return (
165+
<EndpointScalingInsightTicket
166+
data={ticketData}
167+
onClose={onClose}
168+
backendInfo={backendInfo}
169+
/>
170+
);
171+
}
172+
}
173+
146174
if (isSpanPerformanceAnomalyInsight(data.insight)) {
147175
const ticketData = data as InsightTicketInfo<SpanPerformanceAnomalyInsight>;
148176
return (

0 commit comments

Comments
 (0)