diff --git a/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/EndpointSlowdownSourceInsight.stories.tsx b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/EndpointSlowdownSourceInsight.stories.tsx new file mode 100644 index 000000000..830a4fc7e --- /dev/null +++ b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/EndpointSlowdownSourceInsight.stories.tsx @@ -0,0 +1,131 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { EndpointSlowdownSourceInsight } from "."; +import { InsightCategory, InsightScope, InsightType } from "../../../types"; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Insights/common/insights/EndpointSlowdownSourceInsight", + component: EndpointSlowdownSourceInsight, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +export const WithEvaluatingChange: Story = { + args: { + insight: { + sourceSpanCodeObjectInsight: "sourceSpanCodeObjectInsightId", + id: "60b55792-8262-4c5d-9628-7cde7979ad6d", + firstDetected: "2023-12-05T17:25:47.010Z", + lastDetected: "2024-01-05T13:14:47.010Z", + criticality: 0, + firstCommitId: "b3f7b3f", + lastCommitId: "a1b2c3d", + deactivatedCommitId: null, + reopenCount: 0, + ticketLink: null, + impact: 0, + name: "Endpoint Slowdown Source", + type: InsightType.EndpointSlowdownSource, + category: InsightCategory.Performance, + specifity: 4, + importance: 2, + endpointSlowdownSources: [ + { + percentile: "0.5", + spanInfo: { + name: "WaitForLock", + displayName: "WaitForLock", + instrumentationLibrary: "SampleInsightsController", + spanCodeObjectId: "span:SampleInsightsController$_$WaitForLock", + methodCodeObjectId: null, + kind: "Internal", + codeObjectId: null + }, + level: 0, + previousDuration: { + value: 455.16, + unit: "ms", + raw: 455156000 + }, + currentDuration: { + value: 3.22, + unit: "sec", + raw: 3222871000 + }, + changeTime: "2023-06-30T11:09:55.000Z", + changeVerified: false + }, + { + percentile: "0.95", + spanInfo: { + name: "WaitForLock", + displayName: "WaitForLock", + instrumentationLibrary: "SampleInsightsController", + spanCodeObjectId: "span:SampleInsightsController$_$WaitForLock", + methodCodeObjectId: null, + kind: "Internal", + codeObjectId: null + }, + level: 0, + previousDuration: { + value: 1.6, + unit: "sec", + raw: 1604577000 + }, + currentDuration: { + value: 2.62, + unit: "sec", + raw: 2619854000 + }, + changeTime: "2023-06-30T11:09:54.000Z", + changeVerified: false + } + ], + decorators: [ + { + title: "Endpoint Duration Slowdown Source", + description: "Some spans significantly slowdown this endpoint" + } + ], + scope: InsightScope.EntrySpan, + endpointSpan: "HTTP GET SampleInsights/lock/{milisec}", + spanCodeObjectId: + "span:OpenTelemetry.Instrumentation.AspNetCore$_$HTTP GET SampleInsights/lock/{milisec}", + route: "epHTTP:HTTP GET SampleInsights/lock/{milisec}", + serviceName: "Sample.MoneyTransfer.API", + spanInfo: { + name: "HTTP GET SampleInsights/lock/{milisec}", + displayName: "HTTP GET SampleInsights/lock/{milisec}", + instrumentationLibrary: "OpenTelemetry.Instrumentation.AspNetCore", + spanCodeObjectId: + "span:OpenTelemetry.Instrumentation.AspNetCore$_$HTTP GET SampleInsights/lock/{milisec}", + methodCodeObjectId: + "method:Sample.MoneyTransfer.API.Controllers.SampleInsightsController$_$Lock(Double)", + kind: "Server", + codeObjectId: + "Sample.MoneyTransfer.API.Controllers.SampleInsightsController$_$Lock(Double)" + }, + shortDisplayInfo: { + title: "", + targetDisplayName: "", + subtitle: "", + description: "" + }, + codeObjectId: + "Sample.MoneyTransfer.API.Controllers.SampleInsightsController$_$Lock(Double)", + environment: "BOB-LAPTOP[LOCAL]", + severity: 0, + isRecalculateEnabled: false, + prefixedCodeObjectId: + "method:Sample.MoneyTransfer.API.Controllers.SampleInsightsController$_$Lock(Double)", + customStartTime: null, + actualStartTime: "2023-06-16T11:10:21.334Z" + } + } +}; diff --git a/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/index.tsx b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/index.tsx new file mode 100644 index 000000000..3794e3945 --- /dev/null +++ b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/index.tsx @@ -0,0 +1,79 @@ +import { Tooltip } from "../../../../common/v3/Tooltip"; +import { EndpointSlowdownSource } from "../../../types"; +import { DurationChange } from "../../DurationChange"; +import { InsightCard } from "../../InsightCard"; +import { ListItem } from "../../InsightCard/ListItem"; +import { ContentContainer, Description } from "../styles"; +import * as s from "./styles"; +import { EndpointSlowdownSourceInsightProps } from "./types"; + +export const EndpointSlowdownSourceInsight = ( + props: EndpointSlowdownSourceInsightProps +) => { + const handleSpanLinkClick = (spanCodeObjectId: string) => { + props.onAssetLinkClick(spanCodeObjectId, props.insight.type); + }; + + const p50Sources = props.insight.endpointSlowdownSources?.filter( + (x) => x.percentile === "0.5" + ); + + const p95Sources = props.insight.endpointSlowdownSources?.filter( + (x) => x.percentile === "0.95" + ); + + const renderSourceList = (sources: EndpointSlowdownSource[]) => ( + + {sources.map((x) => { + const spanName = x.spanInfo.displayName; + const spanCodeObjectId = x.spanInfo.spanCodeObjectId; + + return ( + + + handleSpanLinkClick(spanCodeObjectId)} + name={spanName} + buttons={[ + + ]} + /> + + + ); + })} + + ); + + return ( + + + Found spans slowing the endpoint + + {p50Sources?.length && ( + <> + Affecting most requests: + {renderSourceList(p50Sources)} + + )} + {p95Sources?.length && ( + <> + Affecting ~5% of requests: + {renderSourceList(p95Sources)} + + )} + + } + onRecalculate={props.onRecalculate} + onRefresh={props.onRefresh} + /> + ); +}; diff --git a/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/styles.ts b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/styles.ts new file mode 100644 index 000000000..38f6813fd --- /dev/null +++ b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/styles.ts @@ -0,0 +1,17 @@ +import styled from "styled-components"; +import { subscriptRegularTypography } from "../../../../common/App/typographies"; + +export const SourceList = styled.div` + display: flex; + flex-direction: column; + gap: 4px; +`; + +export const Source = styled.span` + gap: 8px; +`; + +export const InsightDescription = styled.span` + padding-bottom: 8px; + ${subscriptRegularTypography} +`; diff --git a/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/types.ts b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/types.ts new file mode 100644 index 000000000..6ad58b90f --- /dev/null +++ b/src/components/Insights/common/insights/EndpointSlowdownSourceInsight/types.ts @@ -0,0 +1,13 @@ +import { + EndpointSlowdownSourceInsight, + InsightProps, + InsightType +} from "../../../types"; + +export interface EndpointSlowdownSourceInsightProps extends InsightProps { + insight: EndpointSlowdownSourceInsight; + onAssetLinkClick: ( + spanCodeObjectId: string, + insightType: InsightType + ) => void; +} diff --git a/src/components/Insights/common/insights/SpanNexusInsight/styles.ts b/src/components/Insights/common/insights/SpanNexusInsight/styles.ts index 72891baa0..caaa456ff 100644 --- a/src/components/Insights/common/insights/SpanNexusInsight/styles.ts +++ b/src/components/Insights/common/insights/SpanNexusInsight/styles.ts @@ -1,8 +1,9 @@ import styled from "styled-components"; +import { subscriptRegularTypography } from "../../../../common/App/typographies"; export const Description = styled.div` display: flex; gap: 8px; - font-size: 13px; + ${subscriptRegularTypography} color: ${({ theme }) => theme.colors.v3.text.primary}; `;