powersir 1 рік тому
джерело
коміт
084b88e5a5
4 змінених файлів з 474 додано та 0 видалено
  1. +1
    -0
      src/models/index.ts
  2. +186
    -0
      src/models/redis.data.ts
  3. +248
    -0
      src/pages/infra/redis/index.tsx
  4. +39
    -0
      src/request/service/redis.ts

+ 1
- 0
src/models/index.ts Переглянути файл

@@ -8,6 +8,7 @@ export * from './template.data.ts'
export * from './platform-product.data.ts'
export * from './system-dict.data.ts'
export * from './error-code.data.ts'
export * from './redis.data.ts'

export interface ResponseDTO<T>{
code: number;


+ 186
- 0
src/models/redis.data.ts Переглянути файл

@@ -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
}

+ 248
- 0
src/pages/infra/redis/index.tsx Переглянути файл

@@ -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>
</>
);
};


+ 39
- 0
src/request/service/redis.ts Переглянути файл

@@ -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 } })
},

}

Завантаження…
Відмінити
Зберегти