2024-02-17 03:17:38 -08:00
|
|
|
import "@mantine/core/styles.css";
|
2024-02-21 02:13:48 -08:00
|
|
|
import "@mantine/code-highlight/styles.css";
|
|
|
|
import classes from "./App.module.css";
|
|
|
|
import PrometheusLogo from "./images/prometheus-logo.svg";
|
2024-02-17 03:17:38 -08:00
|
|
|
|
2024-02-21 02:13:48 -08:00
|
|
|
import {
|
|
|
|
AppShell,
|
|
|
|
Burger,
|
|
|
|
Button,
|
|
|
|
Group,
|
|
|
|
MantineProvider,
|
|
|
|
Menu,
|
|
|
|
Skeleton,
|
|
|
|
Text,
|
|
|
|
createTheme,
|
|
|
|
rem,
|
|
|
|
} from "@mantine/core";
|
|
|
|
import { useDisclosure } from "@mantine/hooks";
|
|
|
|
import {
|
|
|
|
IconBellFilled,
|
|
|
|
IconChartAreaFilled,
|
|
|
|
IconChevronDown,
|
|
|
|
IconChevronRight,
|
|
|
|
IconCloudDataConnection,
|
|
|
|
IconDatabase,
|
|
|
|
IconFileAnalytics,
|
|
|
|
IconFlag,
|
|
|
|
IconHeartRateMonitor,
|
|
|
|
IconHelp,
|
|
|
|
IconInfoCircle,
|
|
|
|
IconServerCog,
|
|
|
|
} from "@tabler/icons-react";
|
|
|
|
import {
|
|
|
|
BrowserRouter,
|
|
|
|
NavLink,
|
|
|
|
Navigate,
|
|
|
|
Route,
|
|
|
|
Routes,
|
|
|
|
} from "react-router-dom";
|
|
|
|
import Graph from "./pages/graph";
|
|
|
|
import Alerts from "./pages/alerts";
|
|
|
|
import { IconTable } from "@tabler/icons-react";
|
|
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
|
|
// import { ReactQueryDevtools } from "react-query/devtools";
|
|
|
|
import Rules from "./pages/rules";
|
|
|
|
import Targets from "./pages/targets";
|
|
|
|
import ServiceDiscovery from "./pages/service-discovery";
|
|
|
|
import Status from "./pages/status";
|
|
|
|
import TSDBStatus from "./pages/tsdb-status";
|
|
|
|
import Flags from "./pages/flags";
|
|
|
|
import Config from "./pages/config";
|
|
|
|
import { Suspense, useContext } from "react";
|
|
|
|
import ErrorBoundary from "./error-boundary";
|
|
|
|
import { ThemeSelector } from "./theme-selector";
|
|
|
|
import { SettingsContext } from "./settings";
|
|
|
|
import Agent from "./pages/agent";
|
|
|
|
|
|
|
|
const queryClient = new QueryClient();
|
|
|
|
|
|
|
|
const monitoringStatusPages = [
|
|
|
|
{
|
|
|
|
title: "Targets",
|
|
|
|
path: "/targets",
|
|
|
|
icon: <IconHeartRateMonitor style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <Targets />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "Rules",
|
|
|
|
path: "/rules",
|
|
|
|
icon: <IconTable style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <Rules />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "Service discovery",
|
|
|
|
path: "/service-discovery",
|
|
|
|
icon: (
|
|
|
|
<IconCloudDataConnection style={{ width: rem(14), height: rem(14) }} />
|
|
|
|
),
|
|
|
|
element: <ServiceDiscovery />,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const serverStatusPages = [
|
|
|
|
{
|
|
|
|
title: "Runtime & build information",
|
|
|
|
path: "/status",
|
|
|
|
icon: <IconInfoCircle style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <Status />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "TSDB status",
|
|
|
|
path: "/tsdb-status",
|
|
|
|
icon: <IconDatabase style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <TSDBStatus />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "Command-line flags",
|
|
|
|
path: "/flags",
|
|
|
|
icon: <IconFlag style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <Flags />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "Configuration",
|
|
|
|
path: "/config",
|
|
|
|
icon: <IconServerCog style={{ width: rem(14), height: rem(14) }} />,
|
|
|
|
element: <Config />,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const allStatusPages = [...monitoringStatusPages, ...serverStatusPages];
|
|
|
|
|
|
|
|
const theme = createTheme({
|
|
|
|
colors: {
|
|
|
|
"codebox-bg": [
|
|
|
|
"#f5f5f5",
|
|
|
|
"#e7e7e7",
|
|
|
|
"#cdcdcd",
|
|
|
|
"#b2b2b2",
|
|
|
|
"#9a9a9a",
|
|
|
|
"#8b8b8b",
|
|
|
|
"#848484",
|
|
|
|
"#717171",
|
|
|
|
"#656565",
|
|
|
|
"#575757",
|
|
|
|
],
|
|
|
|
},
|
|
|
|
});
|
2024-02-17 03:17:38 -08:00
|
|
|
|
|
|
|
function App() {
|
2024-02-21 02:13:48 -08:00
|
|
|
const [opened, { toggle }] = useDisclosure();
|
|
|
|
const { agentMode } = useContext(SettingsContext);
|
|
|
|
|
|
|
|
const navLinks = (
|
|
|
|
<>
|
|
|
|
<Button
|
|
|
|
component={NavLink}
|
|
|
|
to="/graph"
|
|
|
|
className={classes.link}
|
2024-02-23 05:19:46 -08:00
|
|
|
leftSection={<IconChartAreaFilled size={14} />}
|
2024-02-21 02:13:48 -08:00
|
|
|
>
|
|
|
|
Graph
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
component={NavLink}
|
|
|
|
to="/alerts"
|
|
|
|
className={classes.link}
|
2024-02-23 05:19:46 -08:00
|
|
|
leftSection={<IconBellFilled size={14} />}
|
2024-02-21 02:13:48 -08:00
|
|
|
>
|
|
|
|
Alerts
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
<Menu shadow="md" width={230}>
|
|
|
|
<Routes>
|
|
|
|
{allStatusPages.map((p) => (
|
|
|
|
<Route
|
|
|
|
key={p.path}
|
|
|
|
path={p.path}
|
|
|
|
element={
|
|
|
|
<Menu.Target>
|
|
|
|
<Button
|
|
|
|
component={NavLink}
|
|
|
|
to={p.path}
|
|
|
|
className={classes.link}
|
|
|
|
leftSection={p.icon}
|
2024-02-23 05:19:46 -08:00
|
|
|
rightSection={<IconChevronDown size={14} />}
|
2024-02-21 02:13:48 -08:00
|
|
|
>
|
2024-02-23 05:19:46 -08:00
|
|
|
Status <IconChevronRight size={14} /> {p.title}
|
2024-02-21 02:13:48 -08:00
|
|
|
</Button>
|
|
|
|
</Menu.Target>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
<Route
|
|
|
|
path="*"
|
|
|
|
element={
|
|
|
|
<Menu.Target>
|
|
|
|
<Button
|
|
|
|
component={NavLink}
|
|
|
|
to="/"
|
|
|
|
className={classes.link}
|
2024-02-23 05:19:46 -08:00
|
|
|
leftSection={<IconFileAnalytics size={14} />}
|
|
|
|
rightSection={<IconChevronDown size={14} />}
|
2024-02-21 02:13:48 -08:00
|
|
|
onClick={(e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Status
|
|
|
|
</Button>
|
|
|
|
</Menu.Target>
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</Routes>
|
|
|
|
|
|
|
|
<Menu.Dropdown>
|
|
|
|
<Menu.Label>Monitoring status</Menu.Label>
|
|
|
|
{monitoringStatusPages.map((p) => (
|
|
|
|
<Menu.Item
|
|
|
|
key={p.path}
|
|
|
|
component={NavLink}
|
|
|
|
to={p.path}
|
|
|
|
leftSection={p.icon}
|
|
|
|
>
|
|
|
|
{p.title}
|
|
|
|
</Menu.Item>
|
|
|
|
))}
|
|
|
|
|
|
|
|
<Menu.Divider />
|
|
|
|
<Menu.Label>Server status</Menu.Label>
|
|
|
|
{serverStatusPages.map((p) => (
|
|
|
|
<Menu.Item
|
|
|
|
key={p.path}
|
|
|
|
component={NavLink}
|
|
|
|
to={p.path}
|
|
|
|
leftSection={p.icon}
|
|
|
|
>
|
|
|
|
{p.title}
|
|
|
|
</Menu.Item>
|
|
|
|
))}
|
|
|
|
</Menu.Dropdown>
|
|
|
|
</Menu>
|
|
|
|
|
|
|
|
<Button
|
|
|
|
component="a"
|
|
|
|
href="https://prometheus.io/docs/prometheus/latest/getting_started/"
|
|
|
|
className={classes.link}
|
2024-02-23 05:19:46 -08:00
|
|
|
leftSection={<IconHelp size={14} />}
|
2024-02-21 02:13:48 -08:00
|
|
|
target="_blank"
|
|
|
|
>
|
|
|
|
Help
|
|
|
|
</Button>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<BrowserRouter>
|
|
|
|
<MantineProvider defaultColorScheme="auto" theme={theme}>
|
|
|
|
<QueryClientProvider client={queryClient}>
|
|
|
|
<AppShell
|
|
|
|
header={{ height: 56 }}
|
|
|
|
navbar={{
|
|
|
|
width: 300,
|
|
|
|
breakpoint: "sm",
|
|
|
|
collapsed: { desktop: true, mobile: !opened },
|
|
|
|
}}
|
|
|
|
padding="md"
|
|
|
|
>
|
|
|
|
<AppShell.Header bg="rgb(65, 73, 81)" c="#fff">
|
|
|
|
<Group h="100%" px="md">
|
|
|
|
<Group style={{ flex: 1 }}>
|
|
|
|
<Group gap={10}>
|
|
|
|
<img src={PrometheusLogo} height={30} />
|
|
|
|
<Text fz={20}>Prometheus{agentMode && " Agent"}</Text>
|
|
|
|
</Group>
|
|
|
|
<Group ml="lg" gap={12} visibleFrom="sm">
|
|
|
|
{navLinks}
|
|
|
|
</Group>
|
|
|
|
</Group>
|
|
|
|
<Burger
|
|
|
|
opened={opened}
|
|
|
|
onClick={toggle}
|
|
|
|
hiddenFrom="sm"
|
|
|
|
size="sm"
|
|
|
|
color="gray.2"
|
|
|
|
/>
|
|
|
|
{<ThemeSelector />}
|
|
|
|
</Group>
|
|
|
|
</AppShell.Header>
|
|
|
|
|
|
|
|
<AppShell.Navbar py="md" px={4} bg="rgb(65, 73, 81)" c="#fff">
|
|
|
|
{navLinks}
|
|
|
|
</AppShell.Navbar>
|
|
|
|
|
|
|
|
<AppShell.Main>
|
|
|
|
<ErrorBoundary key={location.pathname}>
|
|
|
|
<Suspense
|
|
|
|
fallback={Array.from(Array(10), (_, i) => (
|
|
|
|
<Skeleton key={i} height={40} mb={15} width={1000} />
|
|
|
|
))}
|
|
|
|
>
|
|
|
|
<Routes>
|
|
|
|
<Route
|
|
|
|
path="/"
|
|
|
|
element={
|
|
|
|
<Navigate to={agentMode ? "/agent" : "/graph"} />
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<Route path="/graph" element={<Graph />} />
|
|
|
|
<Route path="/agent" element={<Agent />} />
|
|
|
|
<Route path="/alerts" element={<Alerts />} />
|
|
|
|
{allStatusPages.map((p) => (
|
|
|
|
<Route key={p.path} path={p.path} element={p.element} />
|
|
|
|
))}
|
|
|
|
</Routes>
|
|
|
|
</Suspense>
|
|
|
|
</ErrorBoundary>
|
|
|
|
</AppShell.Main>
|
|
|
|
</AppShell>
|
|
|
|
{/* <ReactQueryDevtools initialIsOpen={false} /> */}
|
|
|
|
</QueryClientProvider>
|
|
|
|
</MantineProvider>
|
|
|
|
</BrowserRouter>
|
|
|
|
);
|
2024-02-17 03:17:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
export default App;
|