github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/status/Status.tsx (about) 1 import React, { Fragment, FC } from 'react'; 2 import { RouteComponentProps } from '@reach/router'; 3 import { Table } from 'reactstrap'; 4 import { withStatusIndicator } from '../../components/withStatusIndicator'; 5 import { useFetch } from '../../hooks/useFetch'; 6 import PathPrefixProps from '../../types/PathPrefixProps'; 7 8 interface StatusPageProps { 9 data: Record<string, string>; 10 title: string; 11 } 12 13 export const statusConfig: Record< 14 string, 15 { title?: string; customizeValue?: (v: any, key: string) => any; customRow?: boolean; skip?: boolean } 16 > = { 17 startTime: { title: 'Start time', customizeValue: (v: string) => new Date(v).toUTCString() }, 18 CWD: { title: 'Working directory' }, 19 reloadConfigSuccess: { 20 title: 'Configuration reload', 21 customizeValue: (v: boolean) => (v ? 'Successful' : 'Unsuccessful'), 22 }, 23 lastConfigTime: { title: 'Last successful configuration reload' }, 24 chunkCount: { title: 'Head chunks' }, 25 timeSeriesCount: { title: 'Head time series' }, 26 corruptionCount: { title: 'WAL corruptions' }, 27 goroutineCount: { title: 'Goroutines' }, 28 storageRetention: { title: 'Storage retention' }, 29 activeAlertmanagers: { 30 customRow: true, 31 customizeValue: (alertMgrs: { url: string }[], key) => { 32 return ( 33 <Fragment key={key}> 34 <tr> 35 <th>Endpoint</th> 36 </tr> 37 {alertMgrs.map(({ url }) => { 38 const { origin, pathname } = new URL(url); 39 return ( 40 <tr key={url}> 41 <td> 42 <a href={url}>{origin}</a> 43 {pathname} 44 </td> 45 </tr> 46 ); 47 })} 48 </Fragment> 49 ); 50 }, 51 }, 52 droppedAlertmanagers: { skip: true }, 53 }; 54 55 export const StatusContent: FC<StatusPageProps> = ({ data, title }) => { 56 return ( 57 <> 58 <h2>{title}</h2> 59 <Table className="h-auto" size="sm" bordered striped> 60 <tbody> 61 {Object.entries(data).map(([k, v]) => { 62 const { title = k, customizeValue = (val: any) => val, customRow, skip } = statusConfig[k] || {}; 63 if (skip) { 64 return null; 65 } 66 if (customRow) { 67 return customizeValue(v, k); 68 } 69 return ( 70 <tr key={k}> 71 <th className="capitalize-title" style={{ width: '35%' }}> 72 {title} 73 </th> 74 <td className="text-break">{customizeValue(v, title)}</td> 75 </tr> 76 ); 77 })} 78 </tbody> 79 </Table> 80 </> 81 ); 82 }; 83 const StatusWithStatusIndicator = withStatusIndicator(StatusContent); 84 85 StatusContent.displayName = 'Status'; 86 87 const Status: FC<RouteComponentProps & PathPrefixProps> = ({ pathPrefix = '' }) => { 88 const path = `${pathPrefix}/api/v1`; 89 90 return ( 91 <> 92 {[ 93 { fetchResult: useFetch<Record<string, string>>(`${path}/status/runtimeinfo`), title: 'Runtime Information' }, 94 { fetchResult: useFetch<Record<string, string>>(`${path}/status/buildinfo`), title: 'Build Information' }, 95 ].map(({ fetchResult, title }) => { 96 const { response, isLoading, error } = fetchResult; 97 return ( 98 <StatusWithStatusIndicator 99 key={title} 100 data={response.data} 101 title={title} 102 isLoading={isLoading} 103 error={error} 104 componentTitle={title} 105 /> 106 ); 107 })} 108 </> 109 ); 110 }; 111 112 export default Status;