prometheus/web/ui/react-app/src/pages/status/Status.tsx

118 lines
3.8 KiB
TypeScript
Raw Normal View History

2019-11-12 05:35:47 -08:00
import React, { Fragment, FC } from 'react';
import { RouteComponentProps } from '@reach/router';
2019-11-12 05:35:47 -08:00
import { Table } from 'reactstrap';
import { withStatusIndicator } from '../../components/withStatusIndicator';
import { useFetch } from '../../hooks/useFetch';
import PathPrefixProps from '../../types/PathPrefixProps';
2019-11-02 08:53:32 -07:00
const sectionTitles = ['Runtime Information', 'Build Information', 'Alertmanagers'];
interface StatusConfig {
2019-11-12 05:35:47 -08:00
[k: string]: { title?: string; customizeValue?: (v: any, key: string) => any; customRow?: boolean; skip?: boolean };
2019-11-02 08:53:32 -07:00
}
2019-11-12 05:35:47 -08:00
type StatusPageState = { [k: string]: string };
interface StatusPageProps {
data?: StatusPageState[];
}
2019-11-02 08:53:32 -07:00
export const statusConfig: StatusConfig = {
startTime: { title: 'Start time', customizeValue: (v: string) => new Date(v).toUTCString() },
CWD: { title: 'Working directory' },
reloadConfigSuccess: {
title: 'Configuration reload',
customizeValue: (v: boolean) => (v ? 'Successful' : 'Unsuccessful'),
},
lastConfigTime: { title: 'Last successful configuration reload' },
chunkCount: { title: 'Head chunks' },
timeSeriesCount: { title: 'Head time series' },
corruptionCount: { title: 'WAL corruptions' },
goroutineCount: { title: 'Goroutines' },
storageRetention: { title: 'Storage retention' },
activeAlertmanagers: {
customRow: true,
2019-11-12 05:35:47 -08:00
customizeValue: (alertMgrs: { url: string }[], key) => {
2019-11-02 08:53:32 -07:00
return (
2019-11-12 05:35:47 -08:00
<Fragment key={key}>
2019-11-02 08:53:32 -07:00
<tr>
<th>Endpoint</th>
</tr>
{alertMgrs.map(({ url }) => {
const { origin, pathname } = new URL(url);
return (
<tr key={url}>
<td>
<a href={url}>{origin}</a>
{pathname}
</td>
</tr>
);
})}
</Fragment>
);
},
},
droppedAlertmanagers: { skip: true },
};
2019-11-12 05:35:47 -08:00
export const StatusContent: FC<StatusPageProps> = ({ data = [] }) => {
return (
<>
{data.map((statuses, i) => {
2019-11-02 08:53:32 -07:00
return (
<Fragment key={i}>
<h2>{sectionTitles[i]}</h2>
<Table className="h-auto" size="sm" bordered striped>
<tbody>
{Object.entries(statuses).map(([k, v]) => {
2019-11-02 08:53:32 -07:00
const { title = k, customizeValue = (val: any) => val, customRow, skip } = statusConfig[k] || {};
if (skip) {
return null;
}
if (customRow) {
2019-11-12 05:35:47 -08:00
return customizeValue(v, k);
2019-11-02 08:53:32 -07:00
}
return (
<tr key={k}>
<th className="capitalize-title" style={{ width: '35%' }}>
{title}
</th>
2019-11-12 05:35:47 -08:00
<td className="text-break">{customizeValue(v, title)}</td>
2019-11-02 08:53:32 -07:00
</tr>
);
})}
</tbody>
</Table>
</Fragment>
);
})}
</>
2019-11-12 05:35:47 -08:00
);
};
const StatusWithStatusIndicator = withStatusIndicator(StatusContent);
StatusContent.displayName = 'Status';
const Status: FC<RouteComponentProps & PathPrefixProps> = ({ pathPrefix = '' }) => {
const path = `${pathPrefix}/api/v1`;
const status = useFetch<StatusPageState>(`${path}/status/runtimeinfo`);
const runtime = useFetch<StatusPageState>(`${path}/status/buildinfo`);
const build = useFetch<StatusPageState>(`${path}/alertmanagers`);
let data;
if (status.response.data && runtime.response.data && build.response.data) {
data = [status.response.data, runtime.response.data, build.response.data];
}
return (
<StatusWithStatusIndicator
data={data}
isLoading={status.isLoading || runtime.isLoading || build.isLoading}
error={status.error || runtime.error || build.error}
/>
);
2019-11-02 08:53:32 -07:00
};
export default Status;