diff --git a/frontend/src/components/CeleryTask/CeleryTaskDetail/CeleryTaskDetail.tsx b/frontend/src/components/CeleryTask/CeleryTaskDetail/CeleryTaskDetail.tsx index 4e28c6dc0d..8f358536cb 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskDetail/CeleryTaskDetail.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskDetail/CeleryTaskDetail.tsx @@ -2,6 +2,7 @@ import './CeleryTaskDetail.style.scss'; import { Color, Spacing } from '@signozhq/design-tokens'; import { Divider, Drawer, Typography } from 'antd'; +import logEvent from 'api/common/logEvent'; import { PANEL_TYPES } from 'constants/queryBuilder'; import dayjs from 'dayjs'; import { useIsDarkMode } from 'hooks/useDarkMode'; @@ -98,6 +99,12 @@ export default function CeleryTaskDetail({ ...rowData, [taskData.entity]: taskData.value, }); + logEvent('MQ Celery: navigation to trace page', { + filters, + startTime, + endTime, + source: widgetData.title, + }); navigateToTrace(filters, startTime, endTime); }} start={startTime} diff --git a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskBar.tsx b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskBar.tsx index 77d8ae2d5a..c1de79cd01 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskBar.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskBar.tsx @@ -42,10 +42,12 @@ import { function CeleryTaskBar({ onClick, queryEnabled, + checkIfDataExists, }: { onClick?: (task: CaptureDataProps) => void; queryEnabled: boolean; + checkIfDataExists?: (isDataAvailable: boolean) => void; }): JSX.Element { const history = useHistory(); const { pathname } = useLocation(); @@ -187,6 +189,7 @@ function CeleryTaskBar({ onGraphClick(celerySlowestTasksTableWidgetData, ...args) } customSeries={getCustomSeries} + dataAvailable={checkIfDataExists} /> )} {barState === CeleryTaskState.Failed && ( @@ -232,6 +235,7 @@ function CeleryTaskBar({ CeleryTaskBar.defaultProps = { onClick: (): void => {}, + checkIfDataExists: undefined, }; export default CeleryTaskBar; diff --git a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraph.tsx b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraph.tsx index 4b15054d1e..a7d24175b3 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraph.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraph.tsx @@ -35,6 +35,8 @@ function CeleryTaskGraph({ customErrorMessage, start, end, + checkIfDataExists, + analyticsEvent, }: { widgetData: Widgets; onClick?: (task: CaptureDataProps) => void; @@ -48,6 +50,8 @@ function CeleryTaskGraph({ customErrorMessage?: string; start?: number; end?: number; + checkIfDataExists?: (isDataAvailable: boolean) => void; + analyticsEvent?: string; }): JSX.Element { const history = useHistory(); const { pathname } = useLocation(); @@ -125,6 +129,8 @@ function CeleryTaskGraph({ customErrorMessage={customErrorMessage} start={start} end={end} + dataAvailable={checkIfDataExists} + analyticsEvent={analyticsEvent} /> ); @@ -141,6 +147,8 @@ CeleryTaskGraph.defaultProps = { customErrorMessage: undefined, start: undefined, end: undefined, + checkIfDataExists: undefined, + analyticsEvent: undefined, }; export default CeleryTaskGraph; diff --git a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraphGrid.tsx b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraphGrid.tsx index 050e4e42cc..c53c6e1cca 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraphGrid.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskGraphGrid.tsx @@ -1,6 +1,7 @@ import './CeleryTaskGraph.style.scss'; import { Card, Typography } from 'antd'; +import logEvent from 'api/common/logEvent'; import { CardContainer } from 'container/GridCardLayout/styles'; import { useIsDarkMode } from 'hooks/useDarkMode'; import { ChevronDown, ChevronUp } from 'lucide-react'; @@ -92,6 +93,15 @@ export default function CeleryTaskGraphGrid({ })); }; + const checkIfDataExists = (isDataAvailable: boolean, title: string): void => { + if (isDataAvailable) { + logEvent(`MQ Celery: ${title} data exists`, { + graph: title, + isDataAvailable, + }); + } + }; + return (
@@ -124,6 +134,10 @@ export default function CeleryTaskGraphGrid({ widgetData={celeryActiveTasksData} queryEnabled={queryEnabled} customErrorMessage="Enable Flower metrics to view this graph" + checkIfDataExists={(isDataAvailable): void => + checkIfDataExists(isDataAvailable, 'Active Tasks by worker') + } + analyticsEvent="MQ Celery: Flower metric not enabled" />
@@ -173,8 +187,19 @@ export default function CeleryTaskGraphGrid({
{!collapsedSections.traceBasedGraphs && ( <> - - + + checkIfDataExists(isDataAvailable, 'State Graph') + } + /> + + checkIfDataExists(isDataAvailable, 'Task Latency') + } + />
{bottomWidgetData.map((widgetData, index) => ( + checkIfDataExists(isDataAvailable, rightPanelTitle[index]) + } /> ))}
diff --git a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskLatencyGraph.tsx b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskLatencyGraph.tsx index 50cd4675b1..5128823382 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskLatencyGraph.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskLatencyGraph.tsx @@ -1,6 +1,7 @@ import './CeleryTaskGraph.style.scss'; import { Col, Row } from 'antd'; +import logEvent from 'api/common/logEvent'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; import { ViewMenuAction } from 'container/GridCardLayout/config'; @@ -40,8 +41,10 @@ export enum CeleryTaskGraphState { function CeleryTaskLatencyGraph({ queryEnabled, + checkIfDataExists, }: { queryEnabled: boolean; + checkIfDataExists?: (isDataAvailable: boolean) => void; }): JSX.Element { const history = useHistory(); const { pathname } = useLocation(); @@ -61,6 +64,10 @@ function CeleryTaskLatencyGraph({ const handleTabClick = (key: CeleryTaskGraphState): void => { setGraphState(key as CeleryTaskGraphState); + logEvent('MQ Celery: Task latency graph tab clicked', { + taskName: urlQuery.get(QueryParams.taskName), + graphState: key, + }); }; const onDragSelect = useCallback( @@ -195,6 +202,7 @@ function CeleryTaskLatencyGraph({ onDragSelect={onDragSelect} onClickHandler={onGraphClick('Celery_p99_latency')} isQueryEnabled={queryEnabled} + dataAvailable={checkIfDataExists} /> )} @@ -215,6 +223,7 @@ function CeleryTaskLatencyGraph({ onDragSelect={onDragSelect} onClickHandler={onGraphClick('Celery_p95_latency')} isQueryEnabled={queryEnabled} + dataAvailable={checkIfDataExists} /> )} @@ -234,6 +243,7 @@ function CeleryTaskLatencyGraph({ onDragSelect={onDragSelect} onClickHandler={onGraphClick('Celery_p90_latency')} isQueryEnabled={queryEnabled} + dataAvailable={checkIfDataExists} /> )} @@ -243,3 +253,7 @@ function CeleryTaskLatencyGraph({ } export default CeleryTaskLatencyGraph; + +CeleryTaskLatencyGraph.defaultProps = { + checkIfDataExists: undefined, +}; diff --git a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskStateGraphConfig.tsx b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskStateGraphConfig.tsx index 7768df0530..b690741631 100644 --- a/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskStateGraphConfig.tsx +++ b/frontend/src/components/CeleryTask/CeleryTaskGraph/CeleryTaskStateGraphConfig.tsx @@ -2,6 +2,7 @@ import './CeleryTaskGraph.style.scss'; import { Col, Row } from 'antd'; +import logEvent from 'api/common/logEvent'; import { QueryParams } from 'constants/query'; import useUrlQuery from 'hooks/useUrlQuery'; import { Dispatch, SetStateAction, useMemo } from 'react'; @@ -44,12 +45,16 @@ function CeleryTaskStateGraphConfig({ { label: 'Successful', key: CeleryTaskState.Successful }, ]; + const urlQuery = useUrlQuery(); + const handleTabClick = (key: CeleryTaskState): void => { setBarState(key as CeleryTaskState); + logEvent('MQ Celery: State graph tab clicked', { + taskName: urlQuery.get(QueryParams.taskName), + graphState: key, + }); }; - const urlQuery = useUrlQuery(); - const selectedFilters = useMemo( () => getFiltersFromQueryParams( diff --git a/frontend/src/container/GridCardLayout/GridCard/index.tsx b/frontend/src/container/GridCardLayout/GridCard/index.tsx index 388304bf99..edc5b24527 100644 --- a/frontend/src/container/GridCardLayout/GridCard/index.tsx +++ b/frontend/src/container/GridCardLayout/GridCard/index.tsx @@ -1,3 +1,4 @@ +import logEvent from 'api/common/logEvent'; import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { QueryParams } from 'constants/query'; import { PANEL_TYPES } from 'constants/queryBuilder'; @@ -44,6 +45,7 @@ function GridCardGraph({ customErrorMessage, start, end, + analyticsEvent, }: GridCardGraphProps): JSX.Element { const dispatch = useDispatch(); const [errorMessage, setErrorMessage] = useState(); @@ -219,6 +221,11 @@ function GridCardGraph({ setIsInternalServerError( String(error.message).includes('API responded with 500'), ); + if (analyticsEvent) { + logEvent(analyticsEvent, { + error: error.message, + }); + } } setDashboardQueryRangeCalled(true); }, @@ -283,6 +290,7 @@ GridCardGraph.defaultProps = { threshold: undefined, headerMenuList: [MenuItemKeys.View], version: 'v3', + analyticsEvent: undefined, }; export default memo(GridCardGraph); diff --git a/frontend/src/container/GridCardLayout/GridCard/types.ts b/frontend/src/container/GridCardLayout/GridCard/types.ts index 9067f8cf72..199c972e6d 100644 --- a/frontend/src/container/GridCardLayout/GridCard/types.ts +++ b/frontend/src/container/GridCardLayout/GridCard/types.ts @@ -58,6 +58,7 @@ export interface GridCardGraphProps { customErrorMessage?: string; start?: number; end?: number; + analyticsEvent?: string; } export interface GetGraphVisibilityStateOnLegendClickProps { diff --git a/frontend/src/pages/Celery/CeleryTask/CeleryTask.tsx b/frontend/src/pages/Celery/CeleryTask/CeleryTask.tsx index 6602b11eb7..7f2d8f5085 100644 --- a/frontend/src/pages/Celery/CeleryTask/CeleryTask.tsx +++ b/frontend/src/pages/Celery/CeleryTask/CeleryTask.tsx @@ -1,15 +1,30 @@ import './CeleryTask.styles.scss'; +import logEvent from 'api/common/logEvent'; import CeleryTaskConfigOptions from 'components/CeleryTask/CeleryTaskConfigOptions/CeleryTaskConfigOptions'; import CeleryTaskDetail, { CaptureDataProps, } from 'components/CeleryTask/CeleryTaskDetail/CeleryTaskDetail'; import CeleryTaskGraphGrid from 'components/CeleryTask/CeleryTaskGraph/CeleryTaskGraphGrid'; +import { QueryParams } from 'constants/query'; import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; -import { useState } from 'react'; +import useUrlQuery from 'hooks/useUrlQuery'; +import { useEffect, useRef, useState } from 'react'; export default function CeleryTask(): JSX.Element { const [task, setTask] = useState(null); + const loggedRef = useRef(false); + + const taskName = useUrlQuery().get(QueryParams.taskName); + + useEffect(() => { + if (taskName && !loggedRef.current) { + logEvent('MQ Celery: Task name filter', { + taskName, + }); + loggedRef.current = true; + } + }, [taskName]); const onTaskClick = (captureData: CaptureDataProps): void => { setTask(captureData);