github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/asynqmon/ui/src/views/RedisInfoView.tsx (about)

     1  import React from "react";
     2  import { connect, ConnectedProps } from "react-redux";
     3  import Container from "@material-ui/core/Container";
     4  import { makeStyles } from "@material-ui/core/styles";
     5  import Grid from "@material-ui/core/Grid";
     6  import Typography from "@material-ui/core/Typography";
     7  import Card from "@material-ui/core/Card";
     8  import CardContent from "@material-ui/core/CardContent";
     9  import Alert from "@material-ui/lab/Alert";
    10  import AlertTitle from "@material-ui/lab/AlertTitle";
    11  import SyntaxHighlighter from "../components/SyntaxHighlighter";
    12  import { getRedisInfoAsync } from "../actions/redisInfoActions";
    13  import { usePolling } from "../hooks";
    14  import { AppState } from "../store";
    15  import { timeAgoUnix } from "../utils";
    16  import { RedisInfo } from "../api";
    17  import QueueLocationTable from "../components/QueueLocationTable";
    18  import Link from "@material-ui/core/Link";
    19  
    20  const useStyles = makeStyles((theme) => ({
    21    container: {
    22      paddingTop: theme.spacing(4),
    23      paddingBottom: theme.spacing(4),
    24    },
    25  }));
    26  
    27  function mapStateToProps(state: AppState) {
    28    return {
    29      loading: state.redis.loading,
    30      error: state.redis.error,
    31      redisInfo: state.redis.data,
    32      redisAddress: state.redis.address,
    33      redisInfoRaw: state.redis.rawData,
    34      redisClusterEnabled: state.redis.cluster,
    35      redisClusterNodesRaw: state.redis.rawClusterNodes,
    36      queueLocations: state.redis.queueLocations,
    37      pollInterval: state.settings.pollInterval,
    38      themePreference: state.settings.themePreference,
    39    };
    40  }
    41  
    42  const connector = connect(mapStateToProps, { getRedisInfoAsync });
    43  type Props = ConnectedProps<typeof connector>;
    44  
    45  function RedisInfoView(props: Props) {
    46    const classes = useStyles();
    47    const {
    48      pollInterval,
    49      getRedisInfoAsync,
    50      redisInfo,
    51      redisInfoRaw,
    52      redisClusterEnabled,
    53      redisClusterNodesRaw,
    54      queueLocations,
    55    } = props;
    56    usePolling(getRedisInfoAsync, pollInterval);
    57  
    58    // Metrics to show
    59    // - Used Memory
    60    // - Memory Fragmentation Ratio
    61    // - Connected Clients
    62    // - Connected Replicas (slaves)
    63    // - Persistence (rdb_last_save_time, rdb_changes_since_last_save)
    64    // - Errors (rejected_connections)
    65  
    66    return (
    67      <Container maxWidth="lg" className={classes.container}>
    68        <Grid container spacing={3}>
    69          {props.error === "" ? (
    70            <>
    71              <Grid item xs={12}>
    72                <Typography variant="h5" color="textPrimary">
    73                  {redisClusterEnabled ? "Redis Cluster Info" : "Redis Info"}
    74                </Typography>
    75                {!redisClusterEnabled && (
    76                  <Typography variant="subtitle1" color="textSecondary">
    77                    Connected to: {props.redisAddress}
    78                  </Typography>
    79                )}
    80              </Grid>
    81              {queueLocations && queueLocations.length > 0 && (
    82                <Grid item xs={12}>
    83                  <Typography variant="h6" color="textSecondary">
    84                    Queue Location in Cluster
    85                  </Typography>
    86                  <QueueLocationTable queueLocations={queueLocations} />
    87                </Grid>
    88              )}
    89              {redisClusterNodesRaw && (
    90                <>
    91                  <Grid item xs={12}>
    92                    <Typography variant="h6" color="textSecondary">
    93                      <Link
    94                        href="https://redis.io/commands/cluster-nodes"
    95                        target="_"
    96                      >
    97                        CLUSTER NODES
    98                      </Link>{" "}
    99                      Command Output
   100                    </Typography>
   101                    <SyntaxHighlighter language="yaml">
   102                      {redisClusterNodesRaw}
   103                    </SyntaxHighlighter>
   104                  </Grid>
   105                </>
   106              )}
   107              {redisInfo && !redisClusterEnabled && (
   108                <RedisMetricCards redisInfo={redisInfo} />
   109              )}
   110              {redisInfoRaw && (
   111                <>
   112                  <Grid item xs={6}>
   113                    <Typography variant="h6" color="textSecondary">
   114                      {redisClusterEnabled ? (
   115                        <Link
   116                          href="https://redis.io/commands/cluster-info"
   117                          target="_"
   118                        >
   119                          CLUSTER INFO
   120                        </Link>
   121                      ) : (
   122                        <Link href="https://redis.io/commands/info" target="_">
   123                          INFO
   124                        </Link>
   125                      )}{" "}
   126                      Command Output
   127                    </Typography>
   128                    <SyntaxHighlighter language="yaml">
   129                      {redisInfoRaw}
   130                    </SyntaxHighlighter>
   131                  </Grid>
   132                </>
   133              )}
   134            </>
   135          ) : (
   136            <Grid item xs={12}>
   137              <Alert severity="error">
   138                <AlertTitle>Error</AlertTitle>
   139                Could not retrieve redis live data —{" "}
   140                <strong>See the logs for details</strong>
   141              </Alert>
   142            </Grid>
   143          )}
   144        </Grid>
   145      </Container>
   146    );
   147  }
   148  
   149  function RedisMetricCards(props: { redisInfo: RedisInfo }) {
   150    const { redisInfo } = props;
   151    return (
   152      <>
   153        <Grid item xs={12}>
   154          <Typography variant="h6" color="textSecondary">
   155            Server
   156          </Typography>
   157        </Grid>
   158        <Grid item xs={3}>
   159          <MetricCard title="Version" content={redisInfo.redis_version} />
   160        </Grid>
   161        <Grid item xs={3}>
   162          <MetricCard
   163            title="Uptime"
   164            content={`${redisInfo.uptime_in_days} days`}
   165          />
   166        </Grid>
   167        <Grid item xs={6} />
   168        <Grid item xs={12}>
   169          <Typography variant="h6" color="textSecondary">
   170            Memory
   171          </Typography>
   172        </Grid>
   173        <Grid item xs={3}>
   174          <MetricCard title="Used Memory" content={redisInfo.used_memory_human} />
   175        </Grid>
   176        <Grid item xs={3}>
   177          <MetricCard
   178            title="Peak Memory Used"
   179            content={redisInfo.used_memory_peak_human}
   180          />
   181        </Grid>
   182        <Grid item xs={3}>
   183          <MetricCard
   184            title="Memory Fragmentation Ratio"
   185            content={redisInfo.mem_fragmentation_ratio}
   186          />
   187        </Grid>
   188        <Grid item xs={3} />
   189        <Grid item xs={12}>
   190          <Typography variant="h6" color="textSecondary">
   191            Connections
   192          </Typography>
   193        </Grid>
   194        <Grid item xs={3}>
   195          <MetricCard
   196            title="Connected Clients"
   197            content={redisInfo.connected_clients}
   198          />
   199        </Grid>
   200        <Grid item xs={3}>
   201          <MetricCard
   202            title="Connected Replicas"
   203            content={redisInfo.connected_slaves}
   204          />
   205        </Grid>
   206        <Grid item xs={6} />
   207        <Grid item xs={12}>
   208          <Typography variant="h6" color="textSecondary">
   209            Persistence
   210          </Typography>
   211        </Grid>
   212        <Grid item xs={3}>
   213          <MetricCard
   214            title="Last Save to Disk"
   215            content={timeAgoUnix(parseInt(redisInfo.rdb_last_save_time))}
   216          />
   217        </Grid>
   218        <Grid item xs={3}>
   219          <MetricCard
   220            title="Number of Changes Since Last Dump"
   221            content={redisInfo.rdb_changes_since_last_save}
   222          />
   223        </Grid>
   224        <Grid item xs={6} />
   225      </>
   226    );
   227  }
   228  
   229  interface MetricCardProps {
   230    title: string;
   231    content: string;
   232  }
   233  
   234  function MetricCard(props: MetricCardProps) {
   235    return (
   236      <Card variant="outlined">
   237        <CardContent>
   238          <Typography
   239            gutterBottom
   240            color="textPrimary"
   241            variant="h5"
   242            align="center"
   243          >
   244            {props.content}
   245          </Typography>
   246          <Typography color="textSecondary" variant="subtitle2" align="center">
   247            {props.title}
   248          </Typography>
   249        </CardContent>
   250      </Card>
   251    );
   252  }
   253  
   254  export default connector(RedisInfoView);