From b59c530bada0c7ad8f4f7bd82d88382c7fa171ed Mon Sep 17 00:00:00 2001 From: Suhaha Date: Mon, 19 Apr 2021 22:39:45 +0800 Subject: [PATCH 1/7] feat(ui): rocksdb fields in stmt/slowquery copr tab --- .../SlowQuery/pages/Detail/DetailTabCopr.tsx | 28 +++++++----- .../apps/SlowQuery/utils/useSchemaColumns.ts | 28 ++++++++++++ .../utils/useSlowQueryTableController.ts | 20 ++++----- .../Statement/pages/Detail/PlanDetail.tsx | 9 +++- .../pages/Detail/PlanDetailTabCopr.tsx | 44 ++++++++++++------- ui/lib/apps/Statement/translations/en.yaml | 10 +++++ ui/lib/apps/Statement/translations/zh.yaml | 10 +++++ .../apps/Statement/utils/useSchemaColumns.ts | 28 ++++++++++++ .../utils/useStatementTableController.ts | 19 ++++---- ui/lib/utils/callableCache.ts | 39 ++++++++++++++++ ui/lib/utils/tableColumnFactory.tsx | 10 ++--- 11 files changed, 187 insertions(+), 58 deletions(-) create mode 100644 ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts create mode 100644 ui/lib/apps/Statement/utils/useSchemaColumns.ts create mode 100644 ui/lib/utils/callableCache.ts diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx index b74089b3b6..300e16f02d 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx @@ -10,18 +10,9 @@ export interface ITabCoprProps { export default function TabCopr({ data }: ITabCoprProps) { const items = [ - { - key: 'request_count', - value: , - }, - { - key: 'process_keys', - value: , - }, - { - key: 'total_keys', - value: , - }, + genShortValueTooltipValueItem(data, 'request_count'), + genShortValueTooltipValueItem(data, 'process_keys'), + genShortValueTooltipValueItem(data, 'total_keys'), { key: 'cop_proc_addr', value: data.cop_proc_addr, @@ -30,9 +21,22 @@ export default function TabCopr({ data }: ITabCoprProps) { key: 'cop_wait_addr', value: data.cop_wait_addr, }, + genShortValueTooltipValueItem(data, 'rocksdb_block_cache_hit_count'), + genShortValueTooltipValueItem(data, 'rocksdb_block_read_byte'), + genShortValueTooltipValueItem(data, 'rocksdb_block_read_count'), + genShortValueTooltipValueItem(data, 'rocksdb_delete_skipped_count'), + genShortValueTooltipValueItem(data, 'rocksdb_key_skipped_count'), ] const columns = valueColumns('slow_query.fields.') return ( ) } + +// TODO: refactor items code gen for all DetailsList +function genShortValueTooltipValueItem(data: SlowqueryModel, key: string) { + return { + key, + value: , + } +} diff --git a/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts new file mode 100644 index 0000000000..32b2e727d6 --- /dev/null +++ b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts @@ -0,0 +1,28 @@ +import { useState, useEffect } from 'react' + +import client from '@lib/client' +import { cache } from '@lib/utils/callableCache' + +const slowQueryTableColumnsGet = client + .getInstance() + .slowQueryTableColumnsGet.bind(client.getInstance()) + +export const useSchemaColumns = () => { + const [isLoading, setLoading] = useState(true) + const [schemaColumns, setSchemaColumns] = useState([]) + + useEffect(() => { + const fetchSchemaColumns = async () => { + const { data } = await cache(slowQueryTableColumnsGet).call() + setSchemaColumns(data.map((d) => d.toLowerCase())) + setLoading(false) + } + + fetchSchemaColumns() + }, []) + + return { + schemaColumns, + isLoading, + } +} diff --git a/ui/lib/apps/SlowQuery/utils/useSlowQueryTableController.ts b/ui/lib/apps/SlowQuery/utils/useSlowQueryTableController.ts index d8e1dfeda7..44b5b0a49a 100644 --- a/ui/lib/apps/SlowQuery/utils/useSlowQueryTableController.ts +++ b/ui/lib/apps/SlowQuery/utils/useSlowQueryTableController.ts @@ -16,6 +16,7 @@ import { CacheMgr } from '@lib/utils/useCache' import useCacheItemIndex from '@lib/utils/useCacheItemIndex' import { derivedFields, slowQueryColumns } from './tableColumns' +import { useSchemaColumns } from './useSchemaColumns' export const DEF_SLOW_QUERY_COLUMN_KEYS: IColumnKeys = { query: true, @@ -164,11 +165,11 @@ export default function useSlowQueryTableController( querySchemas() }, []) - const [tableSchemaColumns, setTableSchemaColumns] = useState([]) + const { schemaColumns, isLoading: isSchemaLoading } = useSchemaColumns() const tableColumns = useMemo( - () => slowQueryColumns(slowQueries, tableSchemaColumns, showFullSQL), - [slowQueries, tableSchemaColumns, showFullSQL] + () => slowQueryColumns(slowQueries, schemaColumns, showFullSQL), + [slowQueries, schemaColumns, showFullSQL] ) useEffect(() => { @@ -178,13 +179,6 @@ export default function useSlowQueryTableController( return } - async function queryTableSchema() { - const { - data: schema, - } = await client.getInstance().slowQueryTableColumnsGet() - setTableSchemaColumns(schema) - } - async function getSlowQueryList() { const cacheItem = cacheMgr?.get(cacheKey) if (cacheItem) { @@ -194,7 +188,6 @@ export default function useSlowQueryTableController( setLoadingSlowQueries(true) try { - await queryTableSchema() const res = await client .getInstance() .slowQueryListGet( @@ -220,6 +213,10 @@ export default function useSlowQueryTableController( } setLoadingSlowQueries(false) } + + if (isSchemaLoading) { + return + } getSlowQueryList() }, [ queryOptions, @@ -229,6 +226,7 @@ export default function useSlowQueryTableController( refreshTimes, cacheKey, cacheMgr, + isSchemaLoading, ]) const [downloading, setDownloading] = useState(false) diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx index f3b3195f80..1c2456ed7d 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx @@ -24,6 +24,7 @@ import TabTime from './PlanDetailTabTime' import TabCopr from './PlanDetailTabCopr' import TabTxn from './PlanDetailTabTxn' import SlowQueryTab from './SlowQueryTab' +import { useSchemaColumns } from '../../utils/useSchemaColumns' export interface IQuery extends IPageQuery { plans: string[] @@ -38,7 +39,11 @@ const STMT_DETAIL_PLAN_EXPAND = 'statement.detail_plan_expand' function PlanDetail({ query }: IPlanDetailProps) { const { t } = useTranslation() - const { data, isLoading, error } = useClientRequest((reqConfig) => + const { + data, + isLoading: isDataLoading, + error, + } = useClientRequest((reqConfig) => client .getInstance() .statementsPlanDetailGet( @@ -50,6 +55,8 @@ function PlanDetail({ query }: IPlanDetailProps) { reqConfig ) ) + const { isLoading: isSchemaLoading } = useSchemaColumns() + const isLoading = isDataLoading || isSchemaLoading const [detailExpand, setDetailExpand] = useLocalStorageState( STMT_DETAIL_PLAN_EXPAND, diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx index 8136fc5c16..729347975c 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx @@ -4,32 +4,42 @@ import { StatementModel } from '@lib/client' import { CardTable, ShortValueWithTooltip } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' +import { useSchemaColumns } from '../../utils/useSchemaColumns' + export interface ITabCoprProps { data: StatementModel } export default function TabCopr({ data }: ITabCoprProps) { + const { schemaColumns } = useSchemaColumns() + const columnsSet = new Set(schemaColumns) const items = [ { key: 'sum_cop_task_num', value: data.sum_cop_task_num }, - { - key: 'avg_processed_keys', - value: , - }, - { - key: 'max_processed_keys', - value: , - }, - { - key: 'avg_total_keys', - value: , - }, - { - key: 'max_total_keys', - value: , - }, - ] + genShortValueTooltipValueItem(data, 'avg_processed_keys'), + genShortValueTooltipValueItem(data, 'max_processed_keys'), + genShortValueTooltipValueItem(data, 'avg_total_keys'), + genShortValueTooltipValueItem(data, 'max_total_keys'), + genShortValueTooltipValueItem(data, 'avg_rocksdb_block_cache_hit_count'), + genShortValueTooltipValueItem(data, 'max_rocksdb_block_cache_hit_count'), + genShortValueTooltipValueItem(data, 'avg_rocksdb_block_read_byte'), + genShortValueTooltipValueItem(data, 'max_rocksdb_block_read_byte'), + genShortValueTooltipValueItem(data, 'avg_rocksdb_block_read_count'), + genShortValueTooltipValueItem(data, 'max_rocksdb_block_read_count'), + genShortValueTooltipValueItem(data, 'avg_rocksdb_delete_skipped_count'), + genShortValueTooltipValueItem(data, 'max_rocksdb_delete_skipped_count'), + genShortValueTooltipValueItem(data, 'avg_rocksdb_key_skipped_count'), + genShortValueTooltipValueItem(data, 'max_rocksdb_key_skipped_count'), + ].filter((item) => columnsSet.has(item.key)) const columns = valueColumns('statement.fields.') return ( ) } + +// TODO: refactor items code gen for all DetailsList +function genShortValueTooltipValueItem(data: StatementModel, key: string) { + return { + key, + value: , + } +} diff --git a/ui/lib/apps/Statement/translations/en.yaml b/ui/lib/apps/Statement/translations/en.yaml index 32362aceba..a37f58acbb 100755 --- a/ui/lib/apps/Statement/translations/en.yaml +++ b/ui/lib/apps/Statement/translations/en.yaml @@ -144,3 +144,13 @@ statement: rocksdb_block_read_count_tooltip: Total number of blocks RocksDB read from file (RocksDB block_read_count) rocksdb_block_read_byte: RocksDB FS Read Size rocksdb_block_read_byte_tooltip: Total number of bytes RocksDB read from file (RocksDB block_read_byte) + avg_rocksdb_delete_skipped_count: Mean RocksDB Skipped Deletions + max_rocksdb_delete_skipped_count: Max RocksDB Skipped Deletions + avg_rocksdb_key_skipped_count: Mean RocksDB Skipped Keys + max_rocksdb_key_skipped_count: Max RocksDB Skipped Keys + avg_rocksdb_block_cache_hit_count: Mean RocksDB Block Cache Hits + max_rocksdb_block_cache_hit_count: Max RocksDB Block Cache Hits + avg_rocksdb_block_read_count: Mean RocksDB Block Reads + max_rocksdb_block_read_count: Max RocksDB Block Reads + avg_rocksdb_block_read_byte: Mean RocksDB FS Read Size + max_rocksdb_block_read_byte: Max RocksDB FS Read Size diff --git a/ui/lib/apps/Statement/translations/zh.yaml b/ui/lib/apps/Statement/translations/zh.yaml index 3a78fa1e21..af042a295a 100755 --- a/ui/lib/apps/Statement/translations/zh.yaml +++ b/ui/lib/apps/Statement/translations/zh.yaml @@ -152,3 +152,13 @@ statement: rocksdb_block_read_count_tooltip: RocksDB 从文件系统中读数据的次数 (block_read_count) rocksdb_block_read_byte: RocksDB 文件系统读数据量 rocksdb_block_read_byte_tooltip: RocksDB 从文件系统中读数据的数据量 (block_read_byte) + avg_rocksdb_delete_skipped_count: RocksDB 已删除 Key 平均扫描数 + max_rocksdb_delete_skipped_count: RocksDB 已删除 Key 最大扫描数 + avg_rocksdb_key_skipped_count: RocksDB Key 平均扫描数 + max_rocksdb_key_skipped_count: RocksDB Key 最大扫描数 + avg_rocksdb_block_cache_hit_count: RocksDB 缓存平均读次数 + max_rocksdb_block_cache_hit_count: RocksDB 缓存最大读次数 + avg_rocksdb_block_read_count: RocksDB 文件系统平均读次数 + max_rocksdb_block_read_count: RocksDB 文件系统最大读次数 + avg_rocksdb_block_read_byte: RocksDB 文件系统平均读数据量 + max_rocksdb_block_read_byte: RocksDB 文件系统最大读数据量 diff --git a/ui/lib/apps/Statement/utils/useSchemaColumns.ts b/ui/lib/apps/Statement/utils/useSchemaColumns.ts new file mode 100644 index 0000000000..8301c030ae --- /dev/null +++ b/ui/lib/apps/Statement/utils/useSchemaColumns.ts @@ -0,0 +1,28 @@ +import { useEffect, useState } from 'react' + +import client from '@lib/client' +import { cache } from '@lib/utils/callableCache' + +const statementsTableColumnsGet = client + .getInstance() + .statementsTableColumnsGet.bind(client.getInstance()) + +export const useSchemaColumns = () => { + const [isLoading, setLoading] = useState(true) + const [schemaColumns, setSchemaColumns] = useState([]) + + useEffect(() => { + const fetchSchemaColumns = async () => { + const { data } = await cache(statementsTableColumnsGet).call() + setSchemaColumns(data.map((d) => d.toLowerCase())) + setLoading(false) + } + + fetchSchemaColumns() + }, []) + + return { + schemaColumns, + isLoading, + } +} diff --git a/ui/lib/apps/Statement/utils/useStatementTableController.ts b/ui/lib/apps/Statement/utils/useStatementTableController.ts index 747f4fb1fa..1804f0cc1e 100644 --- a/ui/lib/apps/Statement/utils/useStatementTableController.ts +++ b/ui/lib/apps/Statement/utils/useStatementTableController.ts @@ -19,6 +19,7 @@ import { TimeRange, } from '../pages/List/TimeRangeSelector' import { derivedFields, statementColumns } from './tableColumns' +import { useSchemaColumns } from './useSchemaColumns' export const DEF_STMT_COLUMN_KEYS: IColumnKeys = { digest_text: true, @@ -203,11 +204,11 @@ export default function useStatementTableController( queryStmtTypes() }, [refreshTimes]) - const [tableSchemaColumns, setTableSchemaColumns] = useState([]) + const { schemaColumns, isLoading: isSchemaLoading } = useSchemaColumns() const tableColumns = useMemo( - () => statementColumns(statements, tableSchemaColumns, showFullSQL), - [statements, tableSchemaColumns, showFullSQL] + () => statementColumns(statements, schemaColumns, showFullSQL), + [statements, schemaColumns, showFullSQL] ) useEffect(() => { @@ -217,13 +218,6 @@ export default function useStatementTableController( return } - async function queryTableSchema() { - const { - data: schema, - } = await client.getInstance().statementsTableColumnsGet() - setTableSchemaColumns(schema) - } - async function queryStatementList() { const cacheItem = cacheMgr?.get(cacheKey) if (cacheItem) { @@ -237,7 +231,6 @@ export default function useStatementTableController( } setLoadingStatements(true) try { - await queryTableSchema() const res = await client .getInstance() .statementsListGet( @@ -260,6 +253,9 @@ export default function useStatementTableController( setLoadingStatements(false) } + if (isSchemaLoading) { + return + } queryStatementList() }, [ queryOptions, @@ -268,6 +264,7 @@ export default function useStatementTableController( selectedFields, cacheKey, cacheMgr, + isSchemaLoading, ]) const [downloading, setDownloading] = useState(false) diff --git a/ui/lib/utils/callableCache.ts b/ui/lib/utils/callableCache.ts new file mode 100644 index 0000000000..70595e89e6 --- /dev/null +++ b/ui/lib/utils/callableCache.ts @@ -0,0 +1,39 @@ +interface Cacheable { + call: Fn + clear: () => void +} + +const cacheMap = new Map() + +/** + * function someFunction() { + * return Date.now() + * } + * const cachedSomeFunction = cache(someFunction) + * + * cachedSomeFunction.call() // e.g. 12345 + * cachedSomeFunction.call() // 12345 + * + * cachedSomeFunction.clear() + * + * cachedSomeFunction.call() // e.g. 12346 + */ +export const cache = (fn: Fn): Cacheable => { + const call: any = (...args: any[]) => { + if (cacheMap.has(fn)) { + return cacheMap.get(fn) + } + const rst = fn(...args) + cacheMap.set(fn, rst) + return rst + } + + const clear = () => { + cacheMap.delete(fn) + } + + return { + call, + clear, + } +} diff --git a/ui/lib/utils/tableColumnFactory.tsx b/ui/lib/utils/tableColumnFactory.tsx index 8247dcd35b..bb2e7e0dba 100644 --- a/ui/lib/utils/tableColumnFactory.tsx +++ b/ui/lib/utils/tableColumnFactory.tsx @@ -93,12 +93,10 @@ export class TableColumnFactory { private transPrefix: string, private allowColumns: string[] = [] ) { - this.allowColumnsMap = allowColumns - .map((f) => f.toLowerCase()) - .reduce((prev, f) => { - prev[f] = true - return prev - }, {} as { [f: string]: boolean }) + this.allowColumnsMap = allowColumns.reduce((prev, f) => { + prev[f] = true + return prev + }, {} as { [f: string]: boolean }) } control(config: IColumn): Column { From d77491a4d09def289b8063aa48b8f38ba82a9b58 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Tue, 20 Apr 2021 09:41:09 +0800 Subject: [PATCH 2/7] fix(ui): type safety of copr item --- ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx | 7 +++++-- ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx index 300e16f02d..3eebbc355c 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx @@ -34,9 +34,12 @@ export default function TabCopr({ data }: ITabCoprProps) { } // TODO: refactor items code gen for all DetailsList -function genShortValueTooltipValueItem(data: SlowqueryModel, key: string) { +function genShortValueTooltipValueItem( + data: SlowqueryModel, + key: keyof SlowqueryModel +) { return { key, - value: , + value: , } } diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx index 729347975c..d30c95b1ad 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx @@ -37,9 +37,12 @@ export default function TabCopr({ data }: ITabCoprProps) { } // TODO: refactor items code gen for all DetailsList -function genShortValueTooltipValueItem(data: StatementModel, key: string) { +function genShortValueTooltipValueItem( + data: StatementModel, + key: keyof StatementModel +) { return { key, - value: , + value: , } } From 85af9af87a6164125a9b587c53bf61a5dd7f5c65 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Tue, 20 Apr 2021 16:25:04 +0800 Subject: [PATCH 3/7] chore(ui): unified translate keys --- ui/lib/apps/Statement/translations/en.yaml | 15 +++----- ui/lib/apps/Statement/translations/zh.yaml | 15 +++----- ui/lib/apps/Statement/utils/tableColumns.tsx | 38 +++++++++++++------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/ui/lib/apps/Statement/translations/en.yaml b/ui/lib/apps/Statement/translations/en.yaml index a37f58acbb..d06c070d2e 100755 --- a/ui/lib/apps/Statement/translations/en.yaml +++ b/ui/lib/apps/Statement/translations/en.yaml @@ -134,23 +134,18 @@ statement: prev_sample_text: Previous Query Sample plan: Execution Plan - rocksdb_delete_skipped_count: RocksDB Skipped Deletions - rocksdb_delete_skipped_count_tooltip: Total number of deleted (a.k.a. tombstone) key versions that are skipped during iteration (RocksDB delete_skipped_count) - rocksdb_key_skipped_count: RocksDB Skipped Keys - rocksdb_key_skipped_count_tooltip: Total number of keys skipped during iteration (RocksDB key_skipped_count) - rocksdb_block_cache_hit_count: RocksDB Block Cache Hits - rocksdb_block_cache_hit_count_tooltip: Total number of hits from the block cache (RocksDB block_cache_hit_count) - rocksdb_block_read_count: RocksDB Block Reads - rocksdb_block_read_count_tooltip: Total number of blocks RocksDB read from file (RocksDB block_read_count) - rocksdb_block_read_byte: RocksDB FS Read Size - rocksdb_block_read_byte_tooltip: Total number of bytes RocksDB read from file (RocksDB block_read_byte) avg_rocksdb_delete_skipped_count: Mean RocksDB Skipped Deletions + avg_rocksdb_delete_skipped_count_tooltip: Total number of deleted (a.k.a. tombstone) key versions that are skipped during iteration (RocksDB delete_skipped_count) max_rocksdb_delete_skipped_count: Max RocksDB Skipped Deletions avg_rocksdb_key_skipped_count: Mean RocksDB Skipped Keys + avg_rocksdb_key_skipped_count_tooltip: Total number of keys skipped during iteration (RocksDB key_skipped_count) max_rocksdb_key_skipped_count: Max RocksDB Skipped Keys avg_rocksdb_block_cache_hit_count: Mean RocksDB Block Cache Hits + avg_rocksdb_block_cache_hit_count_tooltip: Total number of hits from the block cache (RocksDB block_cache_hit_count) max_rocksdb_block_cache_hit_count: Max RocksDB Block Cache Hits avg_rocksdb_block_read_count: Mean RocksDB Block Reads + avg_rocksdb_block_read_count_tooltip: Total number of blocks RocksDB read from file (RocksDB block_read_count) max_rocksdb_block_read_count: Max RocksDB Block Reads avg_rocksdb_block_read_byte: Mean RocksDB FS Read Size + avg_rocksdb_block_read_byte_tooltip: Total number of bytes RocksDB read from file (RocksDB block_read_byte) max_rocksdb_block_read_byte: Max RocksDB FS Read Size diff --git a/ui/lib/apps/Statement/translations/zh.yaml b/ui/lib/apps/Statement/translations/zh.yaml index af042a295a..86547c717c 100755 --- a/ui/lib/apps/Statement/translations/zh.yaml +++ b/ui/lib/apps/Statement/translations/zh.yaml @@ -142,23 +142,18 @@ statement: prev_sample_text_tooltip: 一般来说你可能只需要看 COMMIT 语句的前一条 SQL 查询 plan: 执行计划 - rocksdb_delete_skipped_count: RocksDB 已删除 Key 扫描数 - rocksdb_delete_skipped_count_tooltip: RocksDB 扫数据时遇到的已删除 (tombstone) Key 数量 (delete_skipped_count) - rocksdb_key_skipped_count: RocksDB Key 扫描数 - rocksdb_key_skipped_count_tooltip: RocksDB 扫数据时所有遇到的 Key 数量 (key_skipped_count) - rocksdb_block_cache_hit_count: RocksDB 缓存读次数 - rocksdb_block_cache_hit_count_tooltip: RocksDB 从 Block Cache 缓存中读数据的次数 (block_cache_hit_count) - rocksdb_block_read_count: RocksDB 文件系统读次数 - rocksdb_block_read_count_tooltip: RocksDB 从文件系统中读数据的次数 (block_read_count) - rocksdb_block_read_byte: RocksDB 文件系统读数据量 - rocksdb_block_read_byte_tooltip: RocksDB 从文件系统中读数据的数据量 (block_read_byte) avg_rocksdb_delete_skipped_count: RocksDB 已删除 Key 平均扫描数 + avg_rocksdb_delete_skipped_count_tooltip: RocksDB 扫数据时遇到的已删除 (tombstone) Key 数量 (delete_skipped_count) max_rocksdb_delete_skipped_count: RocksDB 已删除 Key 最大扫描数 avg_rocksdb_key_skipped_count: RocksDB Key 平均扫描数 + avg_rocksdb_key_skipped_count_tooltip: RocksDB 扫数据时所有遇到的 Key 数量 (key_skipped_count) max_rocksdb_key_skipped_count: RocksDB Key 最大扫描数 avg_rocksdb_block_cache_hit_count: RocksDB 缓存平均读次数 + avg_rocksdb_block_cache_hit_count_tooltip: RocksDB 从 Block Cache 缓存中读数据的次数 (block_cache_hit_count) max_rocksdb_block_cache_hit_count: RocksDB 缓存最大读次数 avg_rocksdb_block_read_count: RocksDB 文件系统平均读次数 + avg_rocksdb_block_read_count_tooltip: RocksDB 从文件系统中读数据的次数 (block_read_count) max_rocksdb_block_read_count: RocksDB 文件系统最大读次数 avg_rocksdb_block_read_byte: RocksDB 文件系统平均读数据量 + avg_rocksdb_block_read_byte_tooltip: RocksDB 从文件系统中读数据的数据量 (block_read_byte) max_rocksdb_block_read_byte: RocksDB 文件系统最大读数据量 diff --git a/ui/lib/apps/Statement/utils/tableColumns.tsx b/ui/lib/apps/Statement/utils/tableColumns.tsx index 3ccda87430..8b05168a38 100644 --- a/ui/lib/apps/Statement/utils/tableColumns.tsx +++ b/ui/lib/apps/Statement/utils/tableColumns.tsx @@ -77,23 +77,23 @@ export const derivedFields = { avg_disk: genDerivedBarSources('avg_disk', 'max_disk'), sum_errors: ['sum_errors', 'sum_warnings'], related_schemas: ['table_names'], - rocksdb_delete_skipped_count: genDerivedBarSources( + avg_rocksdb_delete_skipped_count: genDerivedBarSources( 'avg_rocksdb_delete_skipped_count', 'max_rocksdb_delete_skipped_count' ), - rocksdb_key_skipped_count: genDerivedBarSources( + avg_rocksdb_key_skipped_count: genDerivedBarSources( 'avg_rocksdb_key_skipped_count', 'max_rocksdb_key_skipped_count' ), - rocksdb_block_cache_hit_count: genDerivedBarSources( + avg_rocksdb_block_cache_hit_count: genDerivedBarSources( 'avg_rocksdb_block_cache_hit_count', 'max_rocksdb_block_cache_hit_count' ), - rocksdb_block_read_count: genDerivedBarSources( + avg_rocksdb_block_read_count: genDerivedBarSources( 'avg_rocksdb_block_read_count', 'max_rocksdb_block_read_count' ), - rocksdb_block_read_byte: genDerivedBarSources( + avg_rocksdb_block_read_byte: genDerivedBarSources( 'avg_rocksdb_block_read_byte', 'max_rocksdb_block_read_byte' ), @@ -232,34 +232,46 @@ export function statementColumns( // rocksdb avgMaxColumn( tcf, - 'rocksdb_delete_skipped_count', + 'avg_rocksdb_delete_skipped_count', 'short', rows ).patchConfig({ minWidth: 220, maxWidth: 250, }), - avgMaxColumn(tcf, 'rocksdb_key_skipped_count', 'short', rows).patchConfig({ - minWidth: 220, - maxWidth: 250, - }), avgMaxColumn( tcf, - 'rocksdb_block_cache_hit_count', + 'avg_rocksdb_key_skipped_count', 'short', rows ).patchConfig({ minWidth: 220, maxWidth: 250, }), - avgMaxColumn(tcf, 'rocksdb_block_read_count', 'short', rows).patchConfig({ + avgMaxColumn( + tcf, + 'avg_rocksdb_block_cache_hit_count', + 'short', + rows + ).patchConfig({ minWidth: 220, maxWidth: 250, }), - avgMaxColumn(tcf, 'rocksdb_block_read_byte', 'short', rows).patchConfig({ + avgMaxColumn( + tcf, + 'avg_rocksdb_block_read_count', + 'short', + rows + ).patchConfig({ minWidth: 220, maxWidth: 250, }), + avgMaxColumn(tcf, 'avg_rocksdb_block_read_byte', 'short', rows).patchConfig( + { + minWidth: 220, + maxWidth: 250, + } + ), ]) } From 12230deca0d4d00618c18e334fc9307b6ecb3204 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Mon, 26 Apr 2021 11:21:07 +0800 Subject: [PATCH 4/7] fix(ui): unit of rocksdb_block_read_byte --- .../SlowQuery/pages/Detail/DetailTabCopr.tsx | 18 +++++++++-- .../pages/Detail/PlanDetailTabCopr.tsx | 20 ++++++++++-- ui/lib/apps/Statement/utils/tableColumns.tsx | 2 +- .../ShortValueWithTooltip/index.tsx | 19 ----------- ui/lib/components/ValueWithTooltip/index.tsx | 32 +++++++++++++++++++ ui/lib/components/index.ts | 7 ++-- 6 files changed, 71 insertions(+), 27 deletions(-) delete mode 100644 ui/lib/components/ShortValueWithTooltip/index.tsx create mode 100644 ui/lib/components/ValueWithTooltip/index.tsx diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx index 3eebbc355c..cd8826404d 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx @@ -1,7 +1,11 @@ import React from 'react' import { SlowqueryModel } from '@lib/client' -import { CardTable, ShortValueWithTooltip } from '@lib/components' +import { + CardTable, + ShortValueWithTooltip, + ScaledBytesWithTooltip, +} from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' export interface ITabCoprProps { @@ -22,7 +26,7 @@ export default function TabCopr({ data }: ITabCoprProps) { value: data.cop_wait_addr, }, genShortValueTooltipValueItem(data, 'rocksdb_block_cache_hit_count'), - genShortValueTooltipValueItem(data, 'rocksdb_block_read_byte'), + genScaledBytesTooltipValueItem(data, 'rocksdb_block_read_byte'), genShortValueTooltipValueItem(data, 'rocksdb_block_read_count'), genShortValueTooltipValueItem(data, 'rocksdb_delete_skipped_count'), genShortValueTooltipValueItem(data, 'rocksdb_key_skipped_count'), @@ -43,3 +47,13 @@ function genShortValueTooltipValueItem( value: , } } + +function genScaledBytesTooltipValueItem( + data: SlowqueryModel, + key: keyof SlowqueryModel +) { + return { + key, + value: , + } +} diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx index d30c95b1ad..f23db8955b 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx @@ -1,7 +1,11 @@ import React from 'react' import { StatementModel } from '@lib/client' -import { CardTable, ShortValueWithTooltip } from '@lib/components' +import { + CardTable, + ShortValueWithTooltip, + ScaledBytesWithTooltip, +} from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' import { useSchemaColumns } from '../../utils/useSchemaColumns' @@ -21,8 +25,8 @@ export default function TabCopr({ data }: ITabCoprProps) { genShortValueTooltipValueItem(data, 'max_total_keys'), genShortValueTooltipValueItem(data, 'avg_rocksdb_block_cache_hit_count'), genShortValueTooltipValueItem(data, 'max_rocksdb_block_cache_hit_count'), - genShortValueTooltipValueItem(data, 'avg_rocksdb_block_read_byte'), - genShortValueTooltipValueItem(data, 'max_rocksdb_block_read_byte'), + genScaledBytesTooltipValueItem(data, 'avg_rocksdb_block_read_byte'), + genScaledBytesTooltipValueItem(data, 'max_rocksdb_block_read_byte'), genShortValueTooltipValueItem(data, 'avg_rocksdb_block_read_count'), genShortValueTooltipValueItem(data, 'max_rocksdb_block_read_count'), genShortValueTooltipValueItem(data, 'avg_rocksdb_delete_skipped_count'), @@ -46,3 +50,13 @@ function genShortValueTooltipValueItem( value: , } } + +function genScaledBytesTooltipValueItem( + data: StatementModel, + key: keyof StatementModel +) { + return { + key, + value: , + } +} diff --git a/ui/lib/apps/Statement/utils/tableColumns.tsx b/ui/lib/apps/Statement/utils/tableColumns.tsx index 8b05168a38..e5846be28a 100644 --- a/ui/lib/apps/Statement/utils/tableColumns.tsx +++ b/ui/lib/apps/Statement/utils/tableColumns.tsx @@ -266,7 +266,7 @@ export function statementColumns( minWidth: 220, maxWidth: 250, }), - avgMaxColumn(tcf, 'avg_rocksdb_block_read_byte', 'short', rows).patchConfig( + avgMaxColumn(tcf, 'avg_rocksdb_block_read_byte', 'bytes', rows).patchConfig( { minWidth: 220, maxWidth: 250, diff --git a/ui/lib/components/ShortValueWithTooltip/index.tsx b/ui/lib/components/ShortValueWithTooltip/index.tsx deleted file mode 100644 index 30c1d456f1..0000000000 --- a/ui/lib/components/ShortValueWithTooltip/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import { Tooltip } from 'antd' -import { getValueFormat } from '@baurine/grafana-value-formats' - -export interface IShortValueWithTooltipProps { - value?: number - scaledDecimal?: number -} - -export default function ShortValueWithTooltip({ - value = 0, - scaledDecimal = 1, -}: IShortValueWithTooltipProps) { - return ( - - {getValueFormat('short')(value || 0, 0, scaledDecimal)} - - ) -} diff --git a/ui/lib/components/ValueWithTooltip/index.tsx b/ui/lib/components/ValueWithTooltip/index.tsx new file mode 100644 index 0000000000..3cc0ba051e --- /dev/null +++ b/ui/lib/components/ValueWithTooltip/index.tsx @@ -0,0 +1,32 @@ +import React from 'react' +import { Tooltip } from 'antd' +import { getValueFormat, scaledUnits } from '@baurine/grafana-value-formats' + +export interface IValueWithTooltipProps { + value?: number + scaledDecimal?: number +} + +export default function ShortValueWithTooltip({ + value = 0, + scaledDecimal = 1, +}: IValueWithTooltipProps) { + return ( + + {getValueFormat('short')(value || 0, 0, scaledDecimal)} + + ) +} + +const bytesScaler = scaledUnits(1024, ['', 'K', 'M', 'B', 'T']) + +export function ScaledBytesWithTooltip({ + value = 0, + scaledDecimal = 2, +}: IValueWithTooltipProps) { + return ( + + {bytesScaler(value || 0, 0, scaledDecimal)} + + ) +} diff --git a/ui/lib/components/index.ts b/ui/lib/components/index.ts index d5b58766fd..3288a49ffd 100644 --- a/ui/lib/components/index.ts +++ b/ui/lib/components/index.ts @@ -44,8 +44,11 @@ export * from './InstanceSelect' export { default as InstanceSelect } from './InstanceSelect' export * from './MultiSelect' export { default as MultiSelect } from './MultiSelect' -export * from './ShortValueWithTooltip' -export { default as ShortValueWithTooltip } from './ShortValueWithTooltip' +export * from './ValueWithTooltip' +export { + default as ShortValueWithTooltip, + ScaledBytesWithTooltip, +} from './ValueWithTooltip' export * from './DatePicker' export { default as DatePicker } from './DatePicker' export * from './ErrorBar' From bd57af958ff11164a6fc10d7149053acb15c4ea3 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Tue, 27 Apr 2021 22:06:30 +0800 Subject: [PATCH 5/7] refactor(ui): slowquery & stmt detail page --- .../SlowQuery/pages/Detail/DetailTabCopr.tsx | 78 ++++++----- .../SlowQuery/pages/Detail/DetailTabTxn.tsx | 8 +- .../pages/Detail/PlanDetailTabBasic.tsx | 8 +- .../pages/Detail/PlanDetailTabCopr.tsx | 125 ++++++++++++------ .../pages/Detail/PlanDetailTabTxn.tsx | 18 +-- ui/lib/components/ValueWithTooltip/index.tsx | 29 +++- ui/lib/components/index.ts | 4 - 7 files changed, 172 insertions(+), 98 deletions(-) diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx index cd8826404d..597c33e0f9 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx @@ -1,22 +1,30 @@ import React from 'react' import { SlowqueryModel } from '@lib/client' -import { - CardTable, - ShortValueWithTooltip, - ScaledBytesWithTooltip, -} from '@lib/components' +import { CardTable, ValueWithTooltip } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' +import { useSchemaColumns } from '../../utils/useSchemaColumns' export interface ITabCoprProps { data: SlowqueryModel } export default function TabCopr({ data }: ITabCoprProps) { + const { schemaColumns } = useSchemaColumns() + const columnsSet = new Set(schemaColumns) const items = [ - genShortValueTooltipValueItem(data, 'request_count'), - genShortValueTooltipValueItem(data, 'process_keys'), - genShortValueTooltipValueItem(data, 'total_keys'), + { + key: 'request_count', + value: , + }, + { + key: 'process_keys', + value: , + }, + { + key: 'total_keys', + value: , + }, { key: 'cop_proc_addr', value: data.cop_proc_addr, @@ -25,35 +33,35 @@ export default function TabCopr({ data }: ITabCoprProps) { key: 'cop_wait_addr', value: data.cop_wait_addr, }, - genShortValueTooltipValueItem(data, 'rocksdb_block_cache_hit_count'), - genScaledBytesTooltipValueItem(data, 'rocksdb_block_read_byte'), - genShortValueTooltipValueItem(data, 'rocksdb_block_read_count'), - genShortValueTooltipValueItem(data, 'rocksdb_delete_skipped_count'), - genShortValueTooltipValueItem(data, 'rocksdb_key_skipped_count'), - ] + { + key: 'rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'rocksdb_block_read_count', + value: , + }, + { + key: 'rocksdb_delete_skipped_count', + value: ( + + ), + }, + { + key: 'rocksdb_key_skipped_count', + value: , + }, + ].filter((item) => columnsSet.has(item.key)) const columns = valueColumns('slow_query.fields.') return ( ) } - -// TODO: refactor items code gen for all DetailsList -function genShortValueTooltipValueItem( - data: SlowqueryModel, - key: keyof SlowqueryModel -) { - return { - key, - value: , - } -} - -function genScaledBytesTooltipValueItem( - data: SlowqueryModel, - key: keyof SlowqueryModel -) { - return { - key, - value: , - } -} diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx index a34ac9b497..0aa19a13d6 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx @@ -2,7 +2,7 @@ import React from 'react' import { getValueFormat } from '@baurine/grafana-value-formats' import { SlowqueryModel } from '@lib/client' -import { CardTable, ShortValueWithTooltip } from '@lib/components' +import { CardTable, ValueWithTooltip } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' export interface ITabTxnProps { @@ -17,7 +17,7 @@ export default function TabCopr({ data }: ITabTxnProps) { }, { key: 'write_keys', - value: , + value: , }, { key: 'write_size', @@ -25,11 +25,11 @@ export default function TabCopr({ data }: ITabTxnProps) { }, { key: 'prewrite_region', - value: , + value: , }, { key: 'txn_retry', - value: , + value: , }, ] const columns = valueColumns('slow_query.fields.') diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx index f4a11813a9..5015da44d9 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx @@ -7,7 +7,7 @@ import { CardTable, DateTime, Pre, - ShortValueWithTooltip, + ValueWithTooltip, TextWrap, } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' @@ -43,7 +43,7 @@ export default function TabBasic({ data }: ITabBasicProps) { }, { key: 'exec_count', - value: , + value: , }, { key: 'sum_latency', @@ -52,11 +52,11 @@ export default function TabBasic({ data }: ITabBasicProps) { { key: 'sample_user', value: data.sample_user }, { key: 'sum_errors', - value: , + value: , }, { key: 'sum_warnings', - value: , + value: , }, { key: 'avg_mem', diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx index f23db8955b..12d510f41c 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx @@ -1,11 +1,7 @@ import React from 'react' import { StatementModel } from '@lib/client' -import { - CardTable, - ShortValueWithTooltip, - ScaledBytesWithTooltip, -} from '@lib/components' +import { CardTable, ValueWithTooltip } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' import { useSchemaColumns } from '../../utils/useSchemaColumns' @@ -19,44 +15,93 @@ export default function TabCopr({ data }: ITabCoprProps) { const columnsSet = new Set(schemaColumns) const items = [ { key: 'sum_cop_task_num', value: data.sum_cop_task_num }, - genShortValueTooltipValueItem(data, 'avg_processed_keys'), - genShortValueTooltipValueItem(data, 'max_processed_keys'), - genShortValueTooltipValueItem(data, 'avg_total_keys'), - genShortValueTooltipValueItem(data, 'max_total_keys'), - genShortValueTooltipValueItem(data, 'avg_rocksdb_block_cache_hit_count'), - genShortValueTooltipValueItem(data, 'max_rocksdb_block_cache_hit_count'), - genScaledBytesTooltipValueItem(data, 'avg_rocksdb_block_read_byte'), - genScaledBytesTooltipValueItem(data, 'max_rocksdb_block_read_byte'), - genShortValueTooltipValueItem(data, 'avg_rocksdb_block_read_count'), - genShortValueTooltipValueItem(data, 'max_rocksdb_block_read_count'), - genShortValueTooltipValueItem(data, 'avg_rocksdb_delete_skipped_count'), - genShortValueTooltipValueItem(data, 'max_rocksdb_delete_skipped_count'), - genShortValueTooltipValueItem(data, 'avg_rocksdb_key_skipped_count'), - genShortValueTooltipValueItem(data, 'max_rocksdb_key_skipped_count'), + { + key: 'avg_processed_keys', + value: , + }, + { + key: 'max_processed_keys', + value: , + }, + { + key: 'avg_total_keys', + value: , + }, + { + key: 'max_total_keys', + value: , + }, + { + key: 'avg_rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'avg_rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'max_rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'avg_rocksdb_block_read_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_block_read_count', + value: ( + + ), + }, + { + key: 'avg_rocksdb_delete_skipped_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_delete_skipped_count', + value: ( + + ), + }, + { + key: 'avg_rocksdb_key_skipped_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_key_skipped_count', + value: ( + + ), + }, ].filter((item) => columnsSet.has(item.key)) const columns = valueColumns('statement.fields.') return ( ) } - -// TODO: refactor items code gen for all DetailsList -function genShortValueTooltipValueItem( - data: StatementModel, - key: keyof StatementModel -) { - return { - key, - value: , - } -} - -function genScaledBytesTooltipValueItem( - data: StatementModel, - key: keyof StatementModel -) { - return { - key, - value: , - } -} diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx index adbc249335..4d1795dcdf 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx @@ -2,7 +2,7 @@ import React from 'react' import { getValueFormat } from '@baurine/grafana-value-formats' import { StatementModel } from '@lib/client' -import { CardTable, ShortValueWithTooltip } from '@lib/components' +import { CardTable, ValueWithTooltip } from '@lib/components' import { valueColumns } from '@lib/utils/tableColumns' export interface ITabTxnProps { @@ -13,19 +13,19 @@ export default function TabCopr({ data }: ITabTxnProps) { const items = [ { key: 'avg_affected_rows', - value: , + value: , }, { key: 'sum_backoff_times', - value: , + value: , }, { key: 'avg_write_keys', - value: , + value: , }, { key: 'max_write_keys', - value: , + value: , }, { key: 'avg_write_size', @@ -37,19 +37,19 @@ export default function TabCopr({ data }: ITabTxnProps) { }, { key: 'avg_prewrite_regions', - value: , + value: , }, { key: 'max_prewrite_regions', - value: , + value: , }, { key: 'avg_txn_retry', - value: , + value: , }, { key: 'max_txn_retry', - value: , + value: , }, ] const columns = valueColumns('statement.fields.') diff --git a/ui/lib/components/ValueWithTooltip/index.tsx b/ui/lib/components/ValueWithTooltip/index.tsx index 3cc0ba051e..013d860f74 100644 --- a/ui/lib/components/ValueWithTooltip/index.tsx +++ b/ui/lib/components/ValueWithTooltip/index.tsx @@ -2,12 +2,30 @@ import React from 'react' import { Tooltip } from 'antd' import { getValueFormat, scaledUnits } from '@baurine/grafana-value-formats' +interface IValueWithTooltip extends IInternalValueWithTooltip { + Short: typeof ShortValueWithTooltip + ScaledBytes: typeof ScaledBytesWithTooltip +} + +interface IInternalValueWithTooltip { + title: string + value: any +} + +function InternalValueWithTooltip({ title, value }: IValueWithTooltip) { + return ( + + {value} + + ) +} + export interface IValueWithTooltipProps { value?: number scaledDecimal?: number } -export default function ShortValueWithTooltip({ +function ShortValueWithTooltip({ value = 0, scaledDecimal = 1, }: IValueWithTooltipProps) { @@ -20,7 +38,7 @@ export default function ShortValueWithTooltip({ const bytesScaler = scaledUnits(1024, ['', 'K', 'M', 'B', 'T']) -export function ScaledBytesWithTooltip({ +function ScaledBytesWithTooltip({ value = 0, scaledDecimal = 2, }: IValueWithTooltipProps) { @@ -30,3 +48,10 @@ export function ScaledBytesWithTooltip({ ) } + +const ValueWithTooltip = (InternalValueWithTooltip as unknown) as IValueWithTooltip + +ValueWithTooltip.Short = ShortValueWithTooltip +ValueWithTooltip.ScaledBytes = ScaledBytesWithTooltip + +export { ValueWithTooltip } diff --git a/ui/lib/components/index.ts b/ui/lib/components/index.ts index 3288a49ffd..174a34e264 100644 --- a/ui/lib/components/index.ts +++ b/ui/lib/components/index.ts @@ -45,10 +45,6 @@ export { default as InstanceSelect } from './InstanceSelect' export * from './MultiSelect' export { default as MultiSelect } from './MultiSelect' export * from './ValueWithTooltip' -export { - default as ShortValueWithTooltip, - ScaledBytesWithTooltip, -} from './ValueWithTooltip' export * from './DatePicker' export { default as DatePicker } from './DatePicker' export * from './ErrorBar' From 61b9a2f3d3678d72861165f86af69a95ed8ff655 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Tue, 27 Apr 2021 22:08:55 +0800 Subject: [PATCH 6/7] refine(ui): api cache by ahooks useRequest --- .../apps/SlowQuery/utils/useSchemaColumns.ts | 21 +++++----- .../apps/Statement/utils/useSchemaColumns.ts | 21 +++++----- ui/lib/utils/callableCache.ts | 39 ------------------- 3 files changed, 22 insertions(+), 59 deletions(-) delete mode 100644 ui/lib/utils/callableCache.ts diff --git a/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts index 32b2e727d6..1a345e256d 100644 --- a/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts +++ b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts @@ -1,28 +1,29 @@ import { useState, useEffect } from 'react' +import { useRequest } from 'ahooks' import client from '@lib/client' -import { cache } from '@lib/utils/callableCache' const slowQueryTableColumnsGet = client .getInstance() .slowQueryTableColumnsGet.bind(client.getInstance()) export const useSchemaColumns = () => { - const [isLoading, setLoading] = useState(true) const [schemaColumns, setSchemaColumns] = useState([]) + const { data: resp, loading } = useRequest(slowQueryTableColumnsGet, { + cacheKey: 'slowquery_schema', + staleTime: 300000, + }) useEffect(() => { - const fetchSchemaColumns = async () => { - const { data } = await cache(slowQueryTableColumnsGet).call() - setSchemaColumns(data.map((d) => d.toLowerCase())) - setLoading(false) + if (!resp) { + return } - - fetchSchemaColumns() - }, []) + const { data } = resp + setSchemaColumns(data.map((d) => d.toLowerCase())) + }, [resp]) return { schemaColumns, - isLoading, + isLoading: loading, } } diff --git a/ui/lib/apps/Statement/utils/useSchemaColumns.ts b/ui/lib/apps/Statement/utils/useSchemaColumns.ts index 8301c030ae..0353e37251 100644 --- a/ui/lib/apps/Statement/utils/useSchemaColumns.ts +++ b/ui/lib/apps/Statement/utils/useSchemaColumns.ts @@ -1,28 +1,29 @@ import { useEffect, useState } from 'react' +import { useRequest } from 'ahooks' import client from '@lib/client' -import { cache } from '@lib/utils/callableCache' const statementsTableColumnsGet = client .getInstance() .statementsTableColumnsGet.bind(client.getInstance()) export const useSchemaColumns = () => { - const [isLoading, setLoading] = useState(true) const [schemaColumns, setSchemaColumns] = useState([]) + const { data: resp, loading } = useRequest(statementsTableColumnsGet, { + cacheKey: 'stmt_schema', + staleTime: 300000, + }) useEffect(() => { - const fetchSchemaColumns = async () => { - const { data } = await cache(statementsTableColumnsGet).call() - setSchemaColumns(data.map((d) => d.toLowerCase())) - setLoading(false) + if (!resp) { + return } - - fetchSchemaColumns() - }, []) + const { data } = resp + setSchemaColumns(data.map((d) => d.toLowerCase())) + }, [resp]) return { schemaColumns, - isLoading, + isLoading: loading, } } diff --git a/ui/lib/utils/callableCache.ts b/ui/lib/utils/callableCache.ts deleted file mode 100644 index 70595e89e6..0000000000 --- a/ui/lib/utils/callableCache.ts +++ /dev/null @@ -1,39 +0,0 @@ -interface Cacheable { - call: Fn - clear: () => void -} - -const cacheMap = new Map() - -/** - * function someFunction() { - * return Date.now() - * } - * const cachedSomeFunction = cache(someFunction) - * - * cachedSomeFunction.call() // e.g. 12345 - * cachedSomeFunction.call() // 12345 - * - * cachedSomeFunction.clear() - * - * cachedSomeFunction.call() // e.g. 12346 - */ -export const cache = (fn: Fn): Cacheable => { - const call: any = (...args: any[]) => { - if (cacheMap.has(fn)) { - return cacheMap.get(fn) - } - const rst = fn(...args) - cacheMap.set(fn, rst) - return rst - } - - const clear = () => { - cacheMap.delete(fn) - } - - return { - call, - clear, - } -} From 54261c4773ecdb1c80c6fd90ebc64c4ed40c1c21 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Wed, 28 Apr 2021 19:33:08 +0800 Subject: [PATCH 7/7] refine(ui): detail tabs --- .../SlowQuery/pages/Detail/DetailTabBasic.tsx | 67 +++---- .../SlowQuery/pages/Detail/DetailTabCopr.tsx | 110 +++++------ .../SlowQuery/pages/Detail/DetailTabTime.tsx | 17 +- .../SlowQuery/pages/Detail/DetailTabTxn.tsx | 57 +++--- .../SlowQuery/pages/Detail/DetailTabs.tsx | 88 +++++++++ ui/lib/apps/SlowQuery/pages/Detail/index.tsx | 32 +--- .../apps/SlowQuery/utils/useSchemaColumns.ts | 18 +- .../Statement/pages/Detail/PlanDetail.tsx | 39 +--- .../pages/Detail/PlanDetailTabBasic.tsx | 135 ++++++------- .../pages/Detail/PlanDetailTabCopr.tsx | 179 ++++++++---------- .../pages/Detail/PlanDetailTabTime.tsx | 143 +++++++------- .../pages/Detail/PlanDetailTabTxn.tsx | 97 +++++----- .../Statement/pages/Detail/PlanDetailTabs.tsx | 100 ++++++++++ .../apps/Statement/utils/useSchemaColumns.ts | 18 +- 14 files changed, 548 insertions(+), 552 deletions(-) create mode 100644 ui/lib/apps/SlowQuery/pages/Detail/DetailTabs.tsx create mode 100644 ui/lib/apps/Statement/pages/Detail/PlanDetailTabs.tsx diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabBasic.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabBasic.tsx index ede4cb72b0..b5fdfa225f 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabBasic.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabBasic.tsx @@ -1,45 +1,30 @@ import React from 'react' import { SlowqueryModel } from '@lib/client' -import { CardTable, DateTime } from '@lib/components' +import { DateTime } from '@lib/components' import { getValueFormat } from '@baurine/grafana-value-formats' -import { valueColumns } from '@lib/utils/tableColumns' -export interface ITabBasicProps { - data: SlowqueryModel -} - -export default function TabBasic({ data }: ITabBasicProps) { - // Here it is fine to not use useMemo() to cache data, - // because the detail data won't be refreshed after loaded - const items = [ - { - key: 'timestamp', - value: ( - - ), - }, - { key: 'digest', value: data.digest }, - { key: 'is_internal', value: data.is_internal }, - { key: 'is_success', value: data.success }, - { key: 'db', value: data.db }, - { key: 'index_names', value: data.index_names }, - { key: 'stats', value: data.stats }, - { key: 'backoff_types', value: data.backoff_types }, - { - key: 'memory_max', - value: getValueFormat('bytes')(data.memory_max || 0, 1), - }, - { - key: 'disk_max', - value: getValueFormat('bytes')(data.disk_max || 0, 1), - }, - { key: 'instance', value: data.instance }, - { key: 'connection_id', value: data.connection_id }, - { key: 'user', value: data.user }, - { key: 'host', value: data.host }, - ] - const columns = valueColumns('slow_query.fields.') - return ( - - ) -} +export const tabBasicItems = (data: SlowqueryModel) => [ + { + key: 'timestamp', + value: , + }, + { key: 'digest', value: data.digest }, + { key: 'is_internal', value: data.is_internal }, + { key: 'is_success', value: data.success }, + { key: 'db', value: data.db }, + { key: 'index_names', value: data.index_names }, + { key: 'stats', value: data.stats }, + { key: 'backoff_types', value: data.backoff_types }, + { + key: 'memory_max', + value: getValueFormat('bytes')(data.memory_max || 0, 1), + }, + { + key: 'disk_max', + value: getValueFormat('bytes')(data.disk_max || 0, 1), + }, + { key: 'instance', value: data.instance }, + { key: 'connection_id', value: data.connection_id }, + { key: 'user', value: data.user }, + { key: 'host', value: data.host }, +] diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx index 597c33e0f9..ff338f5164 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabCopr.tsx @@ -1,67 +1,51 @@ import React from 'react' import { SlowqueryModel } from '@lib/client' -import { CardTable, ValueWithTooltip } from '@lib/components' -import { valueColumns } from '@lib/utils/tableColumns' -import { useSchemaColumns } from '../../utils/useSchemaColumns' +import { ValueWithTooltip } from '@lib/components' -export interface ITabCoprProps { - data: SlowqueryModel -} - -export default function TabCopr({ data }: ITabCoprProps) { - const { schemaColumns } = useSchemaColumns() - const columnsSet = new Set(schemaColumns) - const items = [ - { - key: 'request_count', - value: , - }, - { - key: 'process_keys', - value: , - }, - { - key: 'total_keys', - value: , - }, - { - key: 'cop_proc_addr', - value: data.cop_proc_addr, - }, - { - key: 'cop_wait_addr', - value: data.cop_wait_addr, - }, - { - key: 'rocksdb_block_cache_hit_count', - value: ( - - ), - }, - { - key: 'rocksdb_block_read_byte', - value: ( - - ), - }, - { - key: 'rocksdb_block_read_count', - value: , - }, - { - key: 'rocksdb_delete_skipped_count', - value: ( - - ), - }, - { - key: 'rocksdb_key_skipped_count', - value: , - }, - ].filter((item) => columnsSet.has(item.key)) - const columns = valueColumns('slow_query.fields.') - return ( - - ) -} +export const tabCoprItems = (data: SlowqueryModel) => [ + { + key: 'request_count', + value: , + }, + { + key: 'process_keys', + value: , + }, + { + key: 'total_keys', + value: , + }, + { + key: 'cop_proc_addr', + value: data.cop_proc_addr, + }, + { + key: 'cop_wait_addr', + value: data.cop_wait_addr, + }, + { + key: 'rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'rocksdb_block_read_count', + value: , + }, + { + key: 'rocksdb_delete_skipped_count', + value: , + }, + { + key: 'rocksdb_key_skipped_count', + value: , + }, +] diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTime.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTime.tsx index 1ed6af19ce..6379eac410 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTime.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTime.tsx @@ -1,17 +1,10 @@ import React from 'react' import { SlowqueryModel } from '@lib/client' -import { CardTable } from '@lib/components' -import { timeValueColumns } from '@lib/utils/tableColumns' -import { useTranslation } from 'react-i18next' import { Typography } from 'antd' +import { TFunction } from 'i18next' -export interface ITabTimeProps { - data: SlowqueryModel -} - -export default function TabBasic({ data }: ITabTimeProps) { - const { t } = useTranslation() - const items = [ +export const tabTimeItems = (data: SlowqueryModel, t: TFunction) => { + return [ { key: 'query_time2', keyDisplay: ( @@ -123,8 +116,4 @@ export default function TabBasic({ data }: ITabTimeProps) { indentLevel: 1, }, ] - const columns = timeValueColumns('slow_query.fields.', items) - return ( - - ) } diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx index 0aa19a13d6..880117c7ba 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabTxn.tsx @@ -2,38 +2,27 @@ import React from 'react' import { getValueFormat } from '@baurine/grafana-value-formats' import { SlowqueryModel } from '@lib/client' -import { CardTable, ValueWithTooltip } from '@lib/components' -import { valueColumns } from '@lib/utils/tableColumns' +import { ValueWithTooltip } from '@lib/components' -export interface ITabTxnProps { - data: SlowqueryModel -} - -export default function TabCopr({ data }: ITabTxnProps) { - const items = [ - { - key: 'txn_start_ts', - value: data.txn_start_ts, - }, - { - key: 'write_keys', - value: , - }, - { - key: 'write_size', - value: getValueFormat('bytes')(data.write_size || 0, 1), - }, - { - key: 'prewrite_region', - value: , - }, - { - key: 'txn_retry', - value: , - }, - ] - const columns = valueColumns('slow_query.fields.') - return ( - - ) -} +export const tabTxnItems = (data: SlowqueryModel) => [ + { + key: 'txn_start_ts', + value: data.txn_start_ts, + }, + { + key: 'write_keys', + value: , + }, + { + key: 'write_size', + value: getValueFormat('bytes')(data.write_size || 0, 1), + }, + { + key: 'prewrite_region', + value: , + }, + { + key: 'txn_retry', + value: , + }, +] diff --git a/ui/lib/apps/SlowQuery/pages/Detail/DetailTabs.tsx b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabs.tsx new file mode 100644 index 0000000000..3634d9bb39 --- /dev/null +++ b/ui/lib/apps/SlowQuery/pages/Detail/DetailTabs.tsx @@ -0,0 +1,88 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' + +import { SlowqueryModel } from '@lib/client' +import { valueColumns, timeValueColumns } from '@lib/utils/tableColumns' +import { CardTabs, CardTable } from '@lib/components' + +import { tabBasicItems } from './DetailTabBasic' +import { tabTimeItems } from './DetailTabTime' +import { tabCoprItems } from './DetailTabCopr' +import { tabTxnItems } from './DetailTabTxn' +import { useSchemaColumns } from '../../utils/useSchemaColumns' + +export default function DetailTabs({ data }: { data: SlowqueryModel }) { + const { t } = useTranslation() + const { schemaColumns } = useSchemaColumns() + const columnsSet = new Set(schemaColumns) + + const tabs = [ + { + key: 'basic', + title: t('slow_query.detail.tabs.basic'), + content: () => { + const items = tabBasicItems(data) + const columns = valueColumns('slow_query.fields.') + return ( + + ) + }, + }, + { + key: 'time', + title: t('slow_query.detail.tabs.time'), + content: () => { + const items = tabTimeItems(data, t) + const columns = timeValueColumns('slow_query.fields.', items) + return ( + + ) + }, + }, + { + key: 'copr', + title: t('slow_query.detail.tabs.copr'), + content: () => { + const items = tabCoprItems(data).filter((item) => + columnsSet.has(item.key) + ) + const columns = valueColumns('slow_query.fields.') + return ( + + ) + }, + }, + { + key: 'txn', + title: t('slow_query.detail.tabs.txn'), + content: () => { + const items = tabTxnItems(data) + const columns = valueColumns('slow_query.fields.') + return ( + + ) + }, + }, + ] + return +} diff --git a/ui/lib/apps/SlowQuery/pages/Detail/index.tsx b/ui/lib/apps/SlowQuery/pages/Detail/index.tsx index 0b913871da..a080e312a4 100644 --- a/ui/lib/apps/SlowQuery/pages/Detail/index.tsx +++ b/ui/lib/apps/SlowQuery/pages/Detail/index.tsx @@ -11,7 +11,6 @@ import { buildQueryFn, parseQueryFn } from '@lib/utils/query' import formatSql from '@lib/utils/sqlFormatter' import { AnimatedSkeleton, - CardTabs, CopyLink, Descriptions, ErrorBar, @@ -21,10 +20,8 @@ import { Pre, TextWithInfo, } from '@lib/components' -import TabBasic from './DetailTabBasic' -import TabTime from './DetailTabTime' -import TabCopr from './DetailTabCopr' -import TabTxn from './DetailTabTxn' + +import DetailTabs from './DetailTabs' export interface IPageQuery { connectId?: string @@ -66,29 +63,6 @@ function DetailPage() { const togglePlan = () => setDetailExpand((prev) => ({ ...prev, plan: !prev.plan })) - const tabs = [ - { - key: 'basic', - title: t('slow_query.detail.tabs.basic'), - content: () => , - }, - { - key: 'time', - title: t('slow_query.detail.tabs.time'), - content: () => , - }, - { - key: 'copr', - title: t('slow_query.detail.tabs.copr'), - content: () => , - }, - { - key: 'txn', - title: t('slow_query.detail.tabs.txn'), - content: () => , - }, - ] - return (
- + )} diff --git a/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts index 1a345e256d..ab61e0296f 100644 --- a/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts +++ b/ui/lib/apps/SlowQuery/utils/useSchemaColumns.ts @@ -1,29 +1,23 @@ import { useState, useEffect } from 'react' -import { useRequest } from 'ahooks' import client from '@lib/client' - -const slowQueryTableColumnsGet = client - .getInstance() - .slowQueryTableColumnsGet.bind(client.getInstance()) +import { useClientRequest } from '@lib/utils/useClientRequest' export const useSchemaColumns = () => { const [schemaColumns, setSchemaColumns] = useState([]) - const { data: resp, loading } = useRequest(slowQueryTableColumnsGet, { - cacheKey: 'slowquery_schema', - staleTime: 300000, + const { data, isLoading } = useClientRequest((options) => { + return client.getInstance().slowQueryTableColumnsGet(options) }) useEffect(() => { - if (!resp) { + if (!data) { return } - const { data } = resp setSchemaColumns(data.map((d) => d.toLowerCase())) - }, [resp]) + }, [data]) return { schemaColumns, - isLoading: loading, + isLoading, } } diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx index 1c2456ed7d..c4c1b41cd7 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetail.tsx @@ -5,7 +5,6 @@ import { useTranslation } from 'react-i18next' import { AnimatedSkeleton, Card, - CardTabs, CopyLink, Descriptions, ErrorBar, @@ -18,12 +17,8 @@ import { useClientRequest } from '@lib/utils/useClientRequest' import client from '@lib/client' import formatSql from '@lib/utils/sqlFormatter' -import { IPageQuery } from '.' -import TabBasic from './PlanDetailTabBasic' -import TabTime from './PlanDetailTabTime' -import TabCopr from './PlanDetailTabCopr' -import TabTxn from './PlanDetailTabTxn' -import SlowQueryTab from './SlowQueryTab' +import type { IPageQuery } from '.' +import DetailTabs from './PlanDetailTabs' import { useSchemaColumns } from '../../utils/useSchemaColumns' export interface IQuery extends IPageQuery { @@ -83,34 +78,6 @@ function PlanDetail({ query }: IPlanDetailProps) { titleKey = 'some' } - const tabs = [ - { - key: 'basic', - title: t('statement.pages.detail.tabs.basic'), - content: () => , - }, - { - key: 'time', - title: t('statement.pages.detail.tabs.time'), - content: () => , - }, - { - key: 'copr', - title: t('statement.pages.detail.tabs.copr'), - content: () => , - }, - { - key: 'txn', - title: t('statement.pages.detail.tabs.txn'), - content: () => , - }, - { - key: 'slow_query', - title: t('statement.pages.detail.tabs.slow_query'), - content: () => , - }, - ] - return ( - + )} diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx index 5015da44d9..b01dcc4ddf 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabBasic.tsx @@ -3,80 +3,63 @@ import React from 'react' import { getValueFormat } from '@baurine/grafana-value-formats' import { StatementModel } from '@lib/client' -import { - CardTable, - DateTime, - Pre, - ValueWithTooltip, - TextWrap, -} from '@lib/components' -import { valueColumns } from '@lib/utils/tableColumns' +import { DateTime, Pre, ValueWithTooltip, TextWrap } from '@lib/components' -export interface ITabBasicProps { - data: StatementModel -} - -export default function TabBasic({ data }: ITabBasicProps) { - const items = [ - { - key: 'table_names', - value: ( - - -
{data.table_names}
-
-
- ), - }, - { key: 'index_names', value: data.index_names }, - { - key: 'first_seen', - value: data.first_seen && ( - - ), - }, - { - key: 'last_seen', - value: data.last_seen && ( - - ), - }, - { - key: 'exec_count', - value: , - }, - { - key: 'sum_latency', - value: getValueFormat('ns')(data.sum_latency || 0, 1), - }, - { key: 'sample_user', value: data.sample_user }, - { - key: 'sum_errors', - value: , - }, - { - key: 'sum_warnings', - value: , - }, - { - key: 'avg_mem', - value: getValueFormat('bytes')(data.avg_mem || 0, 1), - }, - { - key: 'max_mem', - value: getValueFormat('bytes')(data.max_mem || 0, 1), - }, - { - key: 'avg_disk', - value: getValueFormat('bytes')(data.avg_disk || 0, 1), - }, - { - key: 'max_disk', - value: getValueFormat('bytes')(data.max_disk || 0, 1), - }, - ] - const columns = valueColumns('statement.fields.') - return ( - - ) -} +export const tabBasicItems = (data: StatementModel) => [ + { + key: 'table_names', + value: ( + + +
{data.table_names}
+
+
+ ), + }, + { key: 'index_names', value: data.index_names }, + { + key: 'first_seen', + value: data.first_seen && ( + + ), + }, + { + key: 'last_seen', + value: data.last_seen && ( + + ), + }, + { + key: 'exec_count', + value: , + }, + { + key: 'sum_latency', + value: getValueFormat('ns')(data.sum_latency || 0, 1), + }, + { key: 'sample_user', value: data.sample_user }, + { + key: 'sum_errors', + value: , + }, + { + key: 'sum_warnings', + value: , + }, + { + key: 'avg_mem', + value: getValueFormat('bytes')(data.avg_mem || 0, 1), + }, + { + key: 'max_mem', + value: getValueFormat('bytes')(data.max_mem || 0, 1), + }, + { + key: 'avg_disk', + value: getValueFormat('bytes')(data.avg_disk || 0, 1), + }, + { + key: 'max_disk', + value: getValueFormat('bytes')(data.max_disk || 0, 1), + }, +] diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx index 12d510f41c..2157258849 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabCopr.tsx @@ -1,107 +1,80 @@ import React from 'react' import { StatementModel } from '@lib/client' -import { CardTable, ValueWithTooltip } from '@lib/components' -import { valueColumns } from '@lib/utils/tableColumns' +import { ValueWithTooltip } from '@lib/components' -import { useSchemaColumns } from '../../utils/useSchemaColumns' - -export interface ITabCoprProps { - data: StatementModel -} - -export default function TabCopr({ data }: ITabCoprProps) { - const { schemaColumns } = useSchemaColumns() - const columnsSet = new Set(schemaColumns) - const items = [ - { key: 'sum_cop_task_num', value: data.sum_cop_task_num }, - { - key: 'avg_processed_keys', - value: , - }, - { - key: 'max_processed_keys', - value: , - }, - { - key: 'avg_total_keys', - value: , - }, - { - key: 'max_total_keys', - value: , - }, - { - key: 'avg_rocksdb_block_cache_hit_count', - value: ( - - ), - }, - { - key: 'max_rocksdb_block_cache_hit_count', - value: ( - - ), - }, - { - key: 'avg_rocksdb_block_read_byte', - value: ( - - ), - }, - { - key: 'max_rocksdb_block_read_byte', - value: ( - - ), - }, - { - key: 'avg_rocksdb_block_read_count', - value: ( - - ), - }, - { - key: 'max_rocksdb_block_read_count', - value: ( - - ), - }, - { - key: 'avg_rocksdb_delete_skipped_count', - value: ( - - ), - }, - { - key: 'max_rocksdb_delete_skipped_count', - value: ( - - ), - }, - { - key: 'avg_rocksdb_key_skipped_count', - value: ( - - ), - }, - { - key: 'max_rocksdb_key_skipped_count', - value: ( - - ), - }, - ].filter((item) => columnsSet.has(item.key)) - const columns = valueColumns('statement.fields.') - return ( - - ) -} +export const tabCoprItems = (data: StatementModel) => [ + { key: 'sum_cop_task_num', value: data.sum_cop_task_num }, + { + key: 'avg_processed_keys', + value: , + }, + { + key: 'max_processed_keys', + value: , + }, + { + key: 'avg_total_keys', + value: , + }, + { + key: 'max_total_keys', + value: , + }, + { + key: 'avg_rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_block_cache_hit_count', + value: ( + + ), + }, + { + key: 'avg_rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'max_rocksdb_block_read_byte', + value: ( + + ), + }, + { + key: 'avg_rocksdb_block_read_count', + value: , + }, + { + key: 'max_rocksdb_block_read_count', + value: , + }, + { + key: 'avg_rocksdb_delete_skipped_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_delete_skipped_count', + value: ( + + ), + }, + { + key: 'avg_rocksdb_key_skipped_count', + value: ( + + ), + }, + { + key: 'max_rocksdb_key_skipped_count', + value: ( + + ), + }, +] diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTime.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTime.tsx index 64060d5bb2..d644aed867 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTime.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTime.tsx @@ -1,82 +1,69 @@ import React from 'react' import { StatementModel } from '@lib/client' -import { CardTable } from '@lib/components' -import { timeValueColumns } from '@lib/utils/tableColumns' -import { useTranslation } from 'react-i18next' import { Typography } from 'antd' +import { TFunction } from 'i18next' -export interface ITabTimeProps { - data: StatementModel -} - -export default function TabBasic({ data }: ITabTimeProps) { - const { t } = useTranslation() - const items = [ - { - key: 'parse_latency', - avg: data.avg_parse_latency, - max: data.max_parse_latency, - }, - { - key: 'compile_latency', - avg: data.avg_compile_latency, - max: data.max_compile_latency, - }, - { key: 'wait_time', avg: data.avg_wait_time, max: data.max_wait_time }, - { - key: 'process_time', - avg: data.avg_process_time, - max: data.max_process_time, - }, - { - key: 'backoff_time', - avg: data.avg_backoff_time, - max: data.max_backoff_time, - }, - { - key: 'get_commit_ts_time', - avg: data.avg_get_commit_ts_time, - max: data.max_get_commit_ts_time, - }, - { - key: 'local_latch_wait_time', - avg: data.avg_local_latch_wait_time, - max: data.max_local_latch_wait_time, - }, - { - key: 'resolve_lock_time', - avg: data.avg_resolve_lock_time, - max: data.max_resolve_lock_time, - }, - { - key: 'prewrite_time', - avg: data.avg_prewrite_time, - max: data.max_prewrite_time, - }, - { - key: 'commit_time', - avg: data.avg_commit_time, - max: data.max_commit_time, - }, - { - key: 'commit_backoff_time', - avg: data.avg_commit_backoff_time, - max: data.max_commit_backoff_time, - }, - { - key: 'query_time2', - keyDisplay: ( - - {t('statement.fields.query_time2')} - - ), - avg: data.avg_latency, - min: data.min_latency, - max: data.max_latency, - }, - ] - const columns = timeValueColumns('statement.fields.', items) - return ( - - ) -} +export const tabTimeItems = (data: StatementModel, t: TFunction) => [ + { + key: 'parse_latency', + avg: data.avg_parse_latency, + max: data.max_parse_latency, + }, + { + key: 'compile_latency', + avg: data.avg_compile_latency, + max: data.max_compile_latency, + }, + { key: 'wait_time', avg: data.avg_wait_time, max: data.max_wait_time }, + { + key: 'process_time', + avg: data.avg_process_time, + max: data.max_process_time, + }, + { + key: 'backoff_time', + avg: data.avg_backoff_time, + max: data.max_backoff_time, + }, + { + key: 'get_commit_ts_time', + avg: data.avg_get_commit_ts_time, + max: data.max_get_commit_ts_time, + }, + { + key: 'local_latch_wait_time', + avg: data.avg_local_latch_wait_time, + max: data.max_local_latch_wait_time, + }, + { + key: 'resolve_lock_time', + avg: data.avg_resolve_lock_time, + max: data.max_resolve_lock_time, + }, + { + key: 'prewrite_time', + avg: data.avg_prewrite_time, + max: data.max_prewrite_time, + }, + { + key: 'commit_time', + avg: data.avg_commit_time, + max: data.max_commit_time, + }, + { + key: 'commit_backoff_time', + avg: data.avg_commit_backoff_time, + max: data.max_commit_backoff_time, + }, + { + key: 'query_time2', + keyDisplay: ( + + {t('statement.fields.query_time2')} + + ), + avg: data.avg_latency, + min: data.min_latency, + max: data.max_latency, + }, +] diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx index 4d1795dcdf..7c3fa41ddb 100644 --- a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabTxn.tsx @@ -2,58 +2,47 @@ import React from 'react' import { getValueFormat } from '@baurine/grafana-value-formats' import { StatementModel } from '@lib/client' -import { CardTable, ValueWithTooltip } from '@lib/components' -import { valueColumns } from '@lib/utils/tableColumns' +import { ValueWithTooltip } from '@lib/components' -export interface ITabTxnProps { - data: StatementModel -} - -export default function TabCopr({ data }: ITabTxnProps) { - const items = [ - { - key: 'avg_affected_rows', - value: , - }, - { - key: 'sum_backoff_times', - value: , - }, - { - key: 'avg_write_keys', - value: , - }, - { - key: 'max_write_keys', - value: , - }, - { - key: 'avg_write_size', - value: getValueFormat('bytes')(data.avg_write_size || 0, 1), - }, - { - key: 'max_write_size', - value: getValueFormat('bytes')(data.max_write_size || 0, 1), - }, - { - key: 'avg_prewrite_regions', - value: , - }, - { - key: 'max_prewrite_regions', - value: , - }, - { - key: 'avg_txn_retry', - value: , - }, - { - key: 'max_txn_retry', - value: , - }, - ] - const columns = valueColumns('statement.fields.') - return ( - - ) -} +export const tabTxnItems = (data: StatementModel) => [ + { + key: 'avg_affected_rows', + value: , + }, + { + key: 'sum_backoff_times', + value: , + }, + { + key: 'avg_write_keys', + value: , + }, + { + key: 'max_write_keys', + value: , + }, + { + key: 'avg_write_size', + value: getValueFormat('bytes')(data.avg_write_size || 0, 1), + }, + { + key: 'max_write_size', + value: getValueFormat('bytes')(data.max_write_size || 0, 1), + }, + { + key: 'avg_prewrite_regions', + value: , + }, + { + key: 'max_prewrite_regions', + value: , + }, + { + key: 'avg_txn_retry', + value: , + }, + { + key: 'max_txn_retry', + value: , + }, +] diff --git a/ui/lib/apps/Statement/pages/Detail/PlanDetailTabs.tsx b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabs.tsx new file mode 100644 index 0000000000..e9379db1ed --- /dev/null +++ b/ui/lib/apps/Statement/pages/Detail/PlanDetailTabs.tsx @@ -0,0 +1,100 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' +import { CardTable, CardTabs } from '@lib/components' +import { StatementModel } from '@lib/client' +import { valueColumns, timeValueColumns } from '@lib/utils/tableColumns' + +import { tabBasicItems } from './PlanDetailTabBasic' +import { tabTimeItems } from './PlanDetailTabTime' +import { tabCoprItems } from './PlanDetailTabCopr' +import { tabTxnItems } from './PlanDetailTabTxn' +import SlowQueryTab from './SlowQueryTab' +import { useSchemaColumns } from '../../utils/useSchemaColumns' +import type { IQuery } from './PlanDetail' + +export default function DetailTabs({ + data, + query, +}: { + data: StatementModel + query: IQuery +}) { + const { t } = useTranslation() + const { schemaColumns } = useSchemaColumns() + const columnsSet = new Set(schemaColumns) + + const tabs = [ + { + key: 'basic', + title: t('statement.pages.detail.tabs.basic'), + content: () => { + const items = tabBasicItems(data) + const columns = valueColumns('statement.fields.') + return ( + + ) + }, + }, + { + key: 'time', + title: t('statement.pages.detail.tabs.time'), + content: () => { + const items = tabTimeItems(data, t) + const columns = timeValueColumns('statement.fields.', items) + return ( + + ) + }, + }, + { + key: 'copr', + title: t('statement.pages.detail.tabs.copr'), + content: () => { + const items = tabCoprItems(data).filter((item) => + columnsSet.has(item.key) + ) + const columns = valueColumns('statement.fields.') + return ( + + ) + }, + }, + { + key: 'txn', + title: t('statement.pages.detail.tabs.txn'), + content: () => { + const items = tabTxnItems(data) + const columns = valueColumns('statement.fields.') + return ( + + ) + }, + }, + { + key: 'slow_query', + title: t('statement.pages.detail.tabs.slow_query'), + content: () => , + }, + ] + return +} diff --git a/ui/lib/apps/Statement/utils/useSchemaColumns.ts b/ui/lib/apps/Statement/utils/useSchemaColumns.ts index 0353e37251..67a0317f4b 100644 --- a/ui/lib/apps/Statement/utils/useSchemaColumns.ts +++ b/ui/lib/apps/Statement/utils/useSchemaColumns.ts @@ -1,29 +1,23 @@ import { useEffect, useState } from 'react' -import { useRequest } from 'ahooks' import client from '@lib/client' - -const statementsTableColumnsGet = client - .getInstance() - .statementsTableColumnsGet.bind(client.getInstance()) +import { useClientRequest } from '@lib/utils/useClientRequest' export const useSchemaColumns = () => { const [schemaColumns, setSchemaColumns] = useState([]) - const { data: resp, loading } = useRequest(statementsTableColumnsGet, { - cacheKey: 'stmt_schema', - staleTime: 300000, + const { data, isLoading } = useClientRequest((options) => { + return client.getInstance().statementsTableColumnsGet(options) }) useEffect(() => { - if (!resp) { + if (!data) { return } - const { data } = resp setSchemaColumns(data.map((d) => d.toLowerCase())) - }, [resp]) + }, [data]) return { schemaColumns, - isLoading: loading, + isLoading, } }