From 14dc7de8698dfe8d243b92da5c3c52da312e1ade Mon Sep 17 00:00:00 2001 From: Ken Hibino Date: Mon, 4 Jan 2021 12:05:37 -0800 Subject: [PATCH] Add content to RedisInfoView --- redis_info_handlers.go | 10 ++- ui/src/api.ts | 1 + ui/src/reducers/redisInfoReducer.ts | 3 + ui/src/utils.ts | 11 ++- ui/src/views/RedisInfoView.tsx | 126 +++++++++++++++++++++++++++- 5 files changed, 141 insertions(+), 10 deletions(-) diff --git a/redis_info_handlers.go b/redis_info_handlers.go index 8d5dd6a..560e9ac 100644 --- a/redis_info_handlers.go +++ b/redis_info_handlers.go @@ -15,8 +15,9 @@ import ( // **************************************************************************** type RedisInfoResponse struct { - Addr string `json:"address"` - Info map[string]string `json:"info"` + Addr string `json:"address"` + Info map[string]string `json:"info"` + RawInfo string `json:"raw_info"` } func newRedisInfoHandlerFunc(rdb *redis.Client) http.HandlerFunc { @@ -29,8 +30,9 @@ func newRedisInfoHandlerFunc(rdb *redis.Client) http.HandlerFunc { } info := parseRedisInfo(res) resp := RedisInfoResponse{ - Addr: redisAddr, - Info: info, + Addr: redisAddr, + Info: info, + RawInfo: res, } if err := json.NewEncoder(w).Encode(resp); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/ui/src/api.ts b/ui/src/api.ts index 9e24fcc..4d08822 100644 --- a/ui/src/api.ts +++ b/ui/src/api.ts @@ -71,6 +71,7 @@ export interface ListQueueStatsResponse { export interface RedisInfoResponse { address: string; info: RedisInfo; + raw_info: string; } // Return value from redis INFO command. diff --git a/ui/src/reducers/redisInfoReducer.ts b/ui/src/reducers/redisInfoReducer.ts index 35504f1..69c83da 100644 --- a/ui/src/reducers/redisInfoReducer.ts +++ b/ui/src/reducers/redisInfoReducer.ts @@ -10,12 +10,14 @@ interface RedisInfoState { loading: boolean; address: string; data: RedisInfo | null; + rawData: string | null; } const initialState: RedisInfoState = { loading: false, address: "", data: null, + rawData: null, }; export default function redisInfoReducer( @@ -40,6 +42,7 @@ export default function redisInfoReducer( loading: false, address: action.payload.address, data: action.payload.info, + rawData: action.payload.raw_info, }; default: diff --git a/ui/src/utils.ts b/ui/src/utils.ts index c714210..e1a4fb9 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -37,13 +37,18 @@ export function durationBefore(timestamp: string): string { export function timeAgo(timestamp: string): string { try { - const duration = durationBetween(Date.now(), Date.parse(timestamp)); - return stringifyDuration(duration) + " ago"; - } catch { + return timeAgoUnix(Date.parse(timestamp) / 1000); + } catch (error) { + console.error("Could not parse timestamp: ", timestamp, error); return "-"; } } +export function timeAgoUnix(unixtime: number) { + const duration = durationBetween(Date.now(), unixtime * 1000); + return stringifyDuration(duration) + " ago"; +} + export function getCurrentUTCDate(): string { const today = new Date(); const dd = today.getUTCDate().toString().padStart(2, "0"); diff --git a/ui/src/views/RedisInfoView.tsx b/ui/src/views/RedisInfoView.tsx index 690c154..3113adb 100644 --- a/ui/src/views/RedisInfoView.tsx +++ b/ui/src/views/RedisInfoView.tsx @@ -4,9 +4,14 @@ import Container from "@material-ui/core/Container"; import { makeStyles } from "@material-ui/core/styles"; import Grid from "@material-ui/core/Grid"; import Typography from "@material-ui/core/Typography"; +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github"; import { getRedisInfoAsync } from "../actions/redisInfoActions"; import { usePolling } from "../hooks"; import { AppState } from "../store"; +import { timeAgoUnix } from "../utils"; const useStyles = makeStyles((theme) => ({ container: { @@ -26,6 +31,7 @@ function mapStateToProps(state: AppState) { loading: state.redis.loading, redisInfo: state.redis.data, redisAddress: state.redis.address, + redisInfoRaw: state.redis.rawData, pollInterval: state.settings.pollInterval, }; } @@ -35,12 +41,10 @@ type Props = ConnectedProps; function RedisInfoView(props: Props) { const classes = useStyles(); - const { pollInterval, getRedisInfoAsync } = props; + const { pollInterval, getRedisInfoAsync, redisInfo, redisInfoRaw } = props; usePolling(getRedisInfoAsync, pollInterval); - console.log("DEBUG: redisInfo", props.redisInfo); - // Metrics to show // - Used Memory // - Memory Fragmentation Ratio @@ -58,9 +62,125 @@ function RedisInfoView(props: Props) { Connected to: {props.redisAddress} + {redisInfo !== null && ( + <> + + + Server + + + + + + + + + + + + Memory + + + + + + + + + + + + + + + Connections + + + + + + + + + + + + Persistence + + + + + + + + + + + )} + {redisInfoRaw !== null && ( + <> + + + INFO Command Output + + + {redisInfoRaw} + + + + )} ); } +interface MetricCardProps { + title: string; + content: string; +} + +function MetricCard(props: MetricCardProps) { + return ( + + + + {props.content} + + + {props.title} + + + + ); +} + export default connector(RedisInfoView);