Fetch redis info from RedisInfoView

This commit is contained in:
Ken Hibino 2021-01-03 08:07:19 -08:00
parent 5a83172784
commit 4951d2f571
5 changed files with 253 additions and 2 deletions

View File

@ -0,0 +1,43 @@
import { Dispatch } from "redux";
import { getRedisInfo, RedisInfo } from "../api";
// List of redis-info related action types.
export const GET_REDIS_INFO_BEGIN = "GET_REDIS_INFO_BEGIN";
export const GET_REDIS_INFO_SUCCESS = "GET_REDIS_INFO_SUCCESS";
export const GET_REDIS_INFO_ERROR = "GET_REDIS_INFO_ERROR";
interface GetRedisInfoBeginAction {
type: typeof GET_REDIS_INFO_BEGIN;
}
interface GetRedisInfoSuccessAction {
type: typeof GET_REDIS_INFO_SUCCESS;
payload: RedisInfo;
}
interface GetRedisInfoErrorAction {
type: typeof GET_REDIS_INFO_ERROR;
error: string;
}
// Union of all redis-info related actions.
export type RedisInfoActionTypes =
| GetRedisInfoBeginAction
| GetRedisInfoErrorAction
| GetRedisInfoSuccessAction;
export function getRedisInfoAsync() {
return async (dispatch: Dispatch<RedisInfoActionTypes>) => {
dispatch({ type: GET_REDIS_INFO_BEGIN });
try {
const response = await getRedisInfo();
dispatch({ type: GET_REDIS_INFO_SUCCESS, payload: response });
} catch (error) {
console.error("getRedisInfoAsync: ", error);
dispatch({
type: GET_REDIS_INFO_BEGIN,
error: "Could not fetch redis info",
});
}
};
}

View File

@ -68,6 +68,141 @@ export interface ListQueueStatsResponse {
stats: { [qname: string]: DailyStat[] }; stats: { [qname: string]: DailyStat[] };
} }
// Return value from redis INFO command.
// See https://redis.io/commands/info#return-value.
export interface RedisInfo {
active_defrag_hits: string;
active_defrag_key_hits: string;
active_defrag_key_misses: string;
active_defrag_misses: string;
active_defrag_running: string;
allocator_active: string;
allocator_allocated: string;
allocator_frag_bytes: string;
allocator_frag_ratio: string;
allocator_resident: string;
allocator_rss_bytes: string;
allocator_rss_ratio: string;
aof_current_rewrite_time_sec: string;
aof_enabled: string;
aof_last_bgrewrite_status: string;
aof_last_cow_size: string;
aof_last_rewrite_time_sec: string;
aof_last_write_status: string;
aof_rewrite_in_progress: string;
aof_rewrite_scheduled: string;
arch_bits: string;
atomicvar_api: string;
blocked_clients: string;
client_recent_max_input_buffer: string;
client_recent_max_output_buffer: string;
clients_in_timeout_table: string;
cluster_enabled: string;
config_file: string;
configured_hz: string;
connected_clients: string;
connected_slaves: string;
evicted_keys: string;
executable: string;
expire_cycle_cpu_milliseconds: string;
expired_keys: string;
expired_stale_perc: string;
expired_time_cap_reached_count: string;
gcc_version: string;
hz: string;
instantaneous_input_kbps: string;
instantaneous_ops_per_sec: string;
instantaneous_output_kbps: string;
keyspace_hits: string;
keyspace_misses: string;
latest_fork_usec: string;
lazyfree_pending_objects: string;
loading: string;
lru_clock: string;
master_repl_offset: string;
master_replid: string;
master_replid2: string;
maxmemory: string;
maxmemory_human: string;
maxmemory_policy: string;
mem_allocator: string;
mem_aof_buffer: string;
mem_clients_normal: string;
mem_clients_slaves: string;
mem_fragmentation_bytes: string;
mem_fragmentation_ratio: string;
mem_not_counted_for_evict: string;
mem_replication_backlog: string;
migrate_cached_sockets: string;
module_fork_in_progress: string;
module_fork_last_cow_size: string;
multiplexing_api: string;
number_of_cached_scripts: string;
os: string;
process_id: string;
pubsub_channels: string;
pubsub_patterns: string;
rdb_bgsave_in_progress: string;
rdb_changes_since_last_save: string;
rdb_current_bgsave_time_sec: string;
rdb_last_bgsave_status: string;
rdb_last_bgsave_time_sec: string;
rdb_last_cow_size: string;
rdb_last_save_time: string;
redis_build_id: string;
redis_git_dirty: string;
redis_git_sha1: string;
redis_mode: string;
redis_version: string;
rejected_connections: string;
repl_backlog_active: string;
repl_backlog_first_byte_offset: string;
repl_backlog_histlen: string;
repl_backlog_size: string;
role: string;
rss_overhead_bytes: string;
rss_overhead_ratio: string;
run_id: string;
second_repl_offset: string;
slave_expires_tracked_keys: string;
sync_full: string;
sync_partial_err: string;
sync_partial_ok: string;
tcp_port: string;
total_commands_processed: string;
total_connections_received: string;
total_net_input_bytes: string;
total_net_output_bytes: string;
total_system_memory: string;
total_system_memory_human: string;
tracking_clients: string;
tracking_total_items: string;
tracking_total_keys: string;
tracking_total_prefixes: string;
unexpected_error_replies: string;
uptime_in_days: string;
uptime_in_seconds: string;
used_cpu_sys: string;
used_cpu_sys_children: string;
used_cpu_user: string;
used_cpu_user_children: string;
used_memory: string;
used_memory_dataset: string;
used_memory_dataset_perc: string;
used_memory_human: string;
used_memory_lua: string;
used_memory_lua_human: string;
used_memory_overhead: string;
used_memory_peak: string;
used_memory_peak_human: string;
used_memory_peak_perc: string;
used_memory_rss: string;
used_memory_rss_human: string;
used_memory_scripts: string;
used_memory_scripts_human: string;
used_memory_startup: string;
}
export interface Queue { export interface Queue {
queue: string; queue: string;
paused: boolean; paused: boolean;
@ -587,3 +722,11 @@ export async function listSchedulerEnqueueEvents(
}); });
return resp.data; return resp.data;
} }
export async function getRedisInfo(): Promise<RedisInfo> {
const resp = await axios({
method: "get",
url: `${BASE_URL}/redis_info`,
});
return resp.data;
}

View File

@ -0,0 +1,45 @@
import {
GET_REDIS_INFO_BEGIN,
GET_REDIS_INFO_ERROR,
GET_REDIS_INFO_SUCCESS,
RedisInfoActionTypes,
} from "../actions/redisInfoActions";
import { RedisInfo } from "../api";
interface RedisInfoState {
loading: boolean;
data: RedisInfo | null;
}
const initialState: RedisInfoState = {
loading: false,
data: null,
};
export default function redisInfoReducer(
state = initialState,
action: RedisInfoActionTypes
): RedisInfoState {
switch (action.type) {
case GET_REDIS_INFO_BEGIN:
return {
...state,
loading: true,
};
case GET_REDIS_INFO_ERROR:
return {
...state,
loading: false,
};
case GET_REDIS_INFO_SUCCESS:
return {
loading: false,
data: action.payload,
};
default:
return state;
}
}

View File

@ -6,6 +6,7 @@ import serversReducer from "./reducers/serversReducer";
import schedulerEntriesReducer from "./reducers/schedulerEntriesReducer"; import schedulerEntriesReducer from "./reducers/schedulerEntriesReducer";
import snackbarReducer from "./reducers/snackbarReducer"; import snackbarReducer from "./reducers/snackbarReducer";
import queueStatsReducer from "./reducers/queueStatsReducer"; import queueStatsReducer from "./reducers/queueStatsReducer";
import redisInfoReducer from "./reducers/redisInfoReducer";
const rootReducer = combineReducers({ const rootReducer = combineReducers({
settings: settingsReducer, settings: settingsReducer,
@ -15,6 +16,7 @@ const rootReducer = combineReducers({
schedulerEntries: schedulerEntriesReducer, schedulerEntries: schedulerEntriesReducer,
snackbar: snackbarReducer, snackbar: snackbarReducer,
queueStats: queueStatsReducer, queueStats: queueStatsReducer,
redis: redisInfoReducer,
}); });
// AppState is the top-level application state maintained by redux store. // AppState is the top-level application state maintained by redux store.

View File

@ -1,8 +1,12 @@
import React from "react"; import React from "react";
import { connect, ConnectedProps } from "react-redux";
import Container from "@material-ui/core/Container"; import Container from "@material-ui/core/Container";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import Grid from "@material-ui/core/Grid"; import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import { getRedisInfoAsync } from "../actions/redisInfoActions";
import { usePolling } from "../hooks";
import { AppState } from "../store";
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
container: { container: {
@ -17,8 +21,22 @@ const useStyles = makeStyles((theme) => ({
}, },
})); }));
function RedisInfoView() { function mapStateToProps(state: AppState) {
return {
loading: state.redis.loading,
redisInfo: state.redis.data,
pollInterval: state.settings.pollInterval,
};
}
const connector = connect(mapStateToProps, { getRedisInfoAsync });
type Props = ConnectedProps<typeof connector>;
function RedisInfoView(props: Props) {
const classes = useStyles(); const classes = useStyles();
const { pollInterval, getRedisInfoAsync } = props;
usePolling(getRedisInfoAsync, pollInterval);
return ( return (
<Container maxWidth="lg" className={classes.container}> <Container maxWidth="lg" className={classes.container}>
@ -31,4 +49,4 @@ function RedisInfoView() {
); );
} }
export default RedisInfoView; export default connector(RedisInfoView);