@@ -0,0 +1,186 @@ | |||||
export interface RedisMonitorInfoVO { | |||||
info: RedisInfoVO | |||||
dbSize: number | |||||
commandStats: RedisCommandStatsVO[] | |||||
} | |||||
export interface RedisInfoVO { | |||||
io_threaded_reads_processed: string | |||||
tracking_clients: string | |||||
uptime_in_seconds: string | |||||
cluster_connections: string | |||||
current_cow_size: string | |||||
maxmemory_human: string | |||||
aof_last_cow_size: string | |||||
master_replid2: string | |||||
mem_replication_backlog: string | |||||
aof_rewrite_scheduled: string | |||||
total_net_input_bytes: string | |||||
rss_overhead_ratio: string | |||||
hz: string | |||||
current_cow_size_age: string | |||||
redis_build_id: string | |||||
errorstat_BUSYGROUP: string | |||||
aof_last_bgrewrite_status: string | |||||
multiplexing_api: string | |||||
client_recent_max_output_buffer: string | |||||
allocator_resident: string | |||||
mem_fragmentation_bytes: string | |||||
aof_current_size: string | |||||
repl_backlog_first_byte_offset: string | |||||
tracking_total_prefixes: string | |||||
redis_mode: string | |||||
redis_git_dirty: string | |||||
aof_delayed_fsync: string | |||||
allocator_rss_bytes: string | |||||
repl_backlog_histlen: string | |||||
io_threads_active: string | |||||
rss_overhead_bytes: string | |||||
total_system_memory: string | |||||
loading: string | |||||
evicted_keys: string | |||||
maxclients: string | |||||
cluster_enabled: string | |||||
redis_version: string | |||||
repl_backlog_active: string | |||||
mem_aof_buffer: string | |||||
allocator_frag_bytes: string | |||||
io_threaded_writes_processed: string | |||||
instantaneous_ops_per_sec: string | |||||
used_memory_human: string | |||||
total_error_replies: string | |||||
role: string | |||||
maxmemory: string | |||||
used_memory_lua: string | |||||
rdb_current_bgsave_time_sec: string | |||||
used_memory_startup: string | |||||
used_cpu_sys_main_thread: string | |||||
lazyfree_pending_objects: string | |||||
aof_pending_bio_fsync: string | |||||
used_memory_dataset_perc: string | |||||
allocator_frag_ratio: string | |||||
arch_bits: string | |||||
used_cpu_user_main_thread: string | |||||
mem_clients_normal: string | |||||
expired_time_cap_reached_count: string | |||||
unexpected_error_replies: string | |||||
mem_fragmentation_ratio: string | |||||
aof_last_rewrite_time_sec: string | |||||
master_replid: string | |||||
aof_rewrite_in_progress: string | |||||
lru_clock: string | |||||
maxmemory_policy: string | |||||
run_id: string | |||||
latest_fork_usec: string | |||||
tracking_total_items: string | |||||
total_commands_processed: string | |||||
expired_keys: string | |||||
errorstat_ERR: string | |||||
used_memory: string | |||||
module_fork_in_progress: string | |||||
errorstat_WRONGPASS: string | |||||
aof_buffer_length: string | |||||
dump_payload_sanitizations: string | |||||
mem_clients_slaves: string | |||||
keyspace_misses: string | |||||
server_time_usec: string | |||||
executable: string | |||||
lazyfreed_objects: string | |||||
db0: string | |||||
used_memory_peak_human: string | |||||
keyspace_hits: string | |||||
rdb_last_cow_size: string | |||||
aof_pending_rewrite: string | |||||
used_memory_overhead: string | |||||
active_defrag_hits: string | |||||
tcp_port: string | |||||
uptime_in_days: string | |||||
used_memory_peak_perc: string | |||||
current_save_keys_processed: string | |||||
blocked_clients: string | |||||
total_reads_processed: string | |||||
expire_cycle_cpu_milliseconds: string | |||||
sync_partial_err: string | |||||
used_memory_scripts_human: string | |||||
aof_current_rewrite_time_sec: string | |||||
aof_enabled: string | |||||
process_supervised: string | |||||
master_repl_offset: string | |||||
used_memory_dataset: string | |||||
used_cpu_user: string | |||||
rdb_last_bgsave_status: string | |||||
tracking_total_keys: string | |||||
atomicvar_api: string | |||||
allocator_rss_ratio: string | |||||
client_recent_max_input_buffer: string | |||||
clients_in_timeout_table: string | |||||
aof_last_write_status: string | |||||
mem_allocator: string | |||||
used_memory_scripts: string | |||||
used_memory_peak: string | |||||
process_id: string | |||||
master_failover_state: string | |||||
errorstat_NOAUTH: string | |||||
used_cpu_sys: string | |||||
repl_backlog_size: string | |||||
connected_slaves: string | |||||
current_save_keys_total: string | |||||
gcc_version: string | |||||
total_system_memory_human: string | |||||
sync_full: string | |||||
connected_clients: string | |||||
module_fork_last_cow_size: string | |||||
total_writes_processed: string | |||||
allocator_active: string | |||||
total_net_output_bytes: string | |||||
pubsub_channels: string | |||||
current_fork_perc: string | |||||
active_defrag_key_hits: string | |||||
rdb_changes_since_last_save: string | |||||
instantaneous_input_kbps: string | |||||
used_memory_rss_human: string | |||||
configured_hz: string | |||||
expired_stale_perc: string | |||||
active_defrag_misses: string | |||||
used_cpu_sys_children: string | |||||
number_of_cached_scripts: string | |||||
sync_partial_ok: string | |||||
used_memory_lua_human: string | |||||
rdb_last_save_time: string | |||||
pubsub_patterns: string | |||||
slave_expires_tracked_keys: string | |||||
redis_git_sha1: string | |||||
used_memory_rss: string | |||||
rdb_last_bgsave_time_sec: string | |||||
os: string | |||||
mem_not_counted_for_evict: string | |||||
active_defrag_running: string | |||||
rejected_connections: string | |||||
aof_rewrite_buffer_length: string | |||||
total_forks: string | |||||
active_defrag_key_misses: string | |||||
allocator_allocated: string | |||||
aof_base_size: string | |||||
instantaneous_output_kbps: string | |||||
second_repl_offset: string | |||||
rdb_bgsave_in_progress: string | |||||
used_cpu_user_children: string | |||||
total_connections_received: string | |||||
migrate_cached_sockets: string | |||||
} | |||||
export interface RedisCommandStatsVO { | |||||
command: string | |||||
calls: number | |||||
usec: number | |||||
} | |||||
export interface RedisKeyInfo { | |||||
keyTemplate: string | |||||
keyType: string | |||||
valueType: string | |||||
timeoutType: number | |||||
timeout: number | |||||
memo: string | |||||
} | |||||
@@ -0,0 +1,248 @@ | |||||
import React, { useState, useEffect, useRef } from 'react'; | |||||
import { Table, Tag, Card, Descriptions } from 'antd'; | |||||
import type { TableColumnsType, DescriptionsProps } from 'antd'; | |||||
import { Pie, Liquid, Gauge } from '@ant-design/plots'; | |||||
import { t } from '@/utils/i18n'; | |||||
import { useRequest } from '@/hooks/use-request'; | |||||
import redisService from '@/request/service/redis'; | |||||
import type { RedisKeyInfo, RedisMonitorInfoVO } from '@/models' | |||||
export default () => { | |||||
const [dataSource, setDataSource] = useState<RedisKeyInfo[]>([]); | |||||
const [redisMonitorInfo, setRedisMonitorInfo] = useState<RedisMonitorInfoVO>(); | |||||
const graphRef = useRef(null); | |||||
const { runAsync: getPageApi } = useRequest(redisService.getKeyDefineListApi, { manual: true }); | |||||
const { runAsync: getCache } = useRequest(redisService.getCacheApi, { manual: true }); | |||||
const load = async () => { | |||||
const [error, { data }] = await getPageApi(); | |||||
if (!error) { | |||||
setDataSource(data); | |||||
} | |||||
}; | |||||
const loadCache = async () => { | |||||
const [error, { data }] = await getCache(); | |||||
if (!error) { | |||||
setRedisMonitorInfo(data); | |||||
graphRef.current!!.changeData(parseFloat(data.info.used_memory_human.replace("M", ''))/100) | |||||
} | |||||
} | |||||
const columns: TableColumnsType<RedisKeyInfo> = [ | |||||
{ | |||||
title: 'Key模板', | |||||
dataIndex: 'keyTemplate', | |||||
key: 'keyTemplate', | |||||
align: 'right', | |||||
width: 200, | |||||
}, | |||||
{ | |||||
title: 'Key类型', | |||||
dataIndex: 'keyType', | |||||
key: 'keyType', | |||||
align: 'center', | |||||
width: 150 | |||||
}, | |||||
{ | |||||
title: 'Value类型', | |||||
key: 'valueType', | |||||
dataIndex: 'valueType', | |||||
align: 'left', | |||||
width: 200 | |||||
}, | |||||
{ | |||||
title: '超时时间', | |||||
key: 'timeoutType', | |||||
dataIndex: 'timeoutType', | |||||
width: 120, | |||||
align: 'center', | |||||
render: (value: number) => { | |||||
return (value === 3 ? <Tag color="purple">固定超时</Tag> : <Tag color="blue">动态超时</Tag>) | |||||
} | |||||
}, | |||||
{ | |||||
title: '备注', | |||||
key: 'memo', | |||||
dataIndex: 'memo', | |||||
align: 'left', | |||||
} | |||||
]; | |||||
const items: DescriptionsProps['items'] = [ | |||||
{ | |||||
key: 'redis_version', | |||||
label: 'Redis版本', | |||||
children: redisMonitorInfo?.info?.redis_version, | |||||
}, | |||||
{ | |||||
key: 'redis_mode', | |||||
label: '运行模式', | |||||
children: redisMonitorInfo?.info?.redis_mode == 'standalone' ? '单机' : '集群', | |||||
}, | |||||
{ | |||||
key: 'tcp_port', | |||||
label: '端口', | |||||
children: redisMonitorInfo?.info?.tcp_port, | |||||
}, | |||||
{ | |||||
key: 'connected_clients', | |||||
label: '客户端数', | |||||
children: redisMonitorInfo?.info?.connected_clients, | |||||
}, | |||||
{ | |||||
key: 'uptime_in_days', | |||||
label: '运行时间(天)', | |||||
children: redisMonitorInfo?.info?.uptime_in_days, | |||||
}, | |||||
{ | |||||
key: 'used_memory_human', | |||||
label: '使用内存', | |||||
children: redisMonitorInfo?.info?.used_memory_human, | |||||
}, | |||||
{ | |||||
key: 'used_cpu_user_children', | |||||
label: '使用CPU', | |||||
children: redisMonitorInfo?.info ? parseFloat(redisMonitorInfo?.info?.used_cpu_user_children).toFixed(2) : '', | |||||
}, | |||||
{ | |||||
key: 'maxmemory_human', | |||||
label: '内存配置', | |||||
children: redisMonitorInfo?.info?.maxmemory_human, | |||||
}, | |||||
{ | |||||
key: 'aof_enabled', | |||||
label: 'AOF是否开启', | |||||
children: redisMonitorInfo?.info?.aof_enabled == '0' ? '否' : '是', | |||||
}, | |||||
{ | |||||
key: 'rdb_last_bgsave_status', | |||||
label: 'RDB是否成功', | |||||
children: redisMonitorInfo?.info?.rdb_last_bgsave_status, | |||||
}, | |||||
{ | |||||
key: 'dbSize', | |||||
label: 'Key数量', | |||||
children: redisMonitorInfo?.dbSize, | |||||
}, | |||||
{ | |||||
key: 'instantaneous', | |||||
label: '网络入口/出口', | |||||
children: (<> | |||||
{redisMonitorInfo?.info?.instantaneous_input_kbps} kps/{redisMonitorInfo?.info?.instantaneous_output_kbps} kps | |||||
</>), | |||||
}, | |||||
]; | |||||
const config = { | |||||
appendPadding: 10, | |||||
data: redisMonitorInfo?.commandStats.map(it => { | |||||
return { | |||||
type: it.command, | |||||
value: it.usec | |||||
} | |||||
}) ?? [], | |||||
angleField: 'value', | |||||
colorField: 'type', | |||||
radius: 0.8, | |||||
label: { | |||||
type: 'outer', | |||||
content: '{name} {percentage}', | |||||
}, | |||||
interactions: [ | |||||
{ | |||||
type: 'pie-legend-active', | |||||
}, | |||||
{ | |||||
type: 'element-active', | |||||
}, | |||||
], | |||||
}; | |||||
const ticks = [0, 1 / 3, 2 / 3, 1]; | |||||
const color = ['#30BF78', '#FAAD14', '#F4664A']; | |||||
const memUsage = { | |||||
percent: 0, | |||||
type: 'meter', | |||||
innerRadius: 0.8, | |||||
range: { ticks, color }, | |||||
indicator: { | |||||
pointer: { | |||||
style: { | |||||
stroke: '#D0D0D0', | |||||
}, | |||||
}, | |||||
pin: { | |||||
style: { | |||||
stroke: '#D0D0D0', | |||||
}, | |||||
}, | |||||
}, | |||||
statistic: { | |||||
title: { | |||||
formatter: () => redisMonitorInfo?.info.used_memory_human??'0M', | |||||
style: ({ percent }) => { | |||||
return { | |||||
fontSize: '24px', | |||||
lineHeight: 1, | |||||
color: percent < ticks[1] ? color[0] : percent < ticks[2] ? color[1] : color[2], | |||||
}; | |||||
}, | |||||
}, | |||||
content: { | |||||
offsetY: 24, | |||||
style: { | |||||
fontSize: '16px', | |||||
lineHeight: '16px', | |||||
}, | |||||
formatter: () => '内存消耗' | |||||
}, | |||||
}, | |||||
onReady: (plot) => { | |||||
graphRef.current = plot; | |||||
} | |||||
} | |||||
useEffect(() => { | |||||
load(); | |||||
loadCache(); | |||||
}, []); | |||||
return ( | |||||
<> | |||||
<div> | |||||
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]'> | |||||
<Descriptions title="基本信息" | |||||
bordered | |||||
column={6} | |||||
items={items} /> | |||||
</Card> | |||||
<div className='flex flex-row'> | |||||
<Card className='basis-1/2 mt-[4px] mr-[8px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' | |||||
title="命令统计"> | |||||
<Pie {...config} /> | |||||
</Card> | |||||
<Card className='basis-1/2 mt-[4px] ml-[8px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' | |||||
title="内存使用情况"> | |||||
<Gauge {...memUsage} /> | |||||
</Card> | |||||
</div> | |||||
<Card className='mt-[4px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]'> | |||||
<Table rowKey="id" | |||||
scroll={{ x: true }} | |||||
columns={columns} | |||||
dataSource={dataSource} | |||||
className='bg-transparent' | |||||
pagination={false} /> | |||||
</Card> | |||||
</div> | |||||
</> | |||||
); | |||||
}; | |||||
@@ -0,0 +1,39 @@ | |||||
import request from '@/request'; | |||||
import { RedisMonitorInfoVO, RedisInfoVO, RedisCommandStatsVO, RedisKeyInfo } from '@/models'; | |||||
const BASE_URL = '/admin-api/infra/redis'; | |||||
export default { | |||||
/** | |||||
* 获取redis 监控信息 | |||||
*/ | |||||
getCacheApi: () => { | |||||
return request.get<RedisMonitorInfoVO>(`${BASE_URL}/get-monitor-info`) | |||||
}, | |||||
// 获取模块 | |||||
getKeyDefineListApi: () => { | |||||
return request.get<RedisKeyInfo[]>(`${BASE_URL}/get-key-define-list`) | |||||
}, | |||||
/** | |||||
* 获取redis key列表 | |||||
*/ | |||||
getKeyListApi: (keyTemplate: string) => { | |||||
return request.get(`${BASE_URL}/get-key-list`, { params: { keyTemplate } }) | |||||
}, | |||||
// 获取缓存内容 | |||||
getKeyValueApi: (key: string) => { | |||||
return request.get(`${BASE_URL}/get-key-value?key=${key}`) | |||||
}, | |||||
// 根据键名删除缓存 | |||||
deleteKeyApi: (key: string) => { | |||||
return request.delete(`${BASE_URL}/delete-key?key=${key}`) | |||||
}, | |||||
deleteKeysApi: (keyTemplate: string) => { | |||||
return request.delete(`${BASE_URL}/delete-keys`, { params: { keyTemplate } }) | |||||
}, | |||||
} |