prometheus

Форк
0
/
CollapsibleAlertPanel.tsx 
154 строки · 5.3 Кб
1
import React, { FC, useState, Fragment } from 'react';
2
import { Link } from 'react-router-dom';
3
import { Alert, Collapse, Table, Badge } from 'reactstrap';
4
import { RuleStatus } from './AlertContents';
5
import { Rule } from '../../types/types';
6
import { faChevronDown, faChevronRight } from '@fortawesome/free-solid-svg-icons';
7
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
8
import { createExpressionLink, parsePrometheusFloat, formatDuration } from '../../utils/index';
9

10
interface CollapsibleAlertPanelProps {
11
  rule: Rule;
12
  showAnnotations: boolean;
13
}
14

15
const alertColors: RuleStatus<string> = {
16
  firing: 'danger',
17
  pending: 'warning',
18
  inactive: 'success',
19
};
20

21
const CollapsibleAlertPanel: FC<CollapsibleAlertPanelProps> = ({ rule, showAnnotations }) => {
22
  const [open, toggle] = useState(false);
23

24
  return (
25
    <>
26
      <Alert fade={false} onClick={() => toggle(!open)} color={alertColors[rule.state]} style={{ cursor: 'pointer' }}>
27
        <FontAwesomeIcon icon={open ? faChevronDown : faChevronRight} fixedWidth />
28
        <strong>{rule.name}</strong> ({`${rule.alerts.length} active`})
29
      </Alert>
30
      <Collapse isOpen={open} className="mb-2">
31
        {open && (
32
          <>
33
            <pre className="alert-cell">
34
              <code>
35
                <div>
36
                  name: <Link to={createExpressionLink(`ALERTS{alertname="${rule.name}"}`)}>{rule.name}</Link>
37
                </div>
38
                <div>
39
                  expr: <Link to={createExpressionLink(rule.query)}>{rule.query}</Link>
40
                </div>
41
                {rule.duration > 0 && (
42
                  <div>
43
                    <div>for: {formatDuration(rule.duration * 1000)}</div>
44
                  </div>
45
                )}
46
                {rule.keepFiringFor > 0 && (
47
                  <div>
48
                    <div>keep_firing_for: {formatDuration(rule.keepFiringFor * 1000)}</div>
49
                  </div>
50
                )}
51
                {rule.labels && Object.keys(rule.labels).length > 0 && (
52
                  <div>
53
                    <div>labels:</div>
54
                    {Object.entries(rule.labels).map(([key, value]) => (
55
                      <div className="ml-4" key={key}>
56
                        {key}: {value}
57
                      </div>
58
                    ))}
59
                  </div>
60
                )}
61
                {rule.annotations && Object.keys(rule.annotations).length > 0 && (
62
                  <div>
63
                    <div>annotations:</div>
64
                    {Object.entries(rule.annotations).map(([key, value]) => (
65
                      <div className="ml-4" key={key}>
66
                        {key}: {value}
67
                      </div>
68
                    ))}
69
                  </div>
70
                )}
71
              </code>
72
            </pre>
73
            {rule.alerts.length > 0 && (
74
              <Table bordered size="sm">
75
                <thead>
76
                  <tr>
77
                    <th>Labels</th>
78
                    <th>State</th>
79
                    <th>Active Since</th>
80
                    <th>Value</th>
81
                  </tr>
82
                </thead>
83
                <tbody>
84
                  {rule.alerts.map((alert, i) => {
85
                    return (
86
                      <Fragment key={i}>
87
                        <tr>
88
                          <td style={{ verticalAlign: 'middle' }}>
89
                            {Object.entries(alert.labels).map(([k, v], j) => {
90
                              return (
91
                                <Badge key={j} color="primary" className="mr-1">
92
                                  {k}={v}
93
                                </Badge>
94
                              );
95
                            })}
96
                          </td>
97
                          <td>
98
                            <h5 className="m-0">
99
                              <Badge color={alertColors[alert.state] + ' text-uppercase'} className="px-3 mr-1">
100
                                {alert.state}
101
                              </Badge>
102
                              {alert.keepFiringSince && (
103
                                <Badge color="secondary" className="px-3">
104
                                  Stabilizing
105
                                </Badge>
106
                              )}
107
                            </h5>
108
                          </td>
109
                          <td>{alert.activeAt}</td>
110
                          <td>{parsePrometheusFloat(alert.value)}</td>
111
                        </tr>
112
                        {showAnnotations && <Annotations annotations={alert.annotations} />}
113
                      </Fragment>
114
                    );
115
                  })}
116
                </tbody>
117
              </Table>
118
            )}
119
          </>
120
        )}
121
      </Collapse>
122
    </>
123
  );
124
};
125

126
interface AnnotationsProps {
127
  annotations: Record<string, string>;
128
}
129

130
export const Annotations: FC<AnnotationsProps> = ({ annotations }) => {
131
  return (
132
    <Fragment>
133
      <tr>
134
        <td colSpan={4}>
135
          <h5 className="font-weight-bold">Annotations</h5>
136
        </td>
137
      </tr>
138
      <tr>
139
        <td colSpan={4}>
140
          {Object.entries(annotations).map(([k, v], i) => {
141
            return (
142
              <div key={i}>
143
                <strong>{k}</strong>
144
                <div>{v}</div>
145
              </div>
146
            );
147
          })}
148
        </td>
149
      </tr>
150
    </Fragment>
151
  );
152
};
153

154
export default CollapsibleAlertPanel;
155

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

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

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

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