Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@mantine/hooks": "^7.5.1",
"@mantine/notifications": "^7.5.1",
"@monaco-editor/react": "^4.5.1",
"@tabler/icons-react": "^2.23.0",
"@tabler/icons-react": "^2.47.0",
"@types/js-cookie": "^3.0.3",
"axios": "^1.4.0",
"dayjs": "^1.11.10",
Expand Down
53 changes: 31 additions & 22 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/@types/parseable/api/about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type AboutData = {
license: string;
mode: string;
staging: string;
store: string;
store: { type: string; path: string };
updateAvailable: boolean;
version: string;
llmActive: boolean;
Expand Down
21 changes: 21 additions & 0 deletions src/@types/parseable/api/clusterInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export type Ingestor = {
domain_name: string;
reachable: boolean;
error: string | null;
status: string;
staging_path: string;
storage_path: string;
};

export type IngestorMetrics = {
address: string;
parseable_events_ingested: number;
parseable_staging_files: number;
process_resident_memory_bytes: number;
parseable_storage_size: {
staging: number;
data: number;
};
};

export type ClusterInfo = Ingestor[];
15 changes: 15 additions & 0 deletions src/api/cluster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Ingestor, IngestorMetrics } from '@/@types/parseable/api/clusterInfo';
import { Axios } from './axios';
import { CLUSTER_INFO_URL, CLUSTER_METRICS_URL, INGESTOR_DELETE_URL } from './constants';

export const getClusterInfo = () => {
return Axios().get<Ingestor[]>(CLUSTER_INFO_URL);
};

export const getClusterMetrics = () => {
return Axios().get<IngestorMetrics[]>(CLUSTER_METRICS_URL);
};

export const deleteIngestor = (ingestorUrl: string) => {
return Axios().delete(INGESTOR_DELETE_URL(ingestorUrl));
};
5 changes: 5 additions & 0 deletions src/api/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const LOG_STREAMS_ALERTS_URL = (streamName: string) => `${LOG_STREAM_LIST
export const LOG_STREAMS_RETRNTION_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}/retention`;
export const LOG_STREAMS_STATS_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}/stats`;
export const DELETE_STREAMS_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}`;
export const CREATE_STREAM_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}`;

// About Parsable Instance
export const ABOUT_URL = `${API_V1}/about`;
Expand All @@ -32,3 +33,7 @@ export const IS_LLM_ACTIVE_URL = `${LLM_QUERY_URL}/isactive`;

// caching
export const CACHING_STATUS_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}/cache`;

export const CLUSTER_INFO_URL = `${API_V1}/cluster/info`;
export const CLUSTER_METRICS_URL = `${API_V1}/cluster/metrics`;
export const INGESTOR_DELETE_URL = (ingestorUrl: string) => `${API_V1}/cluster/${ingestorUrl}`;
5 changes: 5 additions & 0 deletions src/api/logStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
LOG_STREAMS_ALERTS_URL,
LOG_STREAMS_RETRNTION_URL,
LOG_STREAMS_STATS_URL,
CREATE_STREAM_URL,
} from './constants';
import { LogStreamData, LogStreamSchemaData } from '@/@types/parseable/api/stream';

Expand Down Expand Up @@ -40,3 +41,7 @@ export const getLogStreamStats = (streamName: string) => {
export const deleteLogStream = (streamName: string) => {
return Axios().delete(DELETE_STREAMS_URL(streamName));
};

export const createLogStream = (streamName: string) => {
return Axios().put(CREATE_STREAM_URL(streamName));
}
10 changes: 8 additions & 2 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Box, Stack, Tooltip } from '@mantine/core';
import { IconLogout, IconUser, IconBinaryTree2, IconInfoCircle, IconUserCog, IconHome } from '@tabler/icons-react';
import { IconLogout, IconUser, IconBinaryTree2, IconInfoCircle, IconUserCog, IconHome, IconServerCog } from '@tabler/icons-react';
import { FC, useCallback, useEffect } from 'react';
import { useLocation, useParams } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { useHeaderContext } from '@/layouts/MainLayout/Context';
import { useDisclosure } from '@mantine/hooks';
import { HOME_ROUTE, LOGS_ROUTE, USERS_MANAGEMENT_ROUTE } from '@/constants/routes';
import { HOME_ROUTE, LOGS_ROUTE, SYSTEMS_ROUTE, USERS_MANAGEMENT_ROUTE } from '@/constants/routes';
import InfoModal from './infoModal';
import { getStreamsSepcificAccess, getUserSepcificStreams } from './rolesHandler';
import Cookies from 'js-cookie';
Expand Down Expand Up @@ -36,6 +36,12 @@ const navItems = [
path: '/users',
route: USERS_MANAGEMENT_ROUTE,
},
{
icon: IconServerCog,
label: 'Systems',
path: '/systems',
route: SYSTEMS_ROUTE,
}
];

const navActions = [
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navbar/infoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const InfoModal: FC<InfoModalProps> = (props) => {
</Box>
<Box className={aboutTextInnerBox}>
<Text className={aboutTextKey}>Store</Text>
<Text className={aboutTextValue}>{getAboutData?.data.store}</Text>
<Text className={aboutTextValue}>{getAboutData?.data?.store?.type}</Text>
</Box>
<Box className={aboutTextInnerBox}>
<Text className={aboutTextKey}>Cache</Text>
Expand Down
22 changes: 12 additions & 10 deletions src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ export const STATS_ROUTE = '/:streamName/stats';
export const CONFIG_ROUTE = '/:streamName/config';
export const USERS_MANAGEMENT_ROUTE = '/users';
export const OIDC_NOT_CONFIGURED_ROUTE = '/oidc-not-configured';
export const SYSTEMS_ROUTE = '/systems';

export const PATHS = {
all: '/*',
home: '/',
logs: '/:streamName/logs',
login: '/login',
liveTail: '/:streamName/live-tail',
stats: '/:streamName/stats',
config: '/:streamName/config',
users: '/users',
oidcNotConfigured: '/oidc-not-configured'
} as {[key: string]: string}
all: '/*',
home: '/',
logs: '/:streamName/logs',
login: '/login',
liveTail: '/:streamName/live-tail',
stats: '/:streamName/stats',
config: '/:streamName/config',
users: '/users',
oidcNotConfigured: '/oidc-not-configured',
systems: '/systems',
} as { [key: string]: string };
72 changes: 72 additions & 0 deletions src/hooks/useClusterInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useMutation, useQuery } from 'react-query';
import { AxiosError, AxiosResponse, isAxiosError } from 'axios';
import { getClusterInfo, getClusterMetrics, deleteIngestor } from '@/api/cluster';
import { Ingestor, IngestorMetrics } from '@/@types/parseable/api/clusterInfo';
import { notifyError, notifySuccess } from '@/utils/notification';

export const useClusterInfo = () => {
const {
data: clusterInfoData,
isError: getClusterInfoError,
isSuccess: getClusterInfoSuccess,
isLoading: getClusterInfoLoading,
refetch: getClusterInfoRefetch,
} = useQuery<AxiosResponse<Ingestor[]>, Error>(['fetch-cluster-info'], () => getClusterInfo(), {
retry: false,
refetchOnWindowFocus: false,
});
return {
clusterInfoData,
getClusterInfoError,
getClusterInfoSuccess,
getClusterInfoLoading,
getClusterInfoRefetch,
};
};

export const useClusterMetrics = () => {
const {
data: clusterMetrics,
isError: getClusterMetricsError,
isSuccess: getClusterMetricsSuccess,
isLoading: getClusterMetricsLoading,
refetch: getClusterMetricsRefetch,
} = useQuery<AxiosResponse<IngestorMetrics[]>>(['fetch-cluster-metrics'], () => getClusterMetrics(), {
retry: false,
refetchOnWindowFocus: false,
});
return {
clusterMetrics,
getClusterMetricsError,
getClusterMetricsSuccess,
getClusterMetricsLoading,
getClusterMetricsRefetch,
};
};

export const useDeleteIngestor = () => {
const {
mutate: deleteIngestorMutation,
isSuccess: deleteIngestorIsSuccess,
isError: deleteIngestorIsError,
isLoading: deleteIngestorIsLoading,
} = useMutation((data: { ingestorUrl: string; onSuccess: () => void }) => deleteIngestor(data.ingestorUrl), {
onError: (data: AxiosError) => {
if (isAxiosError(data) && data.response) {
const error = data.response.data as string;
typeof error === 'string' && notifyError({ message: error });
}
},
onSuccess: (_data, variables) => {
variables.onSuccess && variables.onSuccess();
notifySuccess({ message: 'Ingestor removed successfully' });
},
});

return {
deleteIngestorMutation,
deleteIngestorIsSuccess,
deleteIngestorIsError,
deleteIngestorIsLoading,
};
};
Loading