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
Expand Up @@ -24,7 +24,8 @@ import type { SpaNPlusOneInsightCardProps } from "./types";
const getSelectorOption = (endpoint: NPlusOneEndpointInfo): Option => ({
route: endpoint.endpointInfo.route,
serviceName: endpoint.endpointInfo.serviceName,
spanCodeObjectId: endpoint.endpointInfo.entrySpanCodeObjectId
spanCodeObjectId: endpoint.endpointInfo.entrySpanCodeObjectId,
duration: endpoint.duration
});

export const SpaNPlusOneInsightCard = ({
Expand All @@ -42,7 +43,12 @@ export const SpaNPlusOneInsightCard = ({
}: SpaNPlusOneInsightCardProps) => {
const endpoints = useMemo(() => insight.endpoints ?? [], [insight.endpoints]);
const selectorOptions = useMemo(
() => endpoints.map(getSelectorOption),
() =>
endpoints
.map(getSelectorOption)
.sort((a, b) =>
a.duration && b.duration ? b.duration.raw - a.duration.raw : 0
),
[endpoints]
);
const endpointWithMaxDuration = endpoints.reduce(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const mockedSpaNPlusOneInsight: SpaNPlusOneInsight = {
duration: {
value: 3.64,
unit: "sec",
raw: 1636050588.0
raw: 3636050588.0
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { isNumber } from "../../../../../../../typeGuards/isNumber";
import { FeatureFlag } from "../../../../../../../types";
import { getDurationString } from "../../../../../../../utils/getDurationString";
import { getPercentileLabel } from "../../../../../../../utils/getPercentileLabel";
import { roundTo } from "../../../../../../../utils/roundTo";
import { Info } from "../../../../../../common/v3/Info";
import { Pagination } from "../../../../../../common/v3/Pagination";
import { Tag } from "../../../../../../common/v3/Tag";
Expand Down Expand Up @@ -82,6 +83,10 @@ export const SpanDurationBreakdownInsightCard = ({
backendInfo,
FeatureFlag.IS_DURATION_BREAKDOWN_QUANTITY_ENABLED
);
const isPercentageOfCallsSupported = getFeatureFlagValue(
backendInfo,
FeatureFlag.IS_DURATION_BREAKDOWN_QUANTITY_ENABLED
);

const columnHelper = createColumnHelper<SpanDurationBreakdownEntry>();

Expand All @@ -90,7 +95,7 @@ export const SpanDurationBreakdownInsightCard = ({
header: "Asset",
id: "asset",
meta: {
width: "60%",
width: "55%",
minWidth: 100
},
cell: (info) => {
Expand All @@ -109,7 +114,7 @@ export const SpanDurationBreakdownInsightCard = ({
id: "quantity",
meta: {
minWidth: 30,
width: "20%",
width: "15%",
info: "The number of times this asset repeats within the trace. The duration shown next to this column represents the overall duration of all asset instances."
},
cell: (info) => {
Expand All @@ -131,12 +136,42 @@ export const SpanDurationBreakdownInsightCard = ({
);
}
}),
columnHelper.accessor((row) => row, {
header: "% Calls",
id: "percentageOfCalls",
meta: {
minWidth: 30,
width: "15%",
info: "The percentage of calls triggering this child asset"
},
cell: (info) => {
const entry = info.getValue();

const percentageOfCalls = entry.percentageOfCalls;
if (!percentageOfCalls) {
return null;
}

const percentageString = `${
percentageOfCalls < 1 ? "<1" : roundTo(percentageOfCalls, 2)
}%`;

return (
<Tag
key={"percentageOfCalls"}
title={percentageString}
type={"highlight"}
content={percentageString}
/>
);
}
}),
columnHelper.accessor((row) => row, {
header: "Duration",
id: "duration",
meta: {
minWidth: 30,
width: "20%",
width: "15%",
info: "The execution time of the asset"
},
cell: (info) => {
Expand All @@ -161,9 +196,12 @@ export const SpanDurationBreakdownInsightCard = ({
})
];

let columnVisibility = { quantity: false };
let columnVisibility = { quantity: false, percentageOfCalls: false };
if (isQuantitySupported) {
columnVisibility = { quantity: true };
columnVisibility = { ...columnVisibility, quantity: true };
}
if (isPercentageOfCallsSupported) {
columnVisibility = { ...columnVisibility, percentageOfCalls: true };
}

const filteredItems = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import type { SpanEndpointBottleneckInsightCardProps } from "./types";
const getSelectorOption = (endpoint: BottleneckEndpointInfo): Option => ({
route: trimEndpointScheme(endpoint.endpointInfo.route),
serviceName: endpoint.endpointInfo.serviceName,
spanCodeObjectId: endpoint.endpointInfo.spanCodeObjectId
spanCodeObjectId: endpoint.endpointInfo.spanCodeObjectId,
duration: endpoint.avgDurationWhenBeingBottleneck
});

export const SpanEndpointBottleneckInsightCard = ({
Expand All @@ -48,7 +49,12 @@ export const SpanEndpointBottleneckInsightCard = ({
[insight.slowEndpoints]
);
const selectorOptions: Option[] = useMemo(
() => slowEndpoints.map(getSelectorOption),
() =>
slowEndpoints
.map(getSelectorOption)
.sort((a, b) =>
a.duration && b.duration ? b.duration.raw - a.duration.raw : 0
),
[slowEndpoints]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export const SpanQueryOptimizationInsightCard = ({
>
{durationString}
</KeyValue>
<KeyValue label={"Typical Duration"}>
<KeyValue
label={"Typical Duration"}
info={
"The average duration of other queries of the same type (e.g. SELECT, UPDATE, INSERT etc.) running against the same DB in the same environment"
}
>
{getDurationString(insight.typicalDuration)}
</KeyValue>
<KeyValue label={"Database"}>{insight.dbName}</KeyValue>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export interface SpanDurationBreakdownEntry {
spanCodeObjectId: string;
percentiles: DurationPercentile[];
codeObjectId: string | null;
percentageOfCalls?: number;
}

export interface SpanDurationBreakdownInsight extends SpanInsight {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Link } from "../../v3/Link";
import { Tooltip } from "../../v3/Tooltip";
import * as s from "./styles";
import type { EndpointOptionProps } from "./types";
Expand All @@ -10,7 +9,9 @@ export const EndpointOption = ({
onSpanLinkClick,
selected,
hideCopyIcon,
onClick
onClick,
duration,
hideDuration
}: EndpointOptionProps) => {
const title = `${serviceName} ${route}`;

Expand All @@ -23,16 +24,21 @@ export const EndpointOption = ({
onClick={() => onClick && onClick()}
>
<s.ServiceName>{serviceName}</s.ServiceName>
{spanCodeObjectId && onSpanLinkClick ? (
<Link onClick={() => onSpanLinkClick(spanCodeObjectId)}>
{route}
</Link>
) : (
<span>{route}</span>
<s.Route>
{spanCodeObjectId && onSpanLinkClick ? (
<s.Link onClick={() => onSpanLinkClick(spanCodeObjectId)}>
{route}
</s.Link>
) : (
<span>{route}</span>
)}
</s.Route>
{!hideCopyIcon && <s.StyledCopyButton text={route} />}
{!selected && !hideDuration && duration && (
<s.Duration>{duration}</s.Duration>
)}
</s.EndpointName>
</Tooltip>
{!hideCopyIcon && <s.StyledCopyButton text={route} />}
</s.Container>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled, { css } from "styled-components";
import { footnoteRegularTypography } from "../../App/typographies";
import { CopyButton } from "../../v3/CopyButton";
import { Link as CommonLink } from "../../v3/Link";
import type { EndpointNameProps } from "./types";

export const StyledCopyButton = styled(CopyButton)`
Expand Down Expand Up @@ -34,9 +35,7 @@ export const EndpointName = styled.div<EndpointNameProps>`
width: 100%;
padding: 4px 8px;
${ServiceName} {
flex-shrink: 0;
width: 151px;
max-width: none;
width: 30%;
}
`;
}
Expand All @@ -54,9 +53,30 @@ export const EndpointName = styled.div<EndpointNameProps>`
`;

export const ServiceName = styled.span`
max-width: fit-content;
max-width: 100px;
min-width: 30px;
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: ${({ theme }) => theme.colors.v3.text.tertiary};
`;

export const Route = styled.span`
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;

export const Link = styled(CommonLink)`
width: 100%;
`;

export const Duration = styled.span`
flex-shrink: 0;
width: 80px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export interface EndpointOptionProps {
onSpanLinkClick?: (spanCodeObjectId: string) => void;
hideCopyIcon?: boolean;
onClick?: ((spanCodeObjectId?: string) => void) | null;
duration?: string;
hideDuration?: boolean;
}

export interface EndpointNameProps {
Expand Down
4 changes: 4 additions & 0 deletions src/components/common/AffectedEndpointsSelector/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ReactNode } from "react";
import { DELIMITER } from "../../../constants";
import { getDurationString } from "../../../utils/getDurationString";
import { trimEndpointScheme } from "../../../utils/trimEndpointScheme";
import { Select } from "../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/Select";
import type { CustomContentProps } from "../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/Select/types";
Expand All @@ -21,6 +22,7 @@ const renderOptions = (
endpoints.map((x) => {
const spanCodeObjectId = x.spanCodeObjectId;
const route = trimEndpointScheme(x.route);
const durationString = x.duration && getDurationString(x.duration);
return {
label: route,
customContent: ({ isSelected, onClick }) => (
Expand All @@ -32,6 +34,7 @@ const renderOptions = (
onSpanLinkClick={handleLinkClick}
hideCopyIcon={!isSelected}
onClick={onClick}
duration={durationString}
/>
),
value: getEndpointKey(x)
Expand Down Expand Up @@ -66,6 +69,7 @@ export const AffectedEndpointsSelector = ({
<EndpointOption
route={"Endpoint"}
serviceName={"Service"}
duration={"Duration"}
hideCopyIcon={true}
/>
</s.ListHeader>
Expand Down
3 changes: 3 additions & 0 deletions src/components/common/AffectedEndpointsSelector/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Duration } from "../../../globals";

export interface FilterButtonProps {
isActive: boolean;
onClick: () => void;
Expand All @@ -20,4 +22,5 @@ export interface Option {
serviceName: string;
route: string;
spanCodeObjectId: string;
duration?: Duration;
}
3 changes: 2 additions & 1 deletion src/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export const featureFlagMinBackendVersions: Record<FeatureFlag, string> = {
"0.3.145",
[FeatureFlag.IS_GLOBAL_ERROR_PIN_ENABLED]: "0.3.147",
[FeatureFlag.IS_GLOBAL_ERROR_DISMISS_ENABLED]: "0.3.148",
[FeatureFlag.IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED]: "0.3.149"
[FeatureFlag.IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED]: "0.3.149",
[FeatureFlag.IS_DURATION_BREAKDOWN_PERCENTAGE_OF_CALLS_ENABLED]: "0.3.193"
};

export const getFeatureFlagValue = (
Expand Down
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export enum FeatureFlag {
ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED,
IS_GLOBAL_ERROR_PIN_ENABLED,
IS_GLOBAL_ERROR_DISMISS_ENABLED,
IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED
IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED,
IS_DURATION_BREAKDOWN_PERCENTAGE_OF_CALLS_ENABLED
}

export enum InsightType {
Expand Down
Loading