mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-11 23:29:01 +08:00
feat: added worker count and other misc changes (#6951)
* feat: added worker count - via autocomplete API * feat: added worker count and code fix * feat: added lightMode styles for all celery feat * feat: changed routes to have redirects, subroute etc * feat: feedback changes * feat: removed console.log
This commit is contained in:
parent
36f91d1993
commit
fb3b70b729
@ -28,7 +28,6 @@ import {
|
||||
LogsExplorer,
|
||||
LogsIndexToFields,
|
||||
LogsSaveViews,
|
||||
MQDetailPage,
|
||||
MySettings,
|
||||
NewDashboardPage,
|
||||
OldLogsExplorer,
|
||||
@ -395,10 +394,10 @@ const routes: AppRoutes[] = [
|
||||
key: 'INTEGRATIONS',
|
||||
},
|
||||
{
|
||||
path: ROUTES.MESSAGING_QUEUES,
|
||||
path: ROUTES.MESSAGING_QUEUES_KAFKA,
|
||||
exact: true,
|
||||
component: MessagingQueues,
|
||||
key: 'MESSAGING_QUEUES',
|
||||
key: 'MESSAGING_QUEUES_KAFKA',
|
||||
isPrivate: true,
|
||||
},
|
||||
{
|
||||
@ -416,10 +415,10 @@ const routes: AppRoutes[] = [
|
||||
isPrivate: true,
|
||||
},
|
||||
{
|
||||
path: ROUTES.MESSAGING_QUEUES_DETAIL,
|
||||
path: ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
||||
exact: true,
|
||||
component: MQDetailPage,
|
||||
key: 'MESSAGING_QUEUES_DETAIL',
|
||||
component: MessagingQueues,
|
||||
key: 'MESSAGING_QUEUES_KAFKA_DETAIL',
|
||||
isPrivate: true,
|
||||
},
|
||||
{
|
||||
@ -461,6 +460,7 @@ export const oldRoutes = [
|
||||
'/logs-save-views',
|
||||
'/traces-save-views',
|
||||
'/settings/access-tokens',
|
||||
'/messaging-queues',
|
||||
];
|
||||
|
||||
export const oldNewRoutesMapping: Record<string, string> = {
|
||||
@ -470,6 +470,7 @@ export const oldNewRoutesMapping: Record<string, string> = {
|
||||
'/logs-save-views': '/logs/saved-views',
|
||||
'/traces-save-views': '/traces/saved-views',
|
||||
'/settings/access-tokens': '/settings/api-keys',
|
||||
'/messaging-queues': '/messaging-queues/overview',
|
||||
};
|
||||
|
||||
export const ROUTES_NOT_TO_BE_OVERRIDEN: string[] = [
|
||||
|
@ -12,93 +12,138 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.celery-overview-table {
|
||||
.ant-table {
|
||||
.ant-table-thead > tr > th {
|
||||
padding: 12px;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
.celery-overview-table-container {
|
||||
width: 100%;
|
||||
|
||||
background: var(--bg-ink-500);
|
||||
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-cell {
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: var(--bg-vanilla-100);
|
||||
background: var(--bg-ink-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;
|
||||
}
|
||||
.column-header-left {
|
||||
text-align: left;
|
||||
}
|
||||
.ant-table-tbody > tr > td {
|
||||
border-bottom: none;
|
||||
}
|
||||
> .ant-input-search {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: var(--bg-ink-500);
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
.celery-overview-table {
|
||||
.ant-table {
|
||||
.ant-table-thead > tr > th {
|
||||
padding: 12px;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
|
||||
// this is to offset intercom icon
|
||||
padding-right: 72px;
|
||||
background: var(--bg-ink-500);
|
||||
border-bottom: none;
|
||||
|
||||
.ant-pagination-item {
|
||||
border-radius: 4px;
|
||||
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;
|
||||
|
||||
&-active {
|
||||
background: var(--bg-robin-500);
|
||||
border-color: var(--bg-robin-500);
|
||||
&::before {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--bg-ink-500) !important;
|
||||
.ant-table-cell {
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: var(--bg-vanilla-100);
|
||||
background: var(--bg-ink-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;
|
||||
}
|
||||
.column-header-left {
|
||||
text-align: left;
|
||||
}
|
||||
.ant-table-tbody > tr > td {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: var(--bg-ink-500);
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
|
||||
// this is to offset intercom icon
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.celery-overview-table-container {
|
||||
.celery-overview-table {
|
||||
.ant-table {
|
||||
.ant-table-thead > tr > th {
|
||||
background: var(--bg-vanilla-100);
|
||||
color: var(--text-ink-300);
|
||||
}
|
||||
|
||||
.ant-table-cell {
|
||||
background: var(--bg-vanilla-100);
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
background: var(--bg-vanilla-100);
|
||||
|
||||
.ant-pagination-item {
|
||||
&-active {
|
||||
background: var(--bg-robin-500);
|
||||
border-color: var(--bg-robin-500);
|
||||
|
||||
a {
|
||||
color: var(--bg-vanilla-100) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,6 +400,15 @@ export default function CeleryOverviewTable({
|
||||
confirm();
|
||||
};
|
||||
|
||||
// Add defaultSorting state
|
||||
const [sortedInfo, setSortedInfo] = useState<{
|
||||
columnKey: string;
|
||||
order: 'ascend' | 'descend';
|
||||
}>({
|
||||
columnKey: 'error_percentage',
|
||||
order: 'descend',
|
||||
});
|
||||
|
||||
const columns = useMemo(
|
||||
() =>
|
||||
getDraggedColumns<RowData>(
|
||||
@ -411,10 +420,15 @@ export default function CeleryOverviewTable({
|
||||
handleSearch,
|
||||
item.key?.toString(),
|
||||
),
|
||||
// Only set defaultSortOrder for error_percentage, but allow sorting for all columns
|
||||
...(item.key === 'error_percentage' && {
|
||||
defaultSortOrder: 'descend',
|
||||
}),
|
||||
sortOrder: sortedInfo.columnKey === item.key ? sortedInfo.order : null,
|
||||
})),
|
||||
draggedColumns,
|
||||
),
|
||||
[tableData, draggedColumns],
|
||||
[tableData, draggedColumns, sortedInfo],
|
||||
);
|
||||
const handleDragColumn = useCallback(
|
||||
(fromIndex: number, toIndex: number) =>
|
||||
@ -459,7 +473,7 @@ export default function CeleryOverviewTable({
|
||||
]);
|
||||
|
||||
return (
|
||||
<div style={{ width: '100%' }}>
|
||||
<div className="celery-overview-table-container">
|
||||
<Input.Search
|
||||
placeholder="Search across all columns"
|
||||
onChange={(e): void => setSearchText(e.target.value)}
|
||||
@ -488,6 +502,12 @@ export default function CeleryOverviewTable({
|
||||
className: 'clickable-row',
|
||||
})}
|
||||
tableLayout="fixed"
|
||||
onChange={(_pagination, _filters, sorter): void => {
|
||||
setSortedInfo({
|
||||
columnKey: (sorter as { columnKey: string }).columnKey,
|
||||
order: (sorter as { order: 'ascend' | 'descend' }).order,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -8,6 +8,11 @@ import { DataSource } from 'types/common/queryBuilder';
|
||||
export interface Filters {
|
||||
searchText: string;
|
||||
attributeKey: string | string[];
|
||||
aggregateOperator?: string;
|
||||
dataSource?: DataSource;
|
||||
aggregateAttribute?: string;
|
||||
filterAttributeKeyDataType?: DataTypes;
|
||||
tagType?: string;
|
||||
}
|
||||
|
||||
export interface GetAllFiltersResponse {
|
||||
@ -16,7 +21,15 @@ export interface GetAllFiltersResponse {
|
||||
}
|
||||
|
||||
export function useGetAllFilters(props: Filters): GetAllFiltersResponse {
|
||||
const { searchText, attributeKey } = props;
|
||||
const {
|
||||
searchText,
|
||||
attributeKey,
|
||||
aggregateOperator,
|
||||
dataSource,
|
||||
aggregateAttribute,
|
||||
filterAttributeKeyDataType,
|
||||
tagType,
|
||||
} = props;
|
||||
|
||||
const { data, isLoading } = useQuery(
|
||||
['attributesValues', attributeKey, searchText],
|
||||
@ -26,13 +39,14 @@ export function useGetAllFilters(props: Filters): GetAllFiltersResponse {
|
||||
const responses = await Promise.all(
|
||||
keys.map((key) =>
|
||||
getAttributesValues({
|
||||
aggregateOperator: 'noop',
|
||||
dataSource: DataSource.TRACES,
|
||||
aggregateAttribute: '',
|
||||
aggregateOperator: aggregateOperator || 'noop',
|
||||
dataSource: dataSource || DataSource.TRACES,
|
||||
aggregateAttribute: aggregateAttribute || '',
|
||||
attributeKey: key,
|
||||
searchText: searchText ?? '',
|
||||
filterAttributeKeyDataType: DataTypes.String,
|
||||
tagType: 'tag',
|
||||
filterAttributeKeyDataType:
|
||||
filterAttributeKeyDataType || DataTypes.String,
|
||||
tagType: tagType || 'tag',
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
@ -72,3 +72,51 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.celery-task-detail-drawer {
|
||||
.ant-drawer-wrapper-body {
|
||||
background: var(--bg-vanilla-100);
|
||||
border: 1px solid var(--bg-vanilla-300);
|
||||
}
|
||||
|
||||
.ant-drawer-body {
|
||||
.ant-card {
|
||||
.ant-card-body {
|
||||
background: var(--bg-vanilla-100);
|
||||
|
||||
.ant-table {
|
||||
background: var(--bg-vanilla-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-drawer-header {
|
||||
border-bottom: 1px solid var(--bg-vanilla-300);
|
||||
.ant-drawer-header-title {
|
||||
button > svg {
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.ant-drawer-title {
|
||||
.title {
|
||||
color: var(--bg-ink-400);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--bg-ink-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-drawer-footer {
|
||||
border-top: 1px solid var(--bg-vanilla-300);
|
||||
|
||||
.footer-text {
|
||||
color: var(--bg-ink-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,12 +24,53 @@
|
||||
|
||||
.widget-graph-container {
|
||||
&.bar {
|
||||
height: calc(100% - 105px);
|
||||
height: calc(100% - 110px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.celery-task-graph-worker-count {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px solid var(--bg-slate-500);
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
rgba(171, 189, 255, 0) 0%,
|
||||
rgba(171, 189, 255, 0) 100%
|
||||
),
|
||||
#0b0c0e;
|
||||
|
||||
.ant-card-body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.worker-count-text-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.celery-task-graph-worker-count-text {
|
||||
font-size: 2.5vw;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.worker-count-header {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: start;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.celery-task-graph-bar,
|
||||
.celery-task-graph-task-latency {
|
||||
height: 380px !important;
|
||||
@ -46,7 +87,7 @@
|
||||
|
||||
.widget-graph-container {
|
||||
&.bar {
|
||||
height: calc(100% - 105px);
|
||||
height: calc(100% - 110px);
|
||||
}
|
||||
|
||||
&.graph {
|
||||
@ -126,3 +167,40 @@
|
||||
background-color: var(--bg-vanilla-100);
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.celery-task-graph-grid-container {
|
||||
.celery-task-graph-grid {
|
||||
.celery-task-graph-worker-count {
|
||||
border: 1px solid var(--bg-vanilla-300);
|
||||
background: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.celery-task-states {
|
||||
border-bottom: 1px solid var(--bg-vanilla-300);
|
||||
|
||||
&__tab {
|
||||
&:not([data-last-tab='true']) {
|
||||
border-right: 1px solid var(--bg-vanilla-300);
|
||||
}
|
||||
|
||||
&--selected {
|
||||
background-color: var(--bg-vanilla-200);
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
&__value {
|
||||
color: var(--bg-slate-100);
|
||||
}
|
||||
|
||||
&__indicator {
|
||||
background-color: var(--bg-ink-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
import './CeleryTaskGraph.style.scss';
|
||||
|
||||
import { Card, Typography } from 'antd';
|
||||
import { useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import { CaptureDataProps } from '../CeleryTaskDetail/CeleryTaskDetail';
|
||||
import { useCeleryFilterOptions } from '../useCeleryFilterOptions';
|
||||
import CeleryTaskBar from './CeleryTaskBar';
|
||||
import CeleryTaskGraph from './CeleryTaskGraph';
|
||||
import {
|
||||
@ -13,7 +17,6 @@ import {
|
||||
celeryErrorByWorkerWidgetData,
|
||||
celeryLatencyByWorkerWidgetData,
|
||||
celeryTasksByWorkerWidgetData,
|
||||
celeryWorkerOnlineWidgetData,
|
||||
} from './CeleryTaskGraphUtils';
|
||||
import CeleryTaskLatencyGraph from './CeleryTaskLatencyGraph';
|
||||
|
||||
@ -28,11 +31,6 @@ export default function CeleryTaskGraphGrid({
|
||||
(state) => state.globalTime,
|
||||
);
|
||||
|
||||
const celeryWorkerOnlineData = useMemo(
|
||||
() => celeryWorkerOnlineWidgetData(minTime, maxTime),
|
||||
[minTime, maxTime],
|
||||
);
|
||||
|
||||
const celeryActiveTasksData = useMemo(
|
||||
() => celeryActiveTasksWidgetData(minTime, maxTime),
|
||||
[minTime, maxTime],
|
||||
@ -65,15 +63,31 @@ export default function CeleryTaskGraphGrid({
|
||||
'Latency by worker',
|
||||
];
|
||||
|
||||
const { options } = useCeleryFilterOptions(
|
||||
'worker',
|
||||
'rate',
|
||||
DataSource.METRICS,
|
||||
'flower_task_runtime_seconds_sum',
|
||||
DataTypes.String,
|
||||
'tag',
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="celery-task-graph-grid-container">
|
||||
<div className="celery-task-graph-grid">
|
||||
<CeleryTaskBar queryEnabled={queryEnabled} onClick={onClick} />
|
||||
<CeleryTaskGraph
|
||||
key={celeryWorkerOnlineData.id}
|
||||
widgetData={celeryWorkerOnlineData}
|
||||
queryEnabled={queryEnabled}
|
||||
/>
|
||||
<Card className="celery-task-graph-worker-count">
|
||||
<div className="worker-count-header">
|
||||
<Typography.Text className="worker-count-header-text">
|
||||
Worker Count
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<div className="worker-count-text-container">
|
||||
<Typography.Text className="celery-task-graph-worker-count-text">
|
||||
{options.filter((option) => option.value).length}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="celery-task-graph-grid">
|
||||
<CeleryTaskLatencyGraph onClick={onClick} queryEnabled={queryEnabled} />
|
||||
|
@ -490,49 +490,6 @@ export const celeryActiveTasksWidgetData = (
|
||||
}),
|
||||
);
|
||||
|
||||
export const celeryWorkerOnlineWidgetData = (
|
||||
startTime: number,
|
||||
endTime: number,
|
||||
): Widgets =>
|
||||
getWidgetQueryBuilder(
|
||||
getWidgetQuery({
|
||||
title: 'Worker Online',
|
||||
description: 'Represents the number of workers online.',
|
||||
panelTypes: PANEL_TYPES.VALUE,
|
||||
queryData: [
|
||||
{
|
||||
aggregateAttribute: {
|
||||
dataType: DataTypes.Float64,
|
||||
id: 'flower_task_runtime_seconds_sum--float64--Sum--true',
|
||||
isColumn: true,
|
||||
isJSON: false,
|
||||
key: 'flower_task_runtime_seconds_sum',
|
||||
type: 'Sum',
|
||||
},
|
||||
aggregateOperator: 'rate',
|
||||
dataSource: DataSource.METRICS,
|
||||
disabled: false,
|
||||
expression: 'A',
|
||||
filters: {
|
||||
items: [],
|
||||
op: 'AND',
|
||||
},
|
||||
functions: [],
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: '',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
reduceTo: 'avg',
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: getStepInterval(startTime, endTime),
|
||||
timeAggregation: 'rate',
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
export const celeryTaskLatencyWidgetData = (
|
||||
type: string,
|
||||
startTime: number,
|
||||
|
@ -1,11 +1,18 @@
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||
import { useState } from 'react';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
import { useGetAllFilters } from './CeleryTaskConfigOptions/useGetCeleryFilters';
|
||||
|
||||
export const useCeleryFilterOptions = (
|
||||
type: string | string[],
|
||||
aggregateOperator?: string,
|
||||
dataSource?: DataSource,
|
||||
aggregateAttribute?: string,
|
||||
filterAttributeKeyDataType?: DataTypes,
|
||||
tagType?: string,
|
||||
): {
|
||||
searchText: string;
|
||||
handleSearch: (value: string) => void;
|
||||
@ -16,6 +23,11 @@ export const useCeleryFilterOptions = (
|
||||
const { isFetching, options } = useGetAllFilters({
|
||||
attributeKey: type,
|
||||
searchText,
|
||||
aggregateOperator,
|
||||
dataSource,
|
||||
aggregateAttribute,
|
||||
filterAttributeKeyDataType,
|
||||
tagType,
|
||||
});
|
||||
const handleDebouncedSearch = useDebouncedFn((searchText): void => {
|
||||
setSearchText(searchText as string);
|
||||
|
@ -59,8 +59,8 @@ const ROUTES = {
|
||||
WORKSPACE_SUSPENDED: '/workspace-suspended',
|
||||
SHORTCUTS: '/shortcuts',
|
||||
INTEGRATIONS: '/integrations',
|
||||
MESSAGING_QUEUES: '/messaging-queues',
|
||||
MESSAGING_QUEUES_DETAIL: '/messaging-queues/detail',
|
||||
MESSAGING_QUEUES_KAFKA: '/messaging-queues/kafka',
|
||||
MESSAGING_QUEUES_KAFKA_DETAIL: '/messaging-queues/kafka/detail',
|
||||
INFRASTRUCTURE_MONITORING_HOSTS: '/infrastructure-monitoring/hosts',
|
||||
INFRASTRUCTURE_MONITORING_KUBERNETES: '/infrastructure-monitoring/kubernetes',
|
||||
MESSAGING_QUEUES_CELERY_TASK: '/messaging-queues/celery-task',
|
||||
|
@ -287,8 +287,8 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
routeKey === 'TRACES_EXPLORER' || routeKey === 'TRACES_SAVE_VIEWS';
|
||||
|
||||
const isMessagingQueues = (): boolean =>
|
||||
routeKey === 'MESSAGING_QUEUES' ||
|
||||
routeKey === 'MESSAGING_QUEUES_DETAIL' ||
|
||||
routeKey === 'MESSAGING_QUEUES_KAFKA' ||
|
||||
routeKey === 'MESSAGING_QUEUES_KAFKA_DETAIL' ||
|
||||
routeKey === 'MESSAGING_QUEUES_CELERY_TASK' ||
|
||||
routeKey === 'MESSAGING_QUEUES_OVERVIEW';
|
||||
|
||||
|
@ -23,21 +23,15 @@ import {
|
||||
TableData,
|
||||
} from './utils';
|
||||
|
||||
export const HoverButtonWrapper = styled.div`
|
||||
const ButtonWrapper = styled.div`
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
`;
|
||||
|
||||
const RelativeWrapper = styled.div`
|
||||
position: relative;
|
||||
|
||||
&:hover ${HoverButtonWrapper} {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
function GridTableComponent({
|
||||
@ -206,12 +200,12 @@ function GridTableComponent({
|
||||
return (
|
||||
<RelativeWrapper>
|
||||
{LineClampedTextComponent}
|
||||
<HoverButtonWrapper className="hover-button">
|
||||
<ButtonWrapper className="hover-button">
|
||||
<button type="button" className="open-traces-button">
|
||||
<Compass size={12} />
|
||||
Open Trace
|
||||
</button>
|
||||
</HoverButtonWrapper>
|
||||
</ButtonWrapper>
|
||||
</RelativeWrapper>
|
||||
);
|
||||
},
|
||||
|
@ -239,7 +239,7 @@ function SideNav(): JSX.Element {
|
||||
);
|
||||
|
||||
registerShortcut(GlobalShortcuts.NavigateToMessagingQueues, () =>
|
||||
onClickHandler(ROUTES.MESSAGING_QUEUES, null),
|
||||
onClickHandler(ROUTES.MESSAGING_QUEUES_OVERVIEW, null),
|
||||
);
|
||||
|
||||
registerShortcut(GlobalShortcuts.NavigateToAlerts, () =>
|
||||
|
@ -49,8 +49,8 @@ export const routeConfig: Record<string, QueryParams[]> = {
|
||||
[ROUTES.TRACE_EXPLORER]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.LOGS_PIPELINES]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.WORKSPACE_LOCKED]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES_DETAIL]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES_KAFKA]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES_CELERY_TASK]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.MESSAGING_QUEUES_OVERVIEW]: [QueryParams.resourceAttributes],
|
||||
[ROUTES.INFRASTRUCTURE_MONITORING_HOSTS]: [QueryParams.resourceAttributes],
|
||||
|
@ -94,7 +94,7 @@ const menuItems: SidebarItem[] = [
|
||||
icon: <LayoutGrid size={16} />,
|
||||
},
|
||||
{
|
||||
key: ROUTES.MESSAGING_QUEUES,
|
||||
key: ROUTES.MESSAGING_QUEUES_OVERVIEW,
|
||||
label: 'Messaging Queues',
|
||||
icon: <ListMinus size={16} />,
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ const breadcrumbNameMap: Record<string, string> = {
|
||||
[ROUTES.SUPPORT]: 'Support',
|
||||
[ROUTES.WORKSPACE_LOCKED]: 'Workspace Locked',
|
||||
[ROUTES.WORKSPACE_SUSPENDED]: 'Workspace Suspended',
|
||||
[ROUTES.MESSAGING_QUEUES]: 'Messaging Queues',
|
||||
[ROUTES.MESSAGING_QUEUES_OVERVIEW]: 'Messaging Queues',
|
||||
};
|
||||
|
||||
function ShowBreadcrumbs(props: RouteComponentProps): JSX.Element {
|
||||
|
@ -212,8 +212,8 @@ export const routesToSkip = [
|
||||
ROUTES.SERVICE_TOP_LEVEL_OPERATIONS,
|
||||
ROUTES.ALERT_HISTORY,
|
||||
ROUTES.ALERT_OVERVIEW,
|
||||
ROUTES.MESSAGING_QUEUES,
|
||||
ROUTES.MESSAGING_QUEUES_DETAIL,
|
||||
ROUTES.MESSAGING_QUEUES_KAFKA,
|
||||
ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
||||
ROUTES.MESSAGING_QUEUES_CELERY_TASK,
|
||||
ROUTES.MESSAGING_QUEUES_OVERVIEW,
|
||||
ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
|
||||
|
@ -1,22 +1,4 @@
|
||||
.celery-overview-container {
|
||||
.celery-overview-breadcrumb {
|
||||
display: flex;
|
||||
padding: 0px 16px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 8px;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: -0.07px;
|
||||
|
||||
border-bottom: 1px solid var(--bg-slate-400);
|
||||
}
|
||||
|
||||
.celery-overview-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -42,3 +24,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.celery-overview-container {
|
||||
.celery-overview-content {
|
||||
.celery-overview-content-header {
|
||||
.celery-overview-content-header-title {
|
||||
color: var(--bg-slate-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,3 +28,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.overview-right-panel-graph-card {
|
||||
border: 1px solid var(--bg-vanilla-300) !important;
|
||||
background: var(--bg-vanilla-100);
|
||||
|
||||
.request-rate-card,
|
||||
.error-rate-card,
|
||||
.avg-latency-card {
|
||||
border-bottom: 0.75px solid var(--bg-vanilla-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ export default function CeleryOverviewDetails({
|
||||
case 'span_name':
|
||||
return getFiltersFromKeyValue('name', value, '');
|
||||
case 'messaging_system':
|
||||
return getFiltersFromKeyValue('messaging.system', value, 'tag');
|
||||
return value === 'celery'
|
||||
? undefined
|
||||
: getFiltersFromKeyValue('messaging.system', value, 'tag');
|
||||
case 'destination':
|
||||
return getFiltersFromKeyValue(
|
||||
details.messaging_system === 'celery'
|
||||
@ -48,12 +50,6 @@ export default function CeleryOverviewDetails({
|
||||
return keyValues.filter((item) => item !== undefined) as TagFilterItem[];
|
||||
}, [details]);
|
||||
|
||||
const groupByFilter = useMemo(
|
||||
() =>
|
||||
getFiltersFromKeyValue('messaging.destination.partition.id', '', 'tag').key,
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
width="60%"
|
||||
@ -92,7 +88,7 @@ export default function CeleryOverviewDetails({
|
||||
>
|
||||
<div className="celery-overview-detail-container">
|
||||
<ValueInfo filters={filters} />
|
||||
<OverviewRightPanelGraph filters={filters} groupByFilter={groupByFilter} />
|
||||
<OverviewRightPanelGraph filters={filters} />
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
|
@ -49,6 +49,8 @@
|
||||
margin-top: 8px;
|
||||
background: #262626;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #404040;
|
||||
@ -61,3 +63,32 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.value-info-card {
|
||||
border: 1px solid var(--bg-vanilla-300) !important;
|
||||
background: var(--bg-vanilla-100);
|
||||
|
||||
.metric-column {
|
||||
.metric-title {
|
||||
color: var(--bg-slate-100);
|
||||
}
|
||||
|
||||
.metric-unit {
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.metric-reference {
|
||||
color: var(--bg-ink-500);
|
||||
}
|
||||
|
||||
.trace-button {
|
||||
background: var(--bg-slate-200);
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-slate-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,4 @@
|
||||
.celery-task-container {
|
||||
.celery-task-breadcrumb {
|
||||
display: flex;
|
||||
padding: 0px 16px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 8px;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: -0.07px;
|
||||
|
||||
border-bottom: 1px solid var(--bg-slate-400);
|
||||
}
|
||||
|
||||
.celery-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -42,3 +24,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lightMode {
|
||||
.celery-task-container {
|
||||
.celery-content {
|
||||
.celery-content-header {
|
||||
.celery-content-header-title {
|
||||
color: var(--bg-slate-200);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import '../MessagingQueues.styles.scss';
|
||||
|
||||
import { Select, Typography } from 'antd';
|
||||
import { Select } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import ROUTES from 'constants/routes';
|
||||
import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { ListMinus } from 'lucide-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
@ -65,20 +64,27 @@ function MQDetailPage(): JSX.Element {
|
||||
selectedView !== MessagingQueuesViewType.dropRate.value &&
|
||||
selectedView !== MessagingQueuesViewType.metricPage.value;
|
||||
|
||||
const handleBackClick = (): void => {
|
||||
history.push(ROUTES.MESSAGING_QUEUES_KAFKA);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="messaging-queue-container">
|
||||
<div className="messaging-breadcrumb">
|
||||
<ListMinus size={16} />
|
||||
<Typography.Text
|
||||
onClick={(): void => history.push(ROUTES.MESSAGING_QUEUES)}
|
||||
className="message-queue-text"
|
||||
>
|
||||
Messaging Queues
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<div className="messaging-header">
|
||||
<div className="header-config">
|
||||
Kafka / views /
|
||||
<div
|
||||
onClick={handleBackClick}
|
||||
className="message-queue-text"
|
||||
onKeyDown={(e): void => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleBackClick();
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
Kafka / views /
|
||||
</div>
|
||||
<Select
|
||||
className="messaging-queue-options"
|
||||
defaultValue={MessagingQueuesViewType.consumerLag.value}
|
||||
|
@ -1,31 +1,6 @@
|
||||
.messaging-queue-container {
|
||||
.messaging-breadcrumb {
|
||||
display: flex;
|
||||
padding: 0px 16px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 8px;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: -0.07px;
|
||||
|
||||
border-bottom: 1px solid var(--bg-slate-400);
|
||||
|
||||
.message-queue-text {
|
||||
cursor: pointer;
|
||||
color: var(--bg-vanilla-400);
|
||||
font-family: Inter;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: -0.07px;
|
||||
}
|
||||
.message-queue-text {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.messaging-header {
|
||||
@ -334,14 +309,6 @@
|
||||
|
||||
.lightMode {
|
||||
.messaging-queue-container {
|
||||
.messaging-breadcrumb {
|
||||
color: var(--bg-ink-400);
|
||||
border-bottom: 1px solid var(--bg-vanilla-300);
|
||||
|
||||
.message-queue-text {
|
||||
color: var(--bg-ink-400);
|
||||
}
|
||||
}
|
||||
.messaging-header {
|
||||
color: var(--bg-ink-400);
|
||||
border-bottom: 1px solid var(--bg-vanilla-300);
|
||||
|
@ -30,7 +30,7 @@ function MessagingQueues(): JSX.Element {
|
||||
});
|
||||
|
||||
history.push(
|
||||
`${ROUTES.MESSAGING_QUEUES_DETAIL}?${QueryParams.mqServiceView}=${callerView}`,
|
||||
`${ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL}?${QueryParams.mqServiceView}=${callerView}`,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -6,10 +6,11 @@ import ROUTES from 'constants/routes';
|
||||
import history from 'lib/history';
|
||||
import { ListMinus, Rows3 } from 'lucide-react';
|
||||
import CeleryOverview from 'pages/Celery/CeleryOverview/CeleryOverview';
|
||||
import { useLocation } from 'react-use';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import CeleryTask from '../Celery/CeleryTask/CeleryTask';
|
||||
import MessagingQueues from './MessagingQueues';
|
||||
import MQDetailPage from './MQDetailPage/MQDetailPage';
|
||||
|
||||
export const Kafka: TabRoutes = {
|
||||
Component: MessagingQueues,
|
||||
@ -18,8 +19,19 @@ export const Kafka: TabRoutes = {
|
||||
<ListMinus size={16} /> Kafka
|
||||
</div>
|
||||
),
|
||||
route: ROUTES.MESSAGING_QUEUES,
|
||||
key: ROUTES.MESSAGING_QUEUES,
|
||||
route: ROUTES.MESSAGING_QUEUES_KAFKA,
|
||||
key: ROUTES.MESSAGING_QUEUES_KAFKA,
|
||||
};
|
||||
|
||||
export const KafkaDetail: TabRoutes = {
|
||||
Component: MQDetailPage,
|
||||
name: (
|
||||
<div className="tab-item">
|
||||
<ListMinus size={16} /> Kafka
|
||||
</div>
|
||||
),
|
||||
route: ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
||||
key: ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL,
|
||||
};
|
||||
|
||||
export const Celery: TabRoutes = {
|
||||
@ -47,7 +59,13 @@ export const Overview: TabRoutes = {
|
||||
export default function MessagingQueuesMainPage(): JSX.Element {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const routes: TabRoutes[] = [Kafka, Celery, Overview];
|
||||
const isKafkaDetail = pathname === ROUTES.MESSAGING_QUEUES_KAFKA_DETAIL;
|
||||
|
||||
const routes: TabRoutes[] = [
|
||||
Overview,
|
||||
isKafkaDetail ? KafkaDetail : Kafka,
|
||||
Celery,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="messaging-queues-module-container">
|
||||
|
@ -52,8 +52,8 @@ export const routePermission: Record<keyof typeof ROUTES, ROLES[]> = {
|
||||
ALL_CHANNELS: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
INGESTION_SETTINGS: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
ALL_DASHBOARD: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
MESSAGING_QUEUES: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
MESSAGING_QUEUES_DETAIL: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
MESSAGING_QUEUES_KAFKA: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
MESSAGING_QUEUES_KAFKA_DETAIL: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
ALL_ERROR: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
APPLICATION: ['ADMIN', 'EDITOR', 'VIEWER'],
|
||||
CHANNELS_EDIT: ['ADMIN'],
|
||||
|
Loading…
x
Reference in New Issue
Block a user