prometheus

Форк
0
159 строк · 4.5 Кб
1
import React, { Fragment, FC, useState, useEffect } from 'react';
2
import { Table } from 'reactstrap';
3
import { withStatusIndicator } from '../../components/withStatusIndicator';
4
import { useFetch } from '../../hooks/useFetch';
5
import { usePathPrefix } from '../../contexts/PathPrefixContext';
6
import { API_PATH } from '../../constants/constants';
7

8
interface StatusPageProps {
9
  data: Record<string, string>;
10
  title: string;
11
}
12

13
export const statusConfig: Record<
14
  string,
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
  { title?: string; customizeValue?: (v: any, key: string) => any; customRow?: boolean; skip?: boolean }
17
> = {
18
  startTime: { title: 'Start time', customizeValue: (v: string) => new Date(v).toUTCString() },
19
  CWD: { title: 'Working directory' },
20
  reloadConfigSuccess: {
21
    title: 'Configuration reload',
22
    customizeValue: (v: boolean) => (v ? 'Successful' : 'Unsuccessful'),
23
  },
24
  lastConfigTime: { title: 'Last successful configuration reload' },
25
  corruptionCount: { title: 'WAL corruptions' },
26
  goroutineCount: { title: 'Goroutines' },
27
  storageRetention: { title: 'Storage retention' },
28
  activeAlertmanagers: {
29
    customRow: true,
30
    customizeValue: (alertMgrs: { url: string }[], key) => {
31
      return (
32
        <Fragment key={key}>
33
          <tr>
34
            <th>Endpoint</th>
35
          </tr>
36
          {alertMgrs.map(({ url }) => {
37
            const { origin, pathname } = new URL(url);
38
            return (
39
              <tr key={url}>
40
                <td>
41
                  <a href={url}>{origin}</a>
42
                  {pathname}
43
                </td>
44
              </tr>
45
            );
46
          })}
47
        </Fragment>
48
      );
49
    },
50
  },
51
  droppedAlertmanagers: { skip: true },
52
};
53

54
export const StatusContent: FC<StatusPageProps> = ({ data, title }) => {
55
  return (
56
    <>
57
      <h2>{title}</h2>
58
      <Table className="h-auto" size="sm" bordered striped>
59
        <tbody>
60
          {Object.entries(data).map(([k, v]) => {
61
            const { title = k, customizeValue = (val: string) => val, customRow, skip } = statusConfig[k] || {};
62
            if (skip) {
63
              return null;
64
            }
65
            if (customRow) {
66
              return customizeValue(v, k);
67
            }
68
            return (
69
              <tr key={k}>
70
                <th className="capitalize-title" style={{ width: '35%' }}>
71
                  {title}
72
                </th>
73
                <td className="text-break">{customizeValue(v, title)}</td>
74
              </tr>
75
            );
76
          })}
77
        </tbody>
78
      </Table>
79
    </>
80
  );
81
};
82
const StatusWithStatusIndicator = withStatusIndicator(StatusContent);
83

84
StatusContent.displayName = 'Status';
85

86
const StatusResult: FC<{ fetchPath: string; title: string }> = ({ fetchPath, title }) => {
87
  const { response, isLoading, error } = useFetch(fetchPath);
88
  return (
89
    <StatusWithStatusIndicator
90
      key={title}
91
      data={response.data}
92
      title={title}
93
      isLoading={isLoading}
94
      error={error}
95
      componentTitle={title}
96
    />
97
  );
98
};
99

100
interface StatusProps {
101
  agentMode?: boolean | false;
102
  setAnimateLogo?: (animateLogo: boolean) => void;
103
}
104

105
const Status: FC<StatusProps> = ({ agentMode, setAnimateLogo }) => {
106
  /*    _
107
   *   /' \
108
   *  |    |
109
   *   \__/ */
110

111
  const [inputText, setInputText] = useState('');
112

113
  useEffect(() => {
114
    const handleKeyPress = (event: KeyboardEvent) => {
115
      const keyPressed = event.key.toUpperCase();
116
      setInputText((prevInputText) => {
117
        const newInputText = prevInputText.slice(-3) + String.fromCharCode(((keyPressed.charCodeAt(0) - 64) % 26) + 65);
118
        return newInputText;
119
      });
120
    };
121

122
    document.addEventListener('keypress', handleKeyPress);
123

124
    return () => {
125
      document.removeEventListener('keypress', handleKeyPress);
126
    };
127
  }, []);
128

129
  useEffect(() => {
130
    if (setAnimateLogo && inputText != '') {
131
      setAnimateLogo(inputText.toUpperCase() === 'QSPN');
132
    }
133
  }, [inputText]);
134

135
  /*    _
136
   *   /' \
137
   *  |    |
138
   *   \__/ */
139

140
  const pathPrefix = usePathPrefix();
141
  const path = `${pathPrefix}/${API_PATH}`;
142

143
  return (
144
    <>
145
      {[
146
        { fetchPath: `${path}/status/runtimeinfo`, title: 'Runtime Information' },
147
        { fetchPath: `${path}/status/buildinfo`, title: 'Build Information' },
148
        { fetchPath: `${path}/alertmanagers`, title: 'Alertmanagers' },
149
      ].map(({ fetchPath, title }) => {
150
        if (agentMode && title === 'Alertmanagers') {
151
          return null;
152
        }
153
        return <StatusResult fetchPath={fetchPath} title={title} />;
154
      })}
155
    </>
156
  );
157
};
158

159
export default Status;
160

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.