Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added the host list view and filters #6210

Merged
merged 26 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f8eeec6
feat: added the host list view and filters
rahulkeswani101 Oct 17, 2024
ae014d1
feat: removed group by filter and added autocomplete for where clause
rahulkeswani101 Oct 19, 2024
08512b9
feat: updated the table view and added the pagination
rahulkeswani101 Oct 19, 2024
3d57dde
feat: pass updated filters to api to get filtered data in the list
rahulkeswani101 Oct 21, 2024
689440b
feat: added global time range and order by for cpu,memory,iowait,load
rahulkeswani101 Oct 21, 2024
403fe9d
feat: added order by and color codes for cpu and memory usage progres…
rahulkeswani101 Oct 21, 2024
6648e84
refactor: removed inline styles
rahulkeswani101 Oct 22, 2024
4581cba
Host lists improvement (#6366)
rahulkeswani101 Nov 6, 2024
1af121d
feat: added the host detail view (#6267)
rahulkeswani101 Nov 6, 2024
a30bb58
Host containers (#6297)
rahulkeswani101 Nov 6, 2024
5aa2f03
Show host metrics panels in metrics tab. (#6306)
rahulkeswani101 Nov 6, 2024
fc43930
Metrics time selection (#6360)
rahulkeswani101 Nov 6, 2024
8ace84c
feat: added logs and traces tab in host metrics detail view (#6359)
rahulkeswani101 Nov 15, 2024
318f0ae
refactor: removed unused code and added comments
rahulkeswani101 Nov 18, 2024
e94de69
refactor: added new code for host metric attribute keys
rahulkeswani101 Nov 19, 2024
dc3c19a
feat: reset query data once we are on infra monitoring page
rahulkeswani101 Nov 19, 2024
1dcb0ad
chore: remove optional parameter from get attributes and groupby inte…
YounixM Nov 20, 2024
bdea4d9
feat: update ui as per the designs
YounixM Nov 20, 2024
67e1a2e
fix: logs list, time select and other ui issues
YounixM Nov 20, 2024
480d142
feat: update title for infra monitoring page
YounixM Nov 20, 2024
c70d7ba
feat: update copies
YounixM Nov 21, 2024
894e3bc
feat: update styles for light mode
YounixM Nov 21, 2024
58a46c9
fix: reset page size on filter, open explorers in new tab, enable hor…
YounixM Nov 21, 2024
fce529c
feat: traces tab updates
YounixM Nov 21, 2024
9ef3d05
feat: move infra monitoring behind ff
YounixM Nov 21, 2024
a69f9c9
fix: remove sorting from host listing page
YounixM Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions frontend/src/AppRoutes/pageComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,10 @@ export const MQDetailPage = Loadable(
/* webpackChunkName: "MQDetailPage" */ 'pages/MessagingQueues/MQDetailPage'
),
);

export const InfrastructureMonitoring = Loadable(
() =>
import(
/* webpackChunkName: "InfrastructureMonitoring" */ 'pages/InfrastructureMonitoring'
),
);
8 changes: 8 additions & 0 deletions frontend/src/AppRoutes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
EditAlertChannelsAlerts,
EditRulesPage,
ErrorDetails,
InfrastructureMonitoring,
IngestionSettings,
InstalledIntegrations,
LicensePage,
Expand Down Expand Up @@ -383,6 +384,13 @@ const routes: AppRoutes[] = [
key: 'MESSAGING_QUEUES_DETAIL',
isPrivate: true,
},
{
path: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
exact: true,
component: InfrastructureMonitoring,
key: 'INFRASTRUCTURE_MONITORING_HOSTS',
isPrivate: true,
},
];

export const SUPPORT_ROUTE: AppRoutes = {
Expand Down
71 changes: 71 additions & 0 deletions frontend/src/api/infraMonitoring/getHostLists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { ApiBaseInstance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';

export interface HostListPayload {
filters: TagFilter;
groupBy: BaseAutocompleteData[];
offset?: number;
limit?: number;
}

export interface TimeSeriesValue {
timestamp: number;
value: string;
}

export interface TimeSeries {
labels: Record<string, string>;
labelsArray: Array<Record<string, string>>;
values: TimeSeriesValue[];
}

export interface HostData {
hostName: string;
active: boolean;
os: string;
cpu: number;
cpuTimeSeries: TimeSeries;
memory: number;
memoryTimeSeries: TimeSeries;
wait: number;
waitTimeSeries: TimeSeries;
load15: number;
load15TimeSeries: TimeSeries;
}

export interface HostListResponse {
status: string;
data: {
type: string;
records: HostData[];
groups: null;
total: number;
};
}

export const getHostLists = async (
props: HostListPayload,
signal?: AbortSignal,
headers?: Record<string, string>,
): Promise<SuccessResponse<HostListResponse> | ErrorResponse> => {
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try catch block doesn't propagate the errors to the consuming component and we have to extract the success / error data from the successResponse.

const response = await ApiBaseInstance.post('/hosts/list', props, {
signal,
headers,
});

return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data,
params: props,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
38 changes: 38 additions & 0 deletions frontend/src/api/infraMonitoring/getInfraAttributeValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ApiBaseInstance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
IAttributeValuesResponse,
IGetAttributeValuesPayload,
} from 'types/api/queryBuilder/getAttributesValues';

export const getInfraAttributesValues = async ({
dataSource,
attributeKey,
filterAttributeKeyDataType,
tagType,
searchText,
}: IGetAttributeValuesPayload): Promise<
SuccessResponse<IAttributeValuesResponse> | ErrorResponse
> => {
try {
const response = await ApiBaseInstance.get(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above.

`/hosts/attribute_values?${createQueryParams({
dataSource,
attributeKey,
searchText,
})}&filterAttributeKeyDataType=${filterAttributeKeyDataType}&tagType=${tagType}`,
);

return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
23 changes: 14 additions & 9 deletions frontend/src/api/queryBuilder/getAttributeKeys.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiV3Instance } from 'api';
import { ApiBaseInstance, ApiV3Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError, AxiosResponse } from 'axios';
import { baseAutoCompleteIdKeysOrder } from 'constants/queryBuilder';
Expand All @@ -18,20 +18,25 @@ export const getAggregateKeys = async ({
dataSource,
aggregateAttribute,
tagType,
isInfraMonitoring,
}: IGetAttributeKeysPayload): Promise<
SuccessResponse<IQueryAutocompleteResponse> | ErrorResponse
> => {
try {
const endpoint = isInfraMonitoring
? `/hosts/attribute_keys?dataSource=metrics&searchText=${searchText || ''}`
: `/autocomplete/attribute_keys?${createQueryParams({
aggregateOperator,
searchText,
rahulkeswani101 marked this conversation as resolved.
Show resolved Hide resolved
dataSource,
aggregateAttribute,
})}&tagType=${tagType}`;

const apiInstance = isInfraMonitoring ? ApiBaseInstance : ApiV3Instance;

const response: AxiosResponse<{
data: IQueryAutocompleteResponse;
}> = await ApiV3Instance.get(
`/autocomplete/attribute_keys?${createQueryParams({
aggregateOperator,
searchText,
dataSource,
aggregateAttribute,
})}&tagType=${tagType}`,
);
}> = await apiInstance.get(endpoint);

const payload: BaseAutocompleteData[] =
response.data.data.attributeKeys?.map(({ id: _, ...item }) => ({
Expand Down
1 change: 1 addition & 0 deletions frontend/src/constants/reactQueryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export const REACT_QUERY_KEY = {
GET_ALL_ALLERTS: 'GET_ALL_ALLERTS',
REMOVE_ALERT_RULE: 'REMOVE_ALERT_RULE',
DUPLICATE_ALERT_RULE: 'DUPLICATE_ALERT_RULE',
GET_HOST_LIST: 'GET_HOST_LIST',
};
1 change: 1 addition & 0 deletions frontend/src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const ROUTES = {
INTEGRATIONS: '/integrations',
MESSAGING_QUEUES: '/messaging-queues',
MESSAGING_QUEUES_DETAIL: '/messaging-queues/detail',
INFRASTRUCTURE_MONITORING_HOSTS: '/infrastructure-monitoring/hosts',
} as const;

export default ROUTES;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.loading-host-metrics {
padding: 24px 0;
height: 600px;

display: flex;
justify-content: center;
align-items: center;

.loading-host-metrics-content {
display: flex;
align-items: center;
flex-direction: column;

.loading-gif {
height: 72px;
margin-left: -24px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import './HostMetricsLoading.styles.scss';

import { Typography } from 'antd';
import { useTranslation } from 'react-i18next';
import { DataSource } from 'types/common/queryBuilder';

export function HostMetricsLoading(): JSX.Element {
const { t } = useTranslation('common');
return (
<div className="loading-host-metrics">
<div className="loading-host-metrics-content">
<img
className="loading-gif"
src="/Icons/loading-plane.gif"
alt="wait-icon"
/>

<Typography>
{t('pending_data_placeholder', {
dataSource: `host ${DataSource.METRICS}`,
})}
</Typography>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
export type GroupByFilterProps = {
query: IBuilderQuery;
onChange: (values: BaseAutocompleteData[]) => void;
disabled: boolean;
disabled?: boolean;
isInfraMonitoring?: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const GroupByFilter = memo(function GroupByFilter({
query,
onChange,
disabled,
isInfraMonitoring,
}: GroupByFilterProps): JSX.Element {
const queryClient = useQueryClient();
const [searchText, setSearchText] = useState<string>('');
Expand Down Expand Up @@ -85,6 +86,7 @@ export const GroupByFilter = memo(function GroupByFilter({
setOptionsData(options);
},
},
isInfraMonitoring,
);

const getAttributeKeys = useCallback(async () => {
Expand All @@ -96,6 +98,7 @@ export const GroupByFilter = memo(function GroupByFilter({
dataSource: query.dataSource,
aggregateOperator: query.aggregateOperator,
searchText,
isInfraMonitoring,
}),
);

Expand All @@ -107,6 +110,7 @@ export const GroupByFilter = memo(function GroupByFilter({
query.dataSource,
queryClient,
searchText,
isInfraMonitoring,
]);

const handleSearchKeys = (searchText: string): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function QueryBuilderSearch({
className,
placeholder,
suffixIcon,
isInfraMonitoring,
}: QueryBuilderSearchProps): JSX.Element {
const { pathname } = useLocation();
const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [
Expand All @@ -93,7 +94,12 @@ function QueryBuilderSearch({
searchKey,
key,
exampleQueries,
} = useAutoComplete(query, whereClauseConfig, isLogsExplorerPage);
} = useAutoComplete(
query,
whereClauseConfig,
isLogsExplorerPage,
isInfraMonitoring,
);
const [isOpen, setIsOpen] = useState<boolean>(false);
const [showAllFilters, setShowAllFilters] = useState<boolean>(false);
const [dynamicPlacholder, setDynamicPlaceholder] = useState<string>(
Expand All @@ -105,6 +111,7 @@ function QueryBuilderSearch({
query,
searchKey,
isLogsExplorerPage,
isInfraMonitoring,
);

const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
Expand Down Expand Up @@ -185,8 +192,8 @@ function QueryBuilderSearch({
);

const isMetricsDataSource = useMemo(
() => query.dataSource === DataSource.METRICS,
[query.dataSource],
() => query.dataSource === DataSource.METRICS && !isInfraMonitoring,
[query.dataSource, isInfraMonitoring],
);

const fetchValueDataType = (value: unknown, operator: string): DataTypes => {
Expand Down Expand Up @@ -426,13 +433,15 @@ interface QueryBuilderSearchProps {
className?: string;
placeholder?: string;
suffixIcon?: React.ReactNode;
isInfraMonitoring?: boolean;
}

QueryBuilderSearch.defaultProps = {
whereClauseConfig: undefined,
className: '',
placeholder: PLACEHOLDER,
suffixIcon: undefined,
isInfraMonitoring: false,
};

export interface CustomTagProps {
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/container/SideNav/menuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
LayoutGrid,
ListMinus,
MessageSquare,
PackagePlus,
Receipt,
Route,
ScrollText,
Expand Down Expand Up @@ -118,6 +119,11 @@ const menuItems: SidebarItem[] = [
label: 'Billing',
icon: <Receipt size={16} />,
},
{
key: ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
label: 'Infrastructure Monitoring',
icon: <PackagePlus size={16} />,
},
{
key: ROUTES.SETTINGS,
label: 'Settings',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export const routesToSkip = [
ROUTES.ALERT_OVERVIEW,
ROUTES.MESSAGING_QUEUES,
ROUTES.MESSAGING_QUEUES_DETAIL,
// ROUTES.INFRASTRUCTURE_MONITORING_HOSTS,
];

export const routesToDisable = [ROUTES.LOGS_EXPLORER, ROUTES.LIVE_LOGS];
Expand Down
Loading
Loading