diff --git a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/utils.tsx b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/utils.tsx index 68c696d586..0ed5aa5a0b 100644 --- a/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/utils.tsx +++ b/frontend/src/container/InfraMonitoringK8s/EntityDetailsUtils/utils.tsx @@ -23,6 +23,7 @@ export const QUERY_KEYS = { K8S_CLUSTER_NAME: 'k8s.cluster.name', K8S_NODE_NAME: 'k8s.node.name', K8S_DEPLOYMENT_NAME: 'k8s.deployment.name', + K8S_STATEFUL_SET_NAME: 'k8s.statefulset.name', }; /** diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/NoEventsContainer.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/NoEventsContainer.tsx deleted file mode 100644 index 794423f42f..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/NoEventsContainer.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Color } from '@signozhq/design-tokens'; -import { Typography } from 'antd'; -import { Ghost } from 'lucide-react'; - -const { Text } = Typography; - -export default function NoEventsContainer(): React.ReactElement { - return ( -
- - No events found for this - statefulSet in the selected time range. - -
- ); -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.styles.scss b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.styles.scss deleted file mode 100644 index b5f192206c..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.styles.scss +++ /dev/null @@ -1,289 +0,0 @@ -.statefulSet-events-container { - margin-top: 1rem; - - .filter-section { - flex: 1; - - .ant-select-selector { - border-radius: 2px; - border: 1px solid var(--bg-slate-400) !important; - background-color: var(--bg-ink-300) !important; - - input { - font-size: 12px; - } - - .ant-tag .ant-typography { - font-size: 12px; - } - } - } - - .statefulSet-events-header { - display: flex; - justify-content: space-between; - gap: 8px; - - padding: 12px; - border-radius: 3px; - border: 1px solid var(--bg-slate-500); - } - - .statefulSet-events { - margin-top: 1rem; - - .virtuoso-list { - overflow-y: hidden !important; - - &::-webkit-scrollbar { - width: 0.3rem; - height: 0.3rem; - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - background: var(--bg-slate-300); - } - - &::-webkit-scrollbar-thumb:hover { - background: var(--bg-slate-200); - } - - .ant-row { - width: fit-content; - } - } - - .skeleton-container { - height: 100%; - padding: 16px; - } - } - - .ant-table { - .ant-table-thead > tr > th { - padding: 12px; - font-weight: 500; - font-size: 12px; - line-height: 18px; - - background: rgb(18, 19, 23); - border-bottom: none; - - color: var(--Vanilla-400, #c0c1c3); - font-family: Inter; - font-size: 11px; - font-style: normal; - font-weight: 600; - line-height: 18px; /* 163.636% */ - letter-spacing: 0.44px; - text-transform: uppercase; - - &::before { - background-color: transparent; - } - } - - .ant-table-thead > tr > th:has(.statefulSetname-column-header) { - background: var(--bg-ink-400); - } - - .ant-table-cell { - padding: 12px; - font-size: 13px; - line-height: 20px; - color: var(--bg-vanilla-100); - background: rgb(18, 19, 23); - border-bottom: none; - } - - .ant-table-cell:has(.statefulSetname-column-value) { - background: var(--bg-ink-400); - } - - .statefulSetname-column-value { - color: var(--bg-vanilla-100); - font-family: 'Geist Mono'; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.07px; - } - - .status-cell { - .active-tag { - color: var(--bg-forest-500); - padding: 4px 8px; - border-radius: 4px; - font-size: 12px; - font-weight: 500; - } - } - - .progress-container { - .ant-progress-bg { - height: 8px !important; - border-radius: 4px; - } - } - - .ant-table-tbody > tr:hover > td { - background: rgba(255, 255, 255, 0.04); - } - - .ant-table-cell:first-child { - text-align: justify; - } - - .ant-table-cell:nth-child(2) { - padding-left: 16px; - padding-right: 16px; - } - - .ant-table-cell:nth-child(n + 3) { - padding-right: 24px; - } - .column-header-right { - text-align: right; - } - .ant-table-tbody > tr > td { - border-bottom: none; - } - - .ant-table-thead - > tr - > th:not(:last-child):not(.ant-table-selection-column):not(.ant-table-row-expand-icon-cell):not([colspan])::before { - background-color: transparent; - } - - .ant-empty-normal { - visibility: hidden; - } - } - - .ant-pagination { - position: fixed; - bottom: 0; - width: calc(100% - 64px); - background: rgb(18, 19, 23); - padding: 16px; - margin: 0; - - // this is to offset intercom icon till we improve the design - padding-right: 72px; - - .ant-pagination-item { - border-radius: 4px; - - &-active { - background: var(--bg-robin-500); - border-color: var(--bg-robin-500); - - a { - color: var(--bg-ink-500) !important; - } - } - } - } -} - -.statefulSet-events-list-container { - flex: 1; - height: calc(100vh - 272px) !important; - display: flex; - height: 100%; - - .raw-log-content { - width: 100%; - text-wrap: inherit; - word-wrap: break-word; - } -} - -.statefulSet-events-list-card { - width: 100%; - margin-top: 12px; - - .ant-table-wrapper { - height: 100%; - overflow-y: auto; - - &::-webkit-scrollbar { - width: 0.3rem; - height: 0.3rem; - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - background: var(--bg-slate-300); - } - - &::-webkit-scrollbar-thumb:hover { - background: var(--bg-slate-200); - } - - .ant-row { - width: fit-content; - } - } - - .ant-card-body { - padding: 0; - - height: 100%; - width: 100%; - } -} - -.logs-loading-skeleton { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 8px; - padding: 8px 0; - - .ant-skeleton-input-sm { - height: 18px; - } -} - -.no-logs-found { - height: 50vh; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - - padding: 24px; - box-sizing: border-box; - - .ant-typography { - display: flex; - align-items: center; - gap: 16px; - } -} - -.lightMode { - .filter-section { - border-top: 1px solid var(--bg-vanilla-300); - border-bottom: 1px solid var(--bg-vanilla-300); - - .ant-select-selector { - border-color: var(--bg-vanilla-300) !important; - background-color: var(--bg-vanilla-100) !important; - color: var(--bg-ink-200); - } - } -} - -.periscope-btn-icon { - cursor: pointer; -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.tsx deleted file mode 100644 index 900ca5b20e..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/StatefulSetEvents.tsx +++ /dev/null @@ -1,366 +0,0 @@ -/* eslint-disable no-nested-ternary */ -import './StatefulSetEvents.styles.scss'; - -import { Color } from '@signozhq/design-tokens'; -import { Button, Table, TableColumnsType } from 'antd'; -import { DEFAULT_ENTITY_VERSION } from 'constants/app'; -import { EventContents } from 'container/InfraMonitoringK8s/commonUtils'; -import LoadingContainer from 'container/InfraMonitoringK8s/LoadingContainer'; -import LogsError from 'container/LogsError/LogsError'; -import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; -import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; -import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; -import { - CustomTimeType, - Time, -} from 'container/TopNav/DateTimeSelectionV2/config'; -import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; -import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults'; -import { isArray } from 'lodash-es'; -import { ChevronDown, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'; -import { useEffect, useMemo, useState } from 'react'; -import { useQuery } from 'react-query'; -import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { DataSource } from 'types/common/queryBuilder'; -import { v4 } from 'uuid'; - -import { getStatefulSetsEventsQueryPayload } from './constants'; -import NoEventsContainer from './NoEventsContainer'; - -interface EventDataType { - key: string; - timestamp: string; - body: string; - id: string; - attributes_bool?: Record; - attributes_number?: Record; - attributes_string?: Record; - resources_string?: Record; - scope_name?: string; - scope_string?: Record; - scope_version?: string; - severity_number?: number; - severity_text?: string; - span_id?: string; - trace_flags?: number; - trace_id?: string; - severity?: string; -} - -interface IStatefulSetEventsProps { - timeRange: { - startTime: number; - endTime: number; - }; - handleChangeEventFilters: (filters: IBuilderQuery['filters']) => void; - filters: IBuilderQuery['filters']; - isModalTimeSelection: boolean; - handleTimeChange: ( - interval: Time | CustomTimeType, - dateTimeRange?: [number, number], - ) => void; - selectedInterval: Time; -} - -const EventsPageSize = 10; - -export default function Events({ - timeRange, - handleChangeEventFilters, - filters, - isModalTimeSelection, - handleTimeChange, - selectedInterval, -}: IStatefulSetEventsProps): JSX.Element { - const { currentQuery } = useQueryBuilder(); - - const [formattedStatefulSetEvents, setFormattedStatefulSetEvents] = useState< - EventDataType[] - >([]); - - const [hasReachedEndOfEvents, setHasReachedEndOfEvents] = useState(false); - - const [page, setPage] = useState(1); - - const updatedCurrentQuery = useMemo( - () => ({ - ...currentQuery, - builder: { - ...currentQuery.builder, - queryData: [ - { - ...currentQuery.builder.queryData[0], - dataSource: DataSource.LOGS, - aggregateOperator: 'noop', - aggregateAttribute: { - ...currentQuery.builder.queryData[0].aggregateAttribute, - }, - filters: { - items: [], - op: 'AND', - }, - }, - ], - }, - }), - [currentQuery], - ); - - const query = updatedCurrentQuery?.builder?.queryData[0] || null; - - const queryPayload = useMemo(() => { - const basePayload = getStatefulSetsEventsQueryPayload( - timeRange.startTime, - timeRange.endTime, - filters, - ); - - basePayload.query.builder.queryData[0].pageSize = 10; - basePayload.query.builder.queryData[0].orderBy = [ - { columnName: 'timestamp', order: ORDERBY_FILTERS.DESC }, - ]; - - return basePayload; - }, [timeRange.startTime, timeRange.endTime, filters]); - - const { data: eventsData, isLoading, isFetching, isError } = useQuery({ - queryKey: [ - 'statefulSetEvents', - timeRange.startTime, - timeRange.endTime, - filters, - ], - queryFn: () => GetMetricQueryRange(queryPayload, DEFAULT_ENTITY_VERSION), - enabled: !!queryPayload, - }); - - const columns: TableColumnsType = [ - { title: 'Severity', dataIndex: 'severity', key: 'severity', width: 100 }, - { - title: 'Timestamp', - dataIndex: 'timestamp', - width: 200, - ellipsis: true, - key: 'timestamp', - }, - { title: 'Body', dataIndex: 'body', key: 'body' }, - ]; - - useEffect(() => { - if (eventsData?.payload?.data?.newResult?.data?.result) { - const responsePayload = - eventsData?.payload.data.newResult.data.result[0].list || []; - - const formattedData = responsePayload?.map( - (event): EventDataType => ({ - timestamp: event.timestamp, - severity: event.data.severity_text, - body: event.data.body, - id: event.data.id, - key: event.data.id, - resources_string: event.data.resources_string, - attributes_string: event.data.attributes_string, - }), - ); - - setFormattedStatefulSetEvents(formattedData); - - if ( - !responsePayload || - (responsePayload && - isArray(responsePayload) && - responsePayload.length < EventsPageSize) - ) { - setHasReachedEndOfEvents(true); - } else { - setHasReachedEndOfEvents(false); - } - } - }, [eventsData]); - - const handleExpandRow = (record: EventDataType): JSX.Element => ( - - ); - - const handlePrev = (): void => { - if (!formattedStatefulSetEvents.length) return; - - setPage(page - 1); - - const firstEvent = formattedStatefulSetEvents[0]; - - const newItems = [ - ...filters.items.filter((item) => item.key?.key !== 'id'), - { - id: v4(), - key: { - key: 'id', - type: '', - dataType: DataTypes.String, - isColumn: true, - }, - op: '>', - value: firstEvent.id, - }, - ]; - - const newFilters = { - op: 'AND', - items: newItems, - } as IBuilderQuery['filters']; - - handleChangeEventFilters(newFilters); - }; - - const handleNext = (): void => { - if (!formattedStatefulSetEvents.length) return; - - setPage(page + 1); - const lastEvent = - formattedStatefulSetEvents[formattedStatefulSetEvents.length - 1]; - - const newItems = [ - ...filters.items.filter((item) => item.key?.key !== 'id'), - { - id: v4(), - key: { - key: 'id', - type: '', - dataType: DataTypes.String, - isColumn: true, - }, - op: '<', - value: lastEvent.id, - }, - ]; - - const newFilters = { - op: 'AND', - items: newItems, - } as IBuilderQuery['filters']; - - handleChangeEventFilters(newFilters); - }; - - const handleExpandRowIcon = ({ - expanded, - onExpand, - record, - }: { - expanded: boolean; - onExpand: ( - record: EventDataType, - e: React.MouseEvent, - ) => void; - record: EventDataType; - }): JSX.Element => - expanded ? ( - - onExpand( - record, - (e as unknown) as React.MouseEvent, - ) - } - /> - ) : ( - - onExpand( - record, - (e as unknown) as React.MouseEvent, - ) - } - /> - ); - - return ( -
-
-
- {query && ( - - )} -
-
- -
-
- - {isLoading && } - - {!isLoading && !isError && formattedStatefulSetEvents.length === 0 && ( - - )} - - {isError && !isLoading && } - - {!isLoading && !isError && formattedStatefulSetEvents.length > 0 && ( -
-
- - loading={isLoading && page > 1} - columns={columns} - expandable={{ - expandedRowRender: handleExpandRow, - rowExpandable: (record): boolean => record.body !== 'Not Expandable', - expandIcon: handleExpandRowIcon, - }} - dataSource={formattedStatefulSetEvents} - pagination={false} - rowKey={(record): string => record.id} - /> -
-
- )} - - {!isError && formattedStatefulSetEvents.length > 0 && ( -
- - - - - {(isFetching || isLoading) && ( - - )} -
- )} -
- ); -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/constants.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/constants.ts deleted file mode 100644 index 235922fe8a..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/constants.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { PANEL_TYPES } from 'constants/queryBuilder'; -import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { EQueryType } from 'types/common/dashboard'; -import { DataSource } from 'types/common/queryBuilder'; -import { v4 as uuidv4 } from 'uuid'; - -export const getStatefulSetsEventsQueryPayload = ( - start: number, - end: number, - filters: IBuilderQuery['filters'], -): GetQueryResultsProps => ({ - graphType: PANEL_TYPES.LIST, - selectedTime: 'GLOBAL_TIME', - query: { - clickhouse_sql: [], - promql: [], - builder: { - queryData: [ - { - dataSource: DataSource.LOGS, - queryName: 'A', - aggregateOperator: 'noop', - aggregateAttribute: { - id: '------false', - dataType: DataTypes.String, - key: '', - isColumn: false, - type: '', - isJSON: false, - }, - timeAggregation: 'rate', - spaceAggregation: 'sum', - functions: [], - filters, - expression: 'A', - disabled: false, - stepInterval: 60, - having: [], - limit: null, - orderBy: [ - { - columnName: 'timestamp', - order: 'desc', - }, - ], - groupBy: [], - legend: '', - reduceTo: 'avg', - offset: 0, - pageSize: 100, - }, - ], - queryFormulas: [], - }, - id: uuidv4(), - queryType: EQueryType.QUERY_BUILDER, - }, - params: { - lastLogLineTimestamp: null, - }, - start, - end, -}); diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/index.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/index.ts deleted file mode 100644 index d0666a9de7..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Events/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import StatefulSetEvents from './StatefulSetEvents'; - -export default StatefulSetEvents; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/NoLogsContainer.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/NoLogsContainer.tsx deleted file mode 100644 index f1b9ad5510..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/NoLogsContainer.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Color } from '@signozhq/design-tokens'; -import { Typography } from 'antd'; -import { Ghost } from 'lucide-react'; - -const { Text } = Typography; - -export default function NoLogsContainer(): React.ReactElement { - return ( -
- - No logs found for this - statefulSet in the selected time range. - -
- ); -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.styles.scss b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.styles.scss deleted file mode 100644 index 7fb7f18991..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.styles.scss +++ /dev/null @@ -1,133 +0,0 @@ -.statefulSet-logs-container { - margin-top: 1rem; - - .filter-section { - flex: 1; - - .ant-select-selector { - border-radius: 2px; - border: 1px solid var(--bg-slate-400) !important; - background-color: var(--bg-ink-300) !important; - - input { - font-size: 12px; - } - - .ant-tag .ant-typography { - font-size: 12px; - } - } - } - - .statefulSet-logs-header { - display: flex; - justify-content: space-between; - gap: 8px; - - padding: 12px; - border-radius: 3px; - border: 1px solid var(--bg-slate-500); - } - - .statefulSet-logs { - margin-top: 1rem; - - .virtuoso-list { - overflow-y: hidden !important; - - &::-webkit-scrollbar { - width: 0.3rem; - height: 0.3rem; - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - background: var(--bg-slate-300); - } - - &::-webkit-scrollbar-thumb:hover { - background: var(--bg-slate-200); - } - - .ant-row { - width: fit-content; - } - } - - .skeleton-container { - height: 100%; - padding: 16px; - } - } -} - -.statefulSet-logs-list-container { - flex: 1; - height: calc(100vh - 272px) !important; - display: flex; - height: 100%; - - .raw-log-content { - width: 100%; - text-wrap: inherit; - word-wrap: break-word; - } -} - -.statefulSet-logs-list-card { - width: 100%; - margin-top: 12px; - - .ant-card-body { - padding: 0; - - height: 100%; - width: 100%; - } -} - -.logs-loading-skeleton { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 8px; - padding: 8px 0; - - .ant-skeleton-input-sm { - height: 18px; - } -} - -.no-logs-found { - height: 50vh; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - - padding: 24px; - box-sizing: border-box; - - .ant-typography { - display: flex; - align-items: center; - gap: 16px; - } -} - -.lightMode { - .filter-section { - border-top: 1px solid var(--bg-vanilla-300); - border-bottom: 1px solid var(--bg-vanilla-300); - - .ant-select-selector { - border-color: var(--bg-vanilla-300) !important; - background-color: var(--bg-vanilla-100) !important; - color: var(--bg-ink-200); - } - } -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.tsx deleted file mode 100644 index a7724a89f3..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogs.tsx +++ /dev/null @@ -1,221 +0,0 @@ -/* eslint-disable no-nested-ternary */ -import './StatefulSetLogs.styles.scss'; - -import { Card } from 'antd'; -import RawLogView from 'components/Logs/RawLogView'; -import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar'; -import { DEFAULT_ENTITY_VERSION } from 'constants/app'; -import LogsError from 'container/LogsError/LogsError'; -import { LogsLoading } from 'container/LogsLoading/LogsLoading'; -import { FontSize } from 'container/OptionsMenu/types'; -import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config'; -import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults'; -import { isEqual } from 'lodash-es'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { useQuery } from 'react-query'; -import { Virtuoso } from 'react-virtuoso'; -import { ILog } from 'types/api/logs/log'; -import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { - IBuilderQuery, - TagFilterItem, -} from 'types/api/queryBuilder/queryBuilderData'; -import { v4 } from 'uuid'; - -import { QUERY_KEYS } from '../constants'; -import { getStatefulSetLogsQueryPayload } from './constants'; -import NoLogsContainer from './NoLogsContainer'; - -interface Props { - timeRange: { - startTime: number; - endTime: number; - }; - handleChangeLogFilters: (filters: IBuilderQuery['filters']) => void; - filters: IBuilderQuery['filters']; -} - -function PodLogs({ - timeRange, - handleChangeLogFilters, - filters, -}: Props): JSX.Element { - const [logs, setLogs] = useState([]); - const [hasReachedEndOfLogs, setHasReachedEndOfLogs] = useState(false); - const [restFilters, setRestFilters] = useState([]); - const [resetLogsList, setResetLogsList] = useState(false); - - useEffect(() => { - const newRestFilters = filters.items.filter( - (item) => - item.key?.key !== 'id' && - ![QUERY_KEYS.K8S_STATEFUL_SET_NAME, QUERY_KEYS.K8S_NAMESPACE_NAME].includes( - item.key?.key ?? '', - ), - ); - - const areFiltersSame = isEqual(restFilters, newRestFilters); - - if (!areFiltersSame) { - setResetLogsList(true); - } - - setRestFilters(newRestFilters); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [filters]); - - const queryPayload = useMemo(() => { - const basePayload = getStatefulSetLogsQueryPayload( - timeRange.startTime, - timeRange.endTime, - filters, - ); - - basePayload.query.builder.queryData[0].pageSize = 100; - basePayload.query.builder.queryData[0].orderBy = [ - { columnName: 'timestamp', order: ORDERBY_FILTERS.DESC }, - ]; - - return basePayload; - }, [timeRange.startTime, timeRange.endTime, filters]); - - const [isPaginating, setIsPaginating] = useState(false); - - const { data, isLoading, isFetching, isError } = useQuery({ - queryKey: [ - 'statefulSetLogs', - timeRange.startTime, - timeRange.endTime, - filters, - ], - queryFn: () => GetMetricQueryRange(queryPayload, DEFAULT_ENTITY_VERSION), - enabled: !!queryPayload, - keepPreviousData: isPaginating, - }); - - useEffect(() => { - if (data?.payload?.data?.newResult?.data?.result) { - const currentData = data.payload.data.newResult.data.result; - - if (resetLogsList) { - const currentLogs: ILog[] = - currentData[0].list?.map((item) => ({ - ...item.data, - timestamp: item.timestamp, - })) || []; - - setLogs(currentLogs); - - setResetLogsList(false); - } - - if (currentData.length > 0 && currentData[0].list) { - const currentLogs: ILog[] = - currentData[0].list.map((item) => ({ - ...item.data, - timestamp: item.timestamp, - })) || []; - - setLogs((prev) => [...prev, ...currentLogs]); - } else { - setHasReachedEndOfLogs(true); - } - } - }, [data, restFilters, isPaginating, resetLogsList]); - - const getItemContent = useCallback( - (_: number, logToRender: ILog): JSX.Element => ( - - ), - [], - ); - - const loadMoreLogs = useCallback(() => { - if (!logs.length) return; - - setIsPaginating(true); - const lastLog = logs[logs.length - 1]; - - const newItems = [ - ...filters.items.filter((item) => item.key?.key !== 'id'), - { - id: v4(), - key: { - key: 'id', - type: '', - dataType: DataTypes.String, - isColumn: true, - }, - op: '<', - value: lastLog.id, - }, - ]; - - const newFilters = { - op: 'AND', - items: newItems, - } as IBuilderQuery['filters']; - - handleChangeLogFilters(newFilters); - }, [logs, filters, handleChangeLogFilters]); - - useEffect(() => { - setIsPaginating(false); - }, [data]); - - const renderFooter = useCallback( - (): JSX.Element | null => ( - // eslint-disable-next-line react/jsx-no-useless-fragment - <> - {isFetching ? ( -
Loading more logs ...
- ) : hasReachedEndOfLogs ? ( -
*** End ***
- ) : null} - - ), - [isFetching, hasReachedEndOfLogs], - ); - - const renderContent = useMemo( - () => ( - - - - - - ), - [logs, loadMoreLogs, getItemContent, renderFooter], - ); - - return ( -
- {isLoading && } - {!isLoading && !isError && logs.length === 0 && } - {isError && !isLoading && } - {!isLoading && !isError && logs.length > 0 && ( -
{renderContent}
- )} -
- ); -} - -export default PodLogs; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogsDetailedView.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogsDetailedView.tsx deleted file mode 100644 index 1110e1cca2..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/StatefulSetLogsDetailedView.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import './StatefulSetLogs.styles.scss'; - -import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; -import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; -import { - CustomTimeType, - Time, -} from 'container/TopNav/DateTimeSelectionV2/config'; -import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; -import { useMemo } from 'react'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { DataSource } from 'types/common/queryBuilder'; - -import StatefulSetLogs from './StatefulSetLogs'; - -interface Props { - timeRange: { - startTime: number; - endTime: number; - }; - isModalTimeSelection: boolean; - handleTimeChange: ( - interval: Time | CustomTimeType, - dateTimeRange?: [number, number], - ) => void; - handleChangeLogFilters: (value: IBuilderQuery['filters']) => void; - logFilters: IBuilderQuery['filters']; - selectedInterval: Time; -} - -function StatefulSetLogsDetailedView({ - timeRange, - isModalTimeSelection, - handleTimeChange, - handleChangeLogFilters, - logFilters, - selectedInterval, -}: Props): JSX.Element { - const { currentQuery } = useQueryBuilder(); - const updatedCurrentQuery = useMemo( - () => ({ - ...currentQuery, - builder: { - ...currentQuery.builder, - queryData: [ - { - ...currentQuery.builder.queryData[0], - dataSource: DataSource.LOGS, - aggregateOperator: 'noop', - aggregateAttribute: { - ...currentQuery.builder.queryData[0].aggregateAttribute, - }, - filters: { - items: [], - op: 'AND', - }, - }, - ], - }, - }), - [currentQuery], - ); - - const query = updatedCurrentQuery?.builder?.queryData[0] || null; - - return ( -
-
-
- {query && ( - - )} -
-
- -
-
- -
- ); -} - -export default StatefulSetLogsDetailedView; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/constants.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/constants.ts deleted file mode 100644 index abdc5a5421..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/constants.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { PANEL_TYPES } from 'constants/queryBuilder'; -import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { EQueryType } from 'types/common/dashboard'; -import { DataSource } from 'types/common/queryBuilder'; -import { v4 as uuidv4 } from 'uuid'; - -export const getStatefulSetLogsQueryPayload = ( - start: number, - end: number, - filters: IBuilderQuery['filters'], -): GetQueryResultsProps => ({ - graphType: PANEL_TYPES.LIST, - selectedTime: 'GLOBAL_TIME', - query: { - clickhouse_sql: [], - promql: [], - builder: { - queryData: [ - { - dataSource: DataSource.LOGS, - queryName: 'A', - aggregateOperator: 'noop', - aggregateAttribute: { - id: '------false', - dataType: DataTypes.String, - key: '', - isColumn: false, - type: '', - isJSON: false, - }, - timeAggregation: 'rate', - spaceAggregation: 'sum', - functions: [], - filters, - expression: 'A', - disabled: false, - stepInterval: 60, - having: [], - limit: null, - orderBy: [ - { - columnName: 'timestamp', - order: 'desc', - }, - ], - groupBy: [], - legend: '', - reduceTo: 'avg', - offset: 0, - pageSize: 100, - }, - ], - queryFormulas: [], - }, - id: uuidv4(), - queryType: EQueryType.QUERY_BUILDER, - }, - params: { - lastLogLineTimestamp: null, - }, - start, - end, -}); diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/index.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/index.ts deleted file mode 100644 index cc3262fba9..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Logs/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import StatefulSetLogs from './StatefulSetLogsDetailedView'; - -export default StatefulSetLogs; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.styles.scss b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.styles.scss deleted file mode 100644 index 86d1ff1ca6..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.styles.scss +++ /dev/null @@ -1,45 +0,0 @@ -.empty-container { - display: flex; - justify-content: center; - align-items: center; - height: 100%; -} - -.statefulSet-metrics-container { - margin-top: 1rem; -} - -.metrics-header { - display: flex; - justify-content: flex-end; - margin-top: 1rem; - - gap: 8px; - padding: 12px; - border-radius: 3px; - border: 1px solid var(--bg-slate-500); -} - -.statefulSet-metrics-card { - margin: 8px 0 1rem 0; - height: 300px; - padding: 10px; - - border: 1px solid var(--bg-slate-500); - - .ant-card-body { - padding: 0; - } - - .chart-container { - width: 100%; - height: 100%; - } - - .no-data-container { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.tsx deleted file mode 100644 index e9a17d07dc..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/StatefulSetMetrics.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import './StatefulSetMetrics.styles.scss'; - -import { Card, Col, Row, Skeleton, Typography } from 'antd'; -import { K8sStatefulSetsData } from 'api/infraMonitoring/getsK8sStatefulSetsList'; -import cx from 'classnames'; -import Uplot from 'components/Uplot'; -import { ENTITY_VERSION_V4 } from 'constants/app'; -import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; -import { - CustomTimeType, - Time, -} from 'container/TopNav/DateTimeSelectionV2/config'; -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 { getStatefulSetQueryPayload, statefulSetWidgetInfo } from './constants'; - -interface StatefulSetMetricsProps { - timeRange: { - startTime: number; - endTime: number; - }; - isModalTimeSelection: boolean; - handleTimeChange: ( - interval: Time | CustomTimeType, - dateTimeRange?: [number, number], - ) => void; - selectedInterval: Time; - statefulSet: K8sStatefulSetsData; -} - -function StatefulSetMetrics({ - selectedInterval, - statefulSet, - timeRange, - handleTimeChange, - isModalTimeSelection, -}: StatefulSetMetricsProps): JSX.Element { - const queryPayloads = useMemo( - () => - getStatefulSetQueryPayload( - statefulSet, - timeRange.startTime, - timeRange.endTime, - ), - [statefulSet, timeRange.startTime, timeRange.endTime], - ); - - const queries = useQueries( - queryPayloads.map((payload) => ({ - queryKey: [ - 'statefulSet-metrics', - payload, - ENTITY_VERSION_V4, - 'STATEFUL_SET', - ], - queryFn: (): Promise> => - GetMetricQueryRange(payload, ENTITY_VERSION_V4), - enabled: !!payload, - })), - ); - - const isDarkMode = useIsDarkMode(); - const graphRef = useRef(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: statefulSetWidgetInfo[idx].yAxisUnit, - softMax: null, - softMin: null, - minTimeScale: timeRange.startTime, - maxTimeScale: timeRange.endTime, - }), - ), - [queries, isDarkMode, dimensions, timeRange.startTime, timeRange.endTime], - ); - - const renderCardContent = ( - query: UseQueryResult, unknown>, - idx: number, - ): JSX.Element => { - if (query.isLoading) { - return ; - } - - if (query.error) { - const errorMessage = - (query.error as Error)?.message || 'Something went wrong'; - return
{errorMessage}
; - } - return ( -
- -
- ); - }; - - return ( - <> -
-
- -
-
- - {queries.map((query, idx) => ( - - {statefulSetWidgetInfo[idx].title} - - {renderCardContent(query, idx)} - - - ))} - - - ); -} - -export default StatefulSetMetrics; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/constants.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/constants.ts deleted file mode 100644 index a49bcb2481..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/constants.ts +++ /dev/null @@ -1,790 +0,0 @@ -/* eslint-disable sonarjs/no-duplicate-string */ -import { K8sStatefulSetsData } from 'api/infraMonitoring/getsK8sStatefulSetsList'; -import { PANEL_TYPES } from 'constants/queryBuilder'; -import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { EQueryType } from 'types/common/dashboard'; -import { DataSource } from 'types/common/queryBuilder'; -import { v4 } from 'uuid'; - -export const statefulSetWidgetInfo = [ - { - title: 'CPU usage, request, limits', - yAxisUnit: '', - }, - { - title: 'CPU request, limit util (%)', - yAxisUnit: 'percentunit', - }, - { - title: 'Memory usage, request, limits', - yAxisUnit: 'bytes', - }, - { - title: 'Memory request, limit util (%)', - yAxisUnit: 'percentunit', - }, - { - title: 'Network IO', - yAxisUnit: 'binBps', - }, - { - title: 'Network errors count', - yAxisUnit: '', - }, -]; - -export const getStatefulSetQueryPayload = ( - statefulSet: K8sStatefulSetsData, - start: number, - end: number, -): GetQueryResultsProps[] => [ - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_cpu_utilization--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_cpu_utilization', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: '8627bd22', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'usage', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'avg', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_container_cpu_request--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_container_cpu_request', - type: 'Gauge', - }, - aggregateOperator: 'latest', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'B', - filters: { - items: [ - { - id: '82f07131', - key: { - dataType: DataTypes.String, - id: 'k8s_pod_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_pod_name', - type: 'tag', - }, - op: 'contains', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'requests', - limit: null, - orderBy: [], - queryName: 'B', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'latest', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_container_cpu_limit--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_container_cpu_limit', - type: 'Gauge', - }, - aggregateOperator: 'latest', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'C', - filters: { - items: [ - { - id: '9c669f4f', - key: { - dataType: DataTypes.String, - id: 'k8s_pod_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_pod_name', - type: 'tag', - }, - op: 'contains', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'limits', - limit: null, - orderBy: [], - queryName: 'C', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'latest', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_cpu_request_utilization--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_cpu_request_utilization', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: '3c835082', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'Reqs util %', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'avg', - stepInterval: 60, - timeAggregation: 'avg', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_cpu_limit_utilization--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_cpu_limit_utilization', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'B', - filters: { - items: [ - { - id: 'c0a5e5b1', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'Limit util %', - limit: null, - orderBy: [], - queryName: 'B', - reduceTo: 'avg', - spaceAggregation: 'avg', - stepInterval: 60, - timeAggregation: 'avg', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_memory_usage--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_memory_usage', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: 'f8ae7d0f', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'usage', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'avg', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_container_memory_request--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_container_memory_request', - type: 'Gauge', - }, - aggregateOperator: 'latest', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'B', - filters: { - items: [ - { - id: '66fbdd5e', - key: { - dataType: DataTypes.String, - id: 'k8s_pod_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_pod_name', - type: 'tag', - }, - op: 'contains', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'requests', - limit: null, - orderBy: [], - queryName: 'B', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'latest', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_container_memory_limit--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_container_memory_limit', - type: 'Gauge', - }, - aggregateOperator: 'latest', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'C', - filters: { - items: [ - { - id: '1a408383', - key: { - dataType: DataTypes.String, - id: 'k8s_pod_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_pod_name', - type: 'tag', - }, - op: 'contains', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'limits', - limit: null, - orderBy: [], - queryName: 'C', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'latest', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_memory_request_utilization--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_memory_request_utilization', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: 'acdccfa2', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'Reqs util %', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'avg', - stepInterval: 60, - timeAggregation: 'avg', - }, - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_memory_limit_utilization--float64--Gauge--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_memory_limit_utilization', - type: 'Gauge', - }, - aggregateOperator: 'avg', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'B', - filters: { - items: [ - { - id: 'cc9a85d3', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [], - having: [], - legend: 'Limits util %', - limit: null, - orderBy: [], - queryName: 'B', - reduceTo: 'avg', - spaceAggregation: 'avg', - stepInterval: 60, - timeAggregation: 'avg', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_network_io--float64--Sum--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_network_io', - type: 'Sum', - }, - aggregateOperator: 'rate', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: '2ea33f83', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [ - { - dataType: DataTypes.String, - id: 'direction--string--tag--false', - isColumn: false, - isJSON: false, - key: 'direction', - type: 'tag', - }, - { - dataType: DataTypes.String, - id: 'interface--string--tag--false', - isColumn: false, - isJSON: false, - key: 'interface', - type: 'tag', - }, - ], - having: [], - legend: '{{direction}} :: {{interface}}', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'rate', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, - { - selectedTime: 'GLOBAL_TIME', - graphType: PANEL_TYPES.TIME_SERIES, - query: { - builder: { - queryData: [ - { - aggregateAttribute: { - dataType: DataTypes.Float64, - id: 'k8s_pod_network_errors--float64--Sum--true', - isColumn: true, - isJSON: false, - key: 'k8s_pod_network_errors', - type: 'Sum', - }, - aggregateOperator: 'increase', - dataSource: DataSource.METRICS, - disabled: false, - expression: 'A', - filters: { - items: [ - { - id: '7e25d4fb', - key: { - dataType: DataTypes.String, - id: 'k8s_statefulset_name--string--tag--false', - isColumn: false, - isJSON: false, - key: 'k8s_statefulset_name', - type: 'tag', - }, - op: '=', - value: statefulSet.meta.k8s_statefulset_name, - }, - ], - op: 'AND', - }, - functions: [], - groupBy: [ - { - dataType: DataTypes.String, - id: 'direction--string--tag--false', - isColumn: false, - isJSON: false, - key: 'direction', - type: 'tag', - }, - { - dataType: DataTypes.String, - id: 'interface--string--tag--false', - isColumn: false, - isJSON: false, - key: 'interface', - type: 'tag', - }, - ], - having: [], - legend: '{{direction}} :: {{interface}}', - limit: null, - orderBy: [], - queryName: 'A', - reduceTo: 'avg', - spaceAggregation: 'sum', - stepInterval: 60, - timeAggregation: 'increase', - }, - ], - queryFormulas: [], - }, - clickhouse_sql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - id: v4(), - promql: [ - { - disabled: false, - legend: '', - name: 'A', - query: '', - }, - ], - queryType: EQueryType.QUERY_BUILDER, - }, - variables: {}, - formatForWeb: false, - start, - end, - }, -]; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/index.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/index.ts deleted file mode 100644 index 4d59fff39b..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Metrics/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import StatefulSetMetrics from './StatefulSetMetrics'; - -export default StatefulSetMetrics; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx index 7e6a7acc42..f2d51e892a 100644 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx +++ b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/StatefulSetDetails.tsx @@ -12,6 +12,12 @@ import { initialQueryState, } from 'constants/queryBuilder'; import ROUTES from 'constants/routes'; +import { K8sCategory } from 'container/InfraMonitoringK8s/constants'; +import EntityEvents from 'container/InfraMonitoringK8s/EntityDetailsUtils/EntityEvents'; +import EntityLogs from 'container/InfraMonitoringK8s/EntityDetailsUtils/EntityLogs'; +import EntityMetrics from 'container/InfraMonitoringK8s/EntityDetailsUtils/EntityMetrics'; +import EntityTraces from 'container/InfraMonitoringK8s/EntityDetailsUtils/EntityTraces'; +import { QUERY_KEYS } from 'container/InfraMonitoringK8s/EntityDetailsUtils/utils'; import { CustomTimeType, Time, @@ -42,12 +48,11 @@ import { import { GlobalReducer } from 'types/reducer/globalTime'; import { v4 as uuidv4 } from 'uuid'; -import { QUERY_KEYS } from './constants'; -import StatefulSetEvents from './Events'; -import StatefulSetLogs from './Logs'; -import StatefulSetMetrics from './Metrics'; +import { + getStatefulSetMetricsQueryPayload, + statefulSetWidgetInfo, +} from './constants'; import { StatefulSetDetailsProps } from './StatefulSetDetails.interfaces'; -import StatefulSetTraces from './Traces'; function StatefulSetDetails({ statefulSet, @@ -92,7 +97,7 @@ function StatefulSetDetails({ type: 'resource', isColumn: false, isJSON: false, - id: 'k8s_statefulSet_name--string--resource--false', + id: 'k8s_statefulset_name--string--resource--false', }, op: '=', value: statefulSet?.meta.k8s_statefulset_name || '', @@ -105,7 +110,7 @@ function StatefulSetDetails({ type: 'resource', isColumn: false, isJSON: false, - id: 'k8s_statefulSet_name--string--resource--false', + id: 'k8s_namespace_name--string--resource--false', }, op: '=', value: statefulSet?.meta.k8s_namespace_name || '', @@ -523,42 +528,55 @@ function StatefulSetDetails({ )} {selectedView === VIEW_TYPES.METRICS && ( - )} {selectedView === VIEW_TYPES.LOGS && ( - )} {selectedView === VIEW_TYPES.TRACES && ( - )} {selectedView === VIEW_TYPES.EVENTS && ( - )} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.styles.scss b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.styles.scss deleted file mode 100644 index 36d5ec7bf1..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.styles.scss +++ /dev/null @@ -1,193 +0,0 @@ -.statefulSet-metric-traces { - margin-top: 1rem; - - .statefulSet-metric-traces-header { - display: flex; - justify-content: space-between; - margin-bottom: 1rem; - - gap: 8px; - padding: 12px; - border-radius: 3px; - border: 1px solid var(--bg-slate-500); - - .filter-section { - flex: 1; - - .ant-select-selector { - border-radius: 2px; - border: 1px solid var(--bg-slate-400) !important; - background-color: var(--bg-ink-300) !important; - - input { - font-size: 12px; - } - - .ant-tag .ant-typography { - font-size: 12px; - } - } - } - } - - .statefulSet-metric-traces-table { - .ant-table-content { - overflow: hidden !important; - } - - .ant-table { - border-radius: 3px; - border: 1px solid var(--bg-slate-500); - - .ant-table-thead > tr > th { - padding: 12px; - font-weight: 500; - font-size: 12px; - line-height: 18px; - - background: rgba(171, 189, 255, 0.01); - border-bottom: none; - - color: var(--Vanilla-400, #c0c1c3); - font-family: Inter; - font-size: 11px; - font-style: normal; - font-weight: 600; - line-height: 18px; /* 163.636% */ - letter-spacing: 0.44px; - text-transform: uppercase; - - &::before { - background-color: transparent; - } - } - - .ant-table-thead > tr > th:has(.hostname-column-header) { - background: var(--bg-ink-400); - } - - .ant-table-cell { - padding: 12px; - font-size: 13px; - line-height: 20px; - color: var(--bg-vanilla-100); - background: rgba(171, 189, 255, 0.01); - } - - .ant-table-cell:has(.hostname-column-value) { - background: var(--bg-ink-400); - } - - .hostname-column-value { - color: var(--bg-vanilla-100); - font-family: 'Geist Mono'; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.07px; - } - - .status-cell { - .active-tag { - color: var(--bg-forest-500); - padding: 4px 8px; - border-radius: 4px; - font-size: 12px; - font-weight: 500; - } - } - - .progress-container { - .ant-progress-bg { - height: 8px !important; - border-radius: 4px; - } - } - - .ant-table-tbody > tr:hover > td { - background: rgba(255, 255, 255, 0.04); - } - - .ant-table-cell:first-child { - text-align: justify; - } - - .ant-table-cell:nth-child(2) { - padding-left: 16px; - padding-right: 16px; - } - - .ant-table-cell:nth-child(n + 3) { - padding-right: 24px; - } - .column-header-right { - text-align: right; - } - .ant-table-tbody > tr > td { - border-bottom: none; - } - - .ant-table-thead - > tr - > th:not(:last-child):not(.ant-table-selection-column):not(.ant-table-row-expand-icon-cell):not([colspan])::before { - background-color: transparent; - } - - .ant-empty-normal { - visibility: hidden; - } - } - - .ant-table-container::after { - content: none; - } - } -} - -.lightMode { - .host-metric-traces-header { - .filter-section { - border-top: 1px solid var(--bg-vanilla-300); - border-bottom: 1px solid var(--bg-vanilla-300); - - .ant-select-selector { - border-color: var(--bg-vanilla-300) !important; - background-color: var(--bg-vanilla-100) !important; - color: var(--bg-ink-200); - } - } - } - - .host-metric-traces-table { - .ant-table { - border-radius: 3px; - border: 1px solid var(--bg-vanilla-300); - - .ant-table-thead > tr > th { - background: var(--bg-vanilla-100); - color: var(--text-ink-300); - } - - .ant-table-thead > tr > th:has(.hostname-column-header) { - background: var(--bg-vanilla-100); - } - - .ant-table-cell { - background: var(--bg-vanilla-100); - color: var(--bg-ink-500); - } - - .ant-table-cell:has(.hostname-column-value) { - background: var(--bg-vanilla-100); - } - - .hostname-column-value { - color: var(--bg-ink-300); - } - - .ant-table-tbody > tr:hover > td { - background: rgba(0, 0, 0, 0.04); - } - } - } -} diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.tsx b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.tsx deleted file mode 100644 index 3d047e060e..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/StatefulSetTraces.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import './StatefulSetTraces.styles.scss'; - -import { getListColumns } from 'components/HostMetricsDetail/HostMetricTraces/utils'; -import { ResizeTable } from 'components/ResizeTable'; -import { DEFAULT_ENTITY_VERSION } from 'constants/app'; -import { QueryParams } from 'constants/query'; -import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch'; -import NoLogs from 'container/NoLogs/NoLogs'; -import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch'; -import { ErrorText } from 'container/TimeSeriesView/styles'; -import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2'; -import { - CustomTimeType, - Time, -} from 'container/TopNav/DateTimeSelectionV2/config'; -import TraceExplorerControls from 'container/TracesExplorer/Controls'; -import { PER_PAGE_OPTIONS } from 'container/TracesExplorer/ListView/configs'; -import { TracesLoading } from 'container/TracesExplorer/TraceLoading/TraceLoading'; -import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; -import { Pagination } from 'hooks/queryPagination'; -import useUrlQueryData from 'hooks/useUrlQueryData'; -import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults'; -import { useEffect, useMemo, useState } from 'react'; -import { useQuery } from 'react-query'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { DataSource } from 'types/common/queryBuilder'; - -import { getStatefulSetTracesQueryPayload, selectedColumns } from './constants'; - -interface Props { - timeRange: { - startTime: number; - endTime: number; - }; - isModalTimeSelection: boolean; - handleTimeChange: ( - interval: Time | CustomTimeType, - dateTimeRange?: [number, number], - ) => void; - handleChangeTracesFilters: (value: IBuilderQuery['filters']) => void; - tracesFilters: IBuilderQuery['filters']; - selectedInterval: Time; -} - -function StatefulSetTraces({ - timeRange, - isModalTimeSelection, - handleTimeChange, - handleChangeTracesFilters, - tracesFilters, - selectedInterval, -}: Props): JSX.Element { - const [traces, setTraces] = useState([]); - const [offset] = useState(0); - - const { currentQuery } = useQueryBuilder(); - const updatedCurrentQuery = useMemo( - () => ({ - ...currentQuery, - builder: { - ...currentQuery.builder, - queryData: [ - { - ...currentQuery.builder.queryData[0], - dataSource: DataSource.TRACES, - aggregateOperator: 'noop', - aggregateAttribute: { - ...currentQuery.builder.queryData[0].aggregateAttribute, - }, - filters: { - items: [], - op: 'AND', - }, - }, - ], - }, - }), - [currentQuery], - ); - - const query = updatedCurrentQuery?.builder?.queryData[0] || null; - - const { queryData: paginationQueryData } = useUrlQueryData( - QueryParams.pagination, - ); - - const queryPayload = useMemo( - () => - getStatefulSetTracesQueryPayload( - timeRange.startTime, - timeRange.endTime, - paginationQueryData?.offset || offset, - tracesFilters, - ), - [ - timeRange.startTime, - timeRange.endTime, - offset, - tracesFilters, - paginationQueryData, - ], - ); - - const { data, isLoading, isFetching, isError } = useQuery({ - queryKey: [ - 'hostMetricTraces', - timeRange.startTime, - timeRange.endTime, - offset, - tracesFilters, - DEFAULT_ENTITY_VERSION, - paginationQueryData, - ], - queryFn: () => GetMetricQueryRange(queryPayload, DEFAULT_ENTITY_VERSION), - enabled: !!queryPayload, - }); - - const traceListColumns = getListColumns(selectedColumns); - - useEffect(() => { - if (data?.payload?.data?.newResult?.data?.result) { - const currentData = data.payload.data.newResult.data.result; - if (currentData.length > 0 && currentData[0].list) { - if (offset === 0) { - setTraces(currentData[0].list ?? []); - } else { - setTraces((prev) => [...prev, ...(currentData[0].list ?? [])]); - } - } - } - }, [data, offset]); - - const isDataEmpty = - !isLoading && !isFetching && !isError && traces.length === 0; - const hasAdditionalFilters = tracesFilters.items.length > 1; - - const totalCount = - data?.payload?.data?.newResult?.data?.result?.[0]?.list?.length || 0; - - return ( -
-
-
- {query && ( - - )} -
-
- -
-
- - {isError && {data?.error || 'Something went wrong'}} - - {isLoading && traces.length === 0 && } - - {isDataEmpty && !hasAdditionalFilters && ( - - )} - - {isDataEmpty && hasAdditionalFilters && ( - - )} - - {!isError && traces.length > 0 && ( -
- - -
- )} -
- ); -} - -export default StatefulSetTraces; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/constants.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/constants.ts deleted file mode 100644 index dc37e29183..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/constants.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { PANEL_TYPES } from 'constants/queryBuilder'; -import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; -import { - BaseAutocompleteData, - DataTypes, -} from 'types/api/queryBuilder/queryAutocompleteResponse'; -import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData'; -import { EQueryType } from 'types/common/dashboard'; -import { DataSource } from 'types/common/queryBuilder'; -import { nanoToMilli } from 'utils/timeUtils'; - -export const columns = [ - { - dataIndex: 'timestamp', - key: 'timestamp', - title: 'Timestamp', - width: 200, - render: (timestamp: string): string => new Date(timestamp).toLocaleString(), - }, - { - title: 'Service Name', - dataIndex: ['data', 'serviceName'], - key: 'serviceName-string-tag', - width: 150, - }, - { - title: 'Name', - dataIndex: ['data', 'name'], - key: 'name-string-tag', - width: 145, - }, - { - title: 'Duration', - dataIndex: ['data', 'durationNano'], - key: 'durationNano-float64-tag', - width: 145, - render: (duration: number): string => `${nanoToMilli(duration)}ms`, - }, - { - title: 'HTTP Method', - dataIndex: ['data', 'httpMethod'], - key: 'httpMethod-string-tag', - width: 145, - }, - { - title: 'Status Code', - dataIndex: ['data', 'responseStatusCode'], - key: 'responseStatusCode-string-tag', - width: 145, - }, -]; - -export const selectedColumns: BaseAutocompleteData[] = [ - { - key: 'timestamp', - dataType: DataTypes.String, - type: 'tag', - isColumn: true, - }, - { - key: 'serviceName', - dataType: DataTypes.String, - type: 'tag', - isColumn: true, - }, - { - key: 'name', - dataType: DataTypes.String, - type: 'tag', - isColumn: true, - }, - { - key: 'durationNano', - dataType: DataTypes.Float64, - type: 'tag', - isColumn: true, - }, - { - key: 'httpMethod', - dataType: DataTypes.String, - type: 'tag', - isColumn: true, - }, - { - key: 'responseStatusCode', - dataType: DataTypes.String, - type: 'tag', - isColumn: true, - }, -]; - -export const getStatefulSetTracesQueryPayload = ( - start: number, - end: number, - offset = 0, - filters: IBuilderQuery['filters'], -): GetQueryResultsProps => ({ - query: { - promql: [], - clickhouse_sql: [], - builder: { - queryData: [ - { - dataSource: DataSource.TRACES, - queryName: 'A', - aggregateOperator: 'noop', - aggregateAttribute: { - id: '------false', - dataType: DataTypes.EMPTY, - key: '', - isColumn: false, - type: '', - isJSON: false, - }, - timeAggregation: 'rate', - spaceAggregation: 'sum', - functions: [], - filters, - expression: 'A', - disabled: false, - stepInterval: 60, - having: [], - limit: null, - orderBy: [ - { - columnName: 'timestamp', - order: 'desc', - }, - ], - groupBy: [], - legend: '', - reduceTo: 'avg', - }, - ], - queryFormulas: [], - }, - id: '572f1d91-6ac0-46c0-b726-c21488b34434', - queryType: EQueryType.QUERY_BUILDER, - }, - graphType: PANEL_TYPES.LIST, - selectedTime: 'GLOBAL_TIME', - start, - end, - params: { - dataSource: DataSource.TRACES, - }, - tableParams: { - pagination: { - limit: 10, - offset, - }, - selectColumns: [ - { - key: 'serviceName', - dataType: 'string', - type: 'tag', - isColumn: true, - isJSON: false, - id: 'serviceName--string--tag--true', - isIndexed: false, - }, - { - key: 'name', - dataType: 'string', - type: 'tag', - isColumn: true, - isJSON: false, - id: 'name--string--tag--true', - isIndexed: false, - }, - { - key: 'durationNano', - dataType: 'float64', - type: 'tag', - isColumn: true, - isJSON: false, - id: 'durationNano--float64--tag--true', - isIndexed: false, - }, - { - key: 'httpMethod', - dataType: 'string', - type: 'tag', - isColumn: true, - isJSON: false, - id: 'httpMethod--string--tag--true', - isIndexed: false, - }, - { - key: 'responseStatusCode', - dataType: 'string', - type: 'tag', - isColumn: true, - isJSON: false, - id: 'responseStatusCode--string--tag--true', - isIndexed: false, - }, - ], - }, -}); diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/index.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/index.ts deleted file mode 100644 index 20f4089099..0000000000 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/Traces/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import StatefulSetTraces from './StatefulSetTraces'; - -export default StatefulSetTraces; diff --git a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/constants.ts b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/constants.ts index 6ba84daf06..245195aa00 100644 --- a/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/constants.ts +++ b/frontend/src/container/InfraMonitoringK8s/StatefulSets/StatefulSetDetails/constants.ts @@ -1,6 +1,790 @@ -export const QUERY_KEYS = { - K8S_OBJECT_KIND: 'k8s.object.kind', - K8S_OBJECT_NAME: 'k8s.object.name', - K8S_STATEFUL_SET_NAME: 'k8s.statefulset.name', - K8S_NAMESPACE_NAME: 'k8s.namespace.name', -}; +/* eslint-disable sonarjs/no-duplicate-string */ +import { K8sStatefulSetsData } from 'api/infraMonitoring/getsK8sStatefulSetsList'; +import { PANEL_TYPES } from 'constants/queryBuilder'; +import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; +import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; +import { EQueryType } from 'types/common/dashboard'; +import { DataSource } from 'types/common/queryBuilder'; +import { v4 } from 'uuid'; + +export const statefulSetWidgetInfo = [ + { + title: 'CPU usage, request, limits', + yAxisUnit: '', + }, + { + title: 'CPU request, limit util (%)', + yAxisUnit: 'percentunit', + }, + { + title: 'Memory usage, request, limits', + yAxisUnit: 'bytes', + }, + { + title: 'Memory request, limit util (%)', + yAxisUnit: 'percentunit', + }, + { + title: 'Network IO', + yAxisUnit: 'binBps', + }, + { + title: 'Network errors count', + yAxisUnit: '', + }, +]; + +export const getStatefulSetMetricsQueryPayload = ( + statefulSet: K8sStatefulSetsData, + start: number, + end: number, +): GetQueryResultsProps[] => [ + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_cpu_utilization--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_cpu_utilization', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: '8627bd22', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'usage', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'avg', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_container_cpu_request--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_container_cpu_request', + type: 'Gauge', + }, + aggregateOperator: 'latest', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'B', + filters: { + items: [ + { + id: '82f07131', + key: { + dataType: DataTypes.String, + id: 'k8s_pod_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_pod_name', + type: 'tag', + }, + op: 'contains', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'requests', + limit: null, + orderBy: [], + queryName: 'B', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'latest', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_container_cpu_limit--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_container_cpu_limit', + type: 'Gauge', + }, + aggregateOperator: 'latest', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'C', + filters: { + items: [ + { + id: '9c669f4f', + key: { + dataType: DataTypes.String, + id: 'k8s_pod_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_pod_name', + type: 'tag', + }, + op: 'contains', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'limits', + limit: null, + orderBy: [], + queryName: 'C', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'latest', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_cpu_request_utilization--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_cpu_request_utilization', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: '3c835082', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'Reqs util %', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'avg', + stepInterval: 60, + timeAggregation: 'avg', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_cpu_limit_utilization--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_cpu_limit_utilization', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'B', + filters: { + items: [ + { + id: 'c0a5e5b1', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'Limit util %', + limit: null, + orderBy: [], + queryName: 'B', + reduceTo: 'avg', + spaceAggregation: 'avg', + stepInterval: 60, + timeAggregation: 'avg', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_memory_usage--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_memory_usage', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: 'f8ae7d0f', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'usage', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'avg', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_container_memory_request--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_container_memory_request', + type: 'Gauge', + }, + aggregateOperator: 'latest', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'B', + filters: { + items: [ + { + id: '66fbdd5e', + key: { + dataType: DataTypes.String, + id: 'k8s_pod_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_pod_name', + type: 'tag', + }, + op: 'contains', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'requests', + limit: null, + orderBy: [], + queryName: 'B', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'latest', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_container_memory_limit--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_container_memory_limit', + type: 'Gauge', + }, + aggregateOperator: 'latest', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'C', + filters: { + items: [ + { + id: '1a408383', + key: { + dataType: DataTypes.String, + id: 'k8s_pod_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_pod_name', + type: 'tag', + }, + op: 'contains', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'limits', + limit: null, + orderBy: [], + queryName: 'C', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'latest', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_memory_request_utilization--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_memory_request_utilization', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: 'acdccfa2', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'Reqs util %', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'avg', + stepInterval: 60, + timeAggregation: 'avg', + }, + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_memory_limit_utilization--float64--Gauge--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_memory_limit_utilization', + type: 'Gauge', + }, + aggregateOperator: 'avg', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'B', + filters: { + items: [ + { + id: 'cc9a85d3', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [], + having: [], + legend: 'Limits util %', + limit: null, + orderBy: [], + queryName: 'B', + reduceTo: 'avg', + spaceAggregation: 'avg', + stepInterval: 60, + timeAggregation: 'avg', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_network_io--float64--Sum--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_network_io', + type: 'Sum', + }, + aggregateOperator: 'rate', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: '2ea33f83', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [ + { + dataType: DataTypes.String, + id: 'direction--string--tag--false', + isColumn: false, + isJSON: false, + key: 'direction', + type: 'tag', + }, + { + dataType: DataTypes.String, + id: 'interface--string--tag--false', + isColumn: false, + isJSON: false, + key: 'interface', + type: 'tag', + }, + ], + having: [], + legend: '{{direction}} :: {{interface}}', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'rate', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, + { + selectedTime: 'GLOBAL_TIME', + graphType: PANEL_TYPES.TIME_SERIES, + query: { + builder: { + queryData: [ + { + aggregateAttribute: { + dataType: DataTypes.Float64, + id: 'k8s_pod_network_errors--float64--Sum--true', + isColumn: true, + isJSON: false, + key: 'k8s_pod_network_errors', + type: 'Sum', + }, + aggregateOperator: 'increase', + dataSource: DataSource.METRICS, + disabled: false, + expression: 'A', + filters: { + items: [ + { + id: '7e25d4fb', + key: { + dataType: DataTypes.String, + id: 'k8s_statefulset_name--string--tag--false', + isColumn: false, + isJSON: false, + key: 'k8s_statefulset_name', + type: 'tag', + }, + op: '=', + value: statefulSet.meta.k8s_statefulset_name, + }, + ], + op: 'AND', + }, + functions: [], + groupBy: [ + { + dataType: DataTypes.String, + id: 'direction--string--tag--false', + isColumn: false, + isJSON: false, + key: 'direction', + type: 'tag', + }, + { + dataType: DataTypes.String, + id: 'interface--string--tag--false', + isColumn: false, + isJSON: false, + key: 'interface', + type: 'tag', + }, + ], + having: [], + legend: '{{direction}} :: {{interface}}', + limit: null, + orderBy: [], + queryName: 'A', + reduceTo: 'avg', + spaceAggregation: 'sum', + stepInterval: 60, + timeAggregation: 'increase', + }, + ], + queryFormulas: [], + }, + clickhouse_sql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + id: v4(), + promql: [ + { + disabled: false, + legend: '', + name: 'A', + query: '', + }, + ], + queryType: EQueryType.QUERY_BUILDER, + }, + variables: {}, + formatForWeb: false, + start, + end, + }, +];