141 lines
3.6 KiB
TypeScript
Raw Normal View History

feat: added new tab for infra metrics in logs detailed page (#5771) * feat: added new tab for infra metrics in logs detailed page * feat: added yaxis unit for the charts * chore: cleanup query_range params * fix: clusterName, podName variables not working * feat: added skeleton for each charts in infra metrics tab * change card height to 300px * fix: updated the test cases * feat: added new sub-tabs node and pod for infra metrics tab * feat: added new components for node and pod metrics * feat: added card titles for host metrics and handled empty state * fix: updated the constant for host name * feat: added vertical dotted line to all panels and updated y axis units for all panels * feat: removed other panel types other than graph from host metrics query payload * fix: updated the query payload for node metrics * feat: moved the label of vertical dotted line to top * feat: added console statement to check query payload * fix: added pod name instead of node name in pod query payload * fix: added key as pod name instead of node name in file system usage * fix: updated query payload for file system usage in pod metrics and removed label from dotted line * fix: updated the y axis units for network io * fix: custom date time issue while plotting the graph * feat: compare end time and current time update the end time accordingly * feat: added the start and end time in query payloads * refactor: removed the comments and unused variables * chore: added a todo to make common component for sub-tabs * fix: addressed review comments --------- Co-authored-by: Ankit Nayan <ankit@signoz.io>
2024-09-20 23:56:34 +05:30
import { Card, Col, Row, Skeleton, Typography } from 'antd';
import cx from 'classnames';
import Uplot from 'components/Uplot';
import { ENTITY_VERSION_V4 } from 'constants/app';
import dayjs from 'dayjs';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useResizeObserver } from 'hooks/useDimensions';
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
import { useMemo, useRef } from 'react';
import { useQueries, UseQueryResult } from 'react-query';
import { SuccessResponse } from 'types/api';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import {
getHostQueryPayload,
getNodeQueryPayload,
hostWidgetInfo,
nodeWidgetInfo,
} from './constants';
function NodeMetrics({
nodeName,
clusterName,
hostName,
logLineTimestamp,
}: {
nodeName: string;
clusterName: string;
hostName: string;
logLineTimestamp: string;
}): JSX.Element {
const { start, end, verticalLineTimestamp } = useMemo(() => {
const logTimestamp = dayjs(logLineTimestamp);
const now = dayjs();
const startTime = logTimestamp.subtract(3, 'hour');
const endTime = logTimestamp.add(3, 'hour').isBefore(now)
? logTimestamp.add(3, 'hour')
: now;
return {
start: startTime.unix(),
end: endTime.unix(),
verticalLineTimestamp: logTimestamp.unix(),
};
}, [logLineTimestamp]);
const queryPayloads = useMemo(() => {
if (nodeName) {
return getNodeQueryPayload(clusterName, nodeName, start, end);
}
return getHostQueryPayload(hostName, start, end);
}, [nodeName, hostName, clusterName, start, end]);
const widgetInfo = nodeName ? nodeWidgetInfo : hostWidgetInfo;
const queries = useQueries(
queryPayloads.map((payload) => ({
queryKey: ['metrics', payload, ENTITY_VERSION_V4, 'NODE'],
queryFn: (): Promise<SuccessResponse<MetricRangePayloadProps>> =>
GetMetricQueryRange(payload, ENTITY_VERSION_V4),
enabled: !!payload,
})),
);
const isDarkMode = useIsDarkMode();
const graphRef = useRef<HTMLDivElement>(null);
const dimensions = useResizeObserver(graphRef);
const chartData = useMemo(
() => queries.map(({ data }) => getUPlotChartData(data?.payload)),
[queries],
);
const options = useMemo(
() =>
queries.map(({ data }, idx) =>
getUPlotChartOptions({
apiResponse: data?.payload,
isDarkMode,
dimensions,
yAxisUnit: widgetInfo[idx].yAxisUnit,
softMax: null,
softMin: null,
minTimeScale: start,
maxTimeScale: end,
verticalLineTimestamp,
}),
),
[
queries,
isDarkMode,
dimensions,
widgetInfo,
start,
verticalLineTimestamp,
end,
],
);
const renderCardContent = (
query: UseQueryResult<SuccessResponse<MetricRangePayloadProps>, unknown>,
idx: number,
): JSX.Element => {
if (query.isLoading) {
return <Skeleton />;
}
if (query.error) {
const errorMessage =
(query.error as Error)?.message || 'Something went wrong';
return <div>{errorMessage}</div>;
}
return (
<div
className={cx('chart-container', {
'no-data-container':
!query.isLoading && !query?.data?.payload?.data?.result?.length,
})}
>
<Uplot options={options[idx]} data={chartData[idx]} />
</div>
);
};
return (
<Row gutter={24}>
{queries.map((query, idx) => (
<Col span={12} key={widgetInfo[idx].title}>
<Typography.Text>{widgetInfo[idx].title}</Typography.Text>
<Card bordered className="infra-metrics-card" ref={graphRef}>
{renderCardContent(query, idx)}
</Card>
</Col>
))}
</Row>
);
}
export default NodeMetrics;