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);