From 954fad541f267da3213a63dcf95666b67a478ff9 Mon Sep 17 00:00:00 2001 From: olehp Date: Wed, 28 Feb 2024 16:02:52 +0200 Subject: [PATCH 1/3] Chatty API --- .../ExcessiveAPICallsInsight.stories.tsx | 14 ++ .../ExcessiveAPICallsInsight.stories.tsx | 212 ++++++++++++++++++ .../ExcessiveAPICallsInsight/index.tsx | 90 ++++++++ .../ExcessiveAPICallsInsight/styles.ts | 25 +++ .../ExcessiveAPICallsInsight/types.ts | 19 ++ 5 files changed, 360 insertions(+) create mode 100644 src/components/Insights/common/insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx create mode 100644 src/components/Insights/common/insights/ExcessiveAPICallsInsight/index.tsx create mode 100644 src/components/Insights/common/insights/ExcessiveAPICallsInsight/styles.ts create mode 100644 src/components/Insights/common/insights/ExcessiveAPICallsInsight/types.ts diff --git a/src/components/Insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx b/src/components/Insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx index ae26aaf24..97dd5a1a8 100644 --- a/src/components/Insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx +++ b/src/components/Insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx @@ -36,6 +36,20 @@ export const Default: Story = { specifity: 2, importance: 3, spans: [ + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io", + displayName: "HTTP GET mockapi.io", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + }, + traceId: "00E4D714D4FAD0A00F9D8A39C8A49E8A" + }, { repeats: 29, clientSpan: { diff --git a/src/components/Insights/common/insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx b/src/components/Insights/common/insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx new file mode 100644 index 000000000..ac10eff92 --- /dev/null +++ b/src/components/Insights/common/insights/ExcessiveAPICallsInsight/ExcessiveAPICallsInsight.stories.tsx @@ -0,0 +1,212 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { ExcessiveAPICallsInsight } 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/ExcessiveAPICallsInsight", + component: ExcessiveAPICallsInsight, + 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 Default: Story = { + args: { + insight: { + id: "60b55792-8262-4c5d-9688-7cce7979ad6d", + firstDetected: "2023-12-05T17:25:47.010Z", + lastDetected: "2024-01-05T13:14:47.010Z", + criticality: 0.5, + firstCommitId: "b3f7b3f", + lastCommitId: "a1b2c3d", + deactivatedCommitId: null, + reopenCount: 0, + ticketLink: null, + impact: 0, + name: "HTTP Chatter", + type: InsightType.EndpointChattyApi, + category: InsightCategory.Performance, + specifity: 2, + importance: 3, + spans: [ + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io", + displayName: "HTTP GET mockapi.io", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + }, + traceId: "00E4D714D4FAD0A00F9D8A39C8A49E8A" + }, + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io 2", + displayName: "HTTP GET mockapi.io 2", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io 2", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + }, + traceId: "00E4D714D4FAD0A00F9D8A39C8A49E8B" + }, + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io 3", + displayName: "HTTP GET mockapi.io 3", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io 3", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + }, + traceId: "00E4D714D4FAD0A00F9D8A39C8A49E8C" + }, + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io 4", + displayName: "HTTP GET mockapi.io 4", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io 4", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + }, + traceId: "00E4D714D4FAD0A00F9D8A39C8A49E8C" + } + ], + scope: InsightScope.EntrySpan, + endpointSpan: "HTTP POST /owners/{ownerId}/pets/new", + spanCodeObjectId: + "span:io.opentelemetry.tomcat-10.0$_$HTTP POST /owners/{ownerId}/pets/new", + route: "epHTTP:HTTP POST /owners/{ownerId}/pets/new", + serviceName: "spring-petclinic", + spanInfo: { + name: "HTTP POST /owners/{ownerId}/pets/new", + displayName: "HTTP POST /owners/{ownerId}/pets/new", + instrumentationLibrary: "io.opentelemetry.tomcat-10.0", + spanCodeObjectId: + "span:io.opentelemetry.tomcat-10.0$_$HTTP POST /owners/{ownerId}/pets/new", + methodCodeObjectId: + "method:org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + kind: "Server", + codeObjectId: + "org.springframework.samples.petclinic.owner.PetController$_$processCreationForm" + }, + shortDisplayInfo: { + title: "", + targetDisplayName: "", + subtitle: "", + description: "" + }, + codeObjectId: + "org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + decorators: [ + { + title: "Excessive HTTP Calls", + description: "Numerous Http calls to the same endpoint detected " + } + ], + environment: "BOB-LAPTOP[LOCAL]", + severity: 0.0, + isRecalculateEnabled: false, + prefixedCodeObjectId: + "method:org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + customStartTime: null, + actualStartTime: "2023-08-10T08:04:00Z" + } + } +}; + +export const EmptyTrace: Story = { + args: { + insight: { + id: "60b55792-8262-4c5d-9688-7cce7979ad6d", + firstDetected: "2023-12-05T17:25:47.010Z", + lastDetected: "2024-01-05T13:14:47.010Z", + criticality: 0.5, + firstCommitId: "b3f7b3f", + lastCommitId: "a1b2c3d", + deactivatedCommitId: null, + reopenCount: 0, + ticketLink: null, + impact: 0, + name: "HTTP Chatter", + type: InsightType.EndpointChattyApi, + category: InsightCategory.Performance, + specifity: 2, + importance: 3, + spans: [ + { + repeats: 29, + clientSpan: { + name: "HTTP GET mockapi.io", + displayName: "HTTP GET mockapi.io", + instrumentationLibrary: "io.opentelemetry.okhttp-3.0", + spanCodeObjectId: + "span:io.opentelemetry.okhttp-3.0$_$HTTP GET mockapi.io", + methodCodeObjectId: null, + kind: "Client", + codeObjectId: null + } + } + ], + scope: InsightScope.EntrySpan, + endpointSpan: "HTTP POST /owners/{ownerId}/pets/new", + spanCodeObjectId: + "span:io.opentelemetry.tomcat-10.0$_$HTTP POST /owners/{ownerId}/pets/new", + route: "epHTTP:HTTP POST /owners/{ownerId}/pets/new", + serviceName: "spring-petclinic", + spanInfo: { + name: "HTTP POST /owners/{ownerId}/pets/new", + displayName: "HTTP POST /owners/{ownerId}/pets/new", + instrumentationLibrary: "io.opentelemetry.tomcat-10.0", + spanCodeObjectId: + "span:io.opentelemetry.tomcat-10.0$_$HTTP POST /owners/{ownerId}/pets/new", + methodCodeObjectId: + "method:org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + kind: "Server", + codeObjectId: + "org.springframework.samples.petclinic.owner.PetController$_$processCreationForm" + }, + shortDisplayInfo: { + title: "", + targetDisplayName: "", + subtitle: "", + description: "" + }, + codeObjectId: + "org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + decorators: [ + { + title: "Excessive HTTP Calls", + description: "Numerous Http calls to the same endpoint detected " + } + ], + environment: "BOB-LAPTOP[LOCAL]", + severity: 0.0, + isRecalculateEnabled: false, + prefixedCodeObjectId: + "method:org.springframework.samples.petclinic.owner.PetController$_$processCreationForm", + customStartTime: null, + actualStartTime: "2023-08-10T08:04:00Z" + } + } +}; diff --git a/src/components/Insights/common/insights/ExcessiveAPICallsInsight/index.tsx b/src/components/Insights/common/insights/ExcessiveAPICallsInsight/index.tsx new file mode 100644 index 000000000..126bd7c40 --- /dev/null +++ b/src/components/Insights/common/insights/ExcessiveAPICallsInsight/index.tsx @@ -0,0 +1,90 @@ +import { useContext } from "react"; +import { usePagination } from "../../../../../hooks/usePagination"; +import { ConfigContext } from "../../../../common/App/ConfigContext"; +import { TargetIcon } from "../../../../common/icons/12px/TargetIcon"; +import { Button } from "../../../../common/v3/Button"; +import { Pagination } from "../../../../common/v3/Pagination"; +import { InsightType, Trace } from "../../../types"; +import { InsightCard } from "../../InsightCard"; +import * as s from "./styles"; +import { ExcessiveAPICallsInsightProps } from "./types"; + +const PAGE_SIZE = 3; + +export const ExcessiveAPICallsInsight = ( + props: ExcessiveAPICallsInsightProps +) => { + const config = useContext(ConfigContext); + + const [pageItems, page, setPage] = usePagination( + props.insight.spans, + PAGE_SIZE, + props.insight.codeObjectId + ); + + const handleLinkClick = (spanCodeObjectId: string) => { + props.onAssetLinkClick(spanCodeObjectId, props.insight.type); + }; + + const handleTraceButtonClick = ( + trace: Trace, + insightType: InsightType, + spanCodeObjectId: string + ) => { + props.onTraceButtonClick(trace, insightType, spanCodeObjectId); + }; + + return ( + + + Excessive API calls to specific endpoint found + + + {pageItems.map((span) => { + const spanName = span.clientSpan.displayName; + const traceId = span.traceId; + const spanCodeObjectId = span.clientSpan.spanCodeObjectId; + + return ( + handleLinkClick(spanCodeObjectId)} + buttons={[ + config.isJaegerEnabled && traceId && ( +