github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/rules/RulesContent.tsx (about)

     1  import React, { FC } from 'react';
     2  import { RouteComponentProps } from '@reach/router';
     3  import { APIResponse } from '../../hooks/useFetch';
     4  import { UncontrolledAlert, Table, Badge } from 'reactstrap';
     5  import { formatRelative, createExternalExpressionLink, humanizeDuration, formatDuration } from '../../utils';
     6  import { Rule } from '../../types/types';
     7  import { now } from 'moment';
     8  
     9  interface RulesContentProps {
    10    response: APIResponse<RulesMap>;
    11  }
    12  
    13  interface RuleGroup {
    14    name: string;
    15    file: string;
    16    rules: Rule[];
    17    evaluationTime: string;
    18    lastEvaluation: string;
    19  }
    20  
    21  export interface RulesMap {
    22    groups: RuleGroup[];
    23  }
    24  
    25  const GraphExpressionLink: FC<{ expr: string; text: string; title: string }> = (props) => {
    26    return (
    27      <>
    28        <strong>{props.title}:</strong>
    29        <a className="ml-4" href={createExternalExpressionLink(props.expr)}>
    30          {props.text}
    31        </a>
    32        <br />
    33      </>
    34    );
    35  };
    36  
    37  export const RulesContent: FC<RouteComponentProps & RulesContentProps> = ({ response }) => {
    38    const getBadgeColor = (state: string) => {
    39      switch (state) {
    40        case 'ok':
    41          return 'success';
    42  
    43        case 'err':
    44          return 'danger';
    45  
    46        case 'unknown':
    47          return 'warning';
    48      }
    49    };
    50  
    51    if (response.data) {
    52      const groups: RuleGroup[] = response.data.groups;
    53      return (
    54        <>
    55          <h2>Rules</h2>
    56          {groups.map((g, i) => {
    57            return (
    58              <Table bordered key={i}>
    59                <thead>
    60                  <tr>
    61                    <td colSpan={3}>
    62                      <a href={'#' + g.name}>
    63                        <h2 id={g.name}>{g.name}</h2>
    64                      </a>
    65                    </td>
    66                    <td>
    67                      <h2>{formatRelative(g.lastEvaluation, now())} ago</h2>
    68                    </td>
    69                    <td>
    70                      <h2>{humanizeDuration(parseFloat(g.evaluationTime) * 1000)}</h2>
    71                    </td>
    72                  </tr>
    73                </thead>
    74                <tbody>
    75                  <tr className="font-weight-bold">
    76                    <td>Rule</td>
    77                    <td>State</td>
    78                    <td>Error</td>
    79                    <td>Last Evaluation</td>
    80                    <td>Evaluation Time</td>
    81                  </tr>
    82                  {g.rules.map((r, i) => {
    83                    return (
    84                      <tr key={i}>
    85                        {r.alerts ? (
    86                          <td className="rule-cell">
    87                            <GraphExpressionLink title="alert" text={r.name} expr={`ALERTS{alertname="${r.name}"}`} />
    88                            <GraphExpressionLink title="expr" text={r.query} expr={r.query} />
    89                            {r.duration > 0 && (
    90                              <div>
    91                                <strong>for:</strong> {formatDuration(r.duration * 1000)}
    92                              </div>
    93                            )}
    94  
    95                            <div>
    96                              <strong>labels:</strong>
    97                              {Object.entries(r.labels).map(([key, value]) => (
    98                                <div className="ml-4" key={key}>
    99                                  {key}: {value}
   100                                </div>
   101                              ))}
   102                            </div>
   103                            <div>
   104                              <strong>annotations:</strong>
   105                              {Object.entries(r.annotations).map(([key, value]) => (
   106                                <div className="ml-4" key={key}>
   107                                  {key}: {value}
   108                                </div>
   109                              ))}
   110                            </div>
   111                          </td>
   112                        ) : (
   113                          <td>
   114                            <GraphExpressionLink title="record" text={r.name} expr={r.name} />
   115                            <GraphExpressionLink title="expr" text={r.query} expr={r.query} />
   116                          </td>
   117                        )}
   118                        <td>
   119                          <Badge color={getBadgeColor(r.health)}>{r.health.toUpperCase()}</Badge>
   120                        </td>
   121                        <td>{r.lastError ? <UncontrolledAlert color="danger">{r.lastError}</UncontrolledAlert> : null}</td>
   122                        <td>{formatRelative(r.lastEvaluation, now())} ago</td>
   123                        <td>{humanizeDuration(parseFloat(r.evaluationTime) * 1000)}</td>
   124                      </tr>
   125                    );
   126                  })}
   127                </tbody>
   128              </Table>
   129            );
   130          })}
   131        </>
   132      );
   133    }
   134  
   135    return null;
   136  };