From e91003be6ccc61b149cf0648419bdf4377bc9481 Mon Sep 17 00:00:00 2001 From: Duyet Le Date: Sun, 3 Dec 2023 18:07:52 +0700 Subject: [PATCH 1/2] feat: colored-badge-format --- app/[query]/clickhouse-queries.ts | 94 ++++++++++++++++++- app/overview/page.tsx | 24 ++--- app/tables/page.tsx | 1 + components/data-table/cell.tsx | 4 + .../data-table/cells/colored-badge-format.tsx | 43 +++++++++ components/data-table/columns.tsx | 7 +- 6 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 components/data-table/cells/colored-badge-format.tsx diff --git a/app/[query]/clickhouse-queries.ts b/app/[query]/clickhouse-queries.ts index 90390bde..7f384d6d 100644 --- a/app/[query]/clickhouse-queries.ts +++ b/app/[query]/clickhouse-queries.ts @@ -109,11 +109,11 @@ export const queries: Array = [ `, columns: [ 'user', + 'type', 'query', 'event_time', 'query_id', 'query_duration', - 'user', 'readable_read_rows', 'readable_written_rows', 'readable_result_rows', @@ -122,7 +122,10 @@ export const queries: Array = [ 'client_name', ], columnFormats: { + user: ColumnFormat.ColoredBadge, + type: ColumnFormat.ColoredBadge, query_duration: ColumnFormat.Duration, + query_kind: ColumnFormat.ColoredBadge, readable_query: ColumnFormat.Code, query: ColumnFormat.Code, event_time: ColumnFormat.RelatedTime, @@ -139,6 +142,89 @@ export const queries: Array = [ ], ], }, + { + name: 'failed-queries', + sql: ` + SELECT + type, + query_start_time, + query_duration_ms, + query_id, + query_kind, + is_initial_query, + normalizeQuery(query) AS normalized_query, + concat(toString(read_rows), ' rows / ', formatReadableSize(read_bytes)) AS read, + concat(toString(written_rows), ' rows / ', formatReadableSize(written_bytes)) AS written, + concat(toString(result_rows), ' rows / ', formatReadableSize(result_bytes)) AS result, + formatReadableSize(memory_usage) AS memory_usage, + exception, + concat('\n', stack_trace) AS stack_trace, + user, + initial_user, + multiIf(empty(client_name), http_user_agent, concat(client_name, ' ', toString(client_version_major), '.', toString(client_version_minor), '.', toString(client_version_patch))) AS client, + client_hostname, + databases, + tables, + columns, + used_aggregate_functions, + used_aggregate_function_combinators, + used_database_engines, + used_data_type_families, + used_dictionaries, + used_formats, + used_functions, + used_storages, + used_table_functions, + thread_ids, + ProfileEvents, + Settings + FROM system.query_log + WHERE type IN ['3', '4'] + ORDER BY query_start_time DESC + LIMIT 100 + `, + columns: [ + 'type', + 'query_start_time', + 'query_duration_ms', + 'query_id', + 'query_kind', + 'is_initial_query', + 'normalized_query', + 'read', + 'written', + 'result', + 'memory usage', + 'exception', + 'stack_trace', + 'user', + 'initial_user', + 'client', + 'client_hostname', + 'databases', + 'tables', + 'columns', + 'used_aggregate_functions', + 'used_aggregate_function_combinators', + 'used_database_engines', + 'used_data_type_families', + 'used_dictionaries', + 'used_formats', + 'used_functions', + 'used_storages', + 'used_table_functions', + 'thread_ids', + ], + columnFormats: { + type: ColumnFormat.ColoredBadge, + query_duration_ms: ColumnFormat.Duration, + query_start_time: ColumnFormat.RelatedTime, + normalized_query: ColumnFormat.Code, + exception: ColumnFormat.Code, + stack_trace: ColumnFormat.Code, + client: ColumnFormat.Code, + }, + }, { name: 'expensive-queries', description: 'Most expensive queries finished over last 24 hours', @@ -276,6 +362,8 @@ export const queries: Array = [ 'merge_algorithm', ], columnFormats: { + database: ColumnFormat.ColoredBadge, + table: ColumnFormat.ColoredBadge, query: ColumnFormat.Code, elapsed: ColumnFormat.Duration, is_mutation: ColumnFormat.Boolean, @@ -344,6 +432,7 @@ export const queries: Array = [ readonly: ColumnFormat.Boolean, is_obsolete: ColumnFormat.Boolean, value: ColumnFormat.Code, + type: ColumnFormat.ColoredBadge, }, }, { @@ -371,6 +460,9 @@ export const queries: Array = [ 'readable_total_space', 'keep_free_space', ], + columnFormats: { + name: ColumnFormat.ColoredBadge, + }, relatedCharts: [ [ 'disks-usage', diff --git a/app/overview/page.tsx b/app/overview/page.tsx index 6a861503..60d2f9cc 100644 --- a/app/overview/page.tsx +++ b/app/overview/page.tsx @@ -20,9 +20,7 @@ export default async function Overview() {
Overview - - Disks - + Disks Settings @@ -57,20 +55,24 @@ export default async function Overview() { - +
+ + +
-
diff --git a/app/tables/page.tsx b/app/tables/page.tsx index 09c5cc12..cbe5857b 100644 --- a/app/tables/page.tsx +++ b/app/tables/page.tsx @@ -42,6 +42,7 @@ const config: QueryConfig = { columnFormats: { part_count: ColumnFormat.Number, table: [ColumnFormat.Link, { href: '/tables/[database]/[table]' }], + engine: ColumnFormat.ColoredBadge, }, } diff --git a/components/data-table/cell.tsx b/components/data-table/cell.tsx index 5f138ed1..d52fae5a 100644 --- a/components/data-table/cell.tsx +++ b/components/data-table/cell.tsx @@ -12,6 +12,7 @@ import type { Action } from './cells/actions/types' import { BadgeFormat } from './cells/badge-format' import { BooleanFormat } from './cells/boolean-format' import { CodeToggleFormat } from './cells/code-toggle-format' +import { ColoredBadgeFormat } from './cells/colored-badge-format' import { LinkFormat } from './cells/link-format' export const formatCell = ( @@ -21,6 +22,9 @@ export const formatCell = ( columnFormatOptions?: ColumnFormatOptions ) => { switch (format) { + case ColumnFormat.ColoredBadge: + return + case ColumnFormat.Code: return {value} diff --git a/components/data-table/cells/colored-badge-format.tsx b/components/data-table/cells/colored-badge-format.tsx new file mode 100644 index 00000000..be520034 --- /dev/null +++ b/components/data-table/cells/colored-badge-format.tsx @@ -0,0 +1,43 @@ +import { cn } from '@/lib/utils' + +interface ColoredBadgeFormatProps { + value: any + className?: string +} + +export function ColoredBadgeFormat({ + value, + className, +}: ColoredBadgeFormatProps) { + const colors = [ + 'bg-green-100 text-green-800', + 'bg-yellow-100 text-yellow-800', + 'bg-blue-100 text-blue-800', + 'bg-indigo-100 text-indigo-800', + 'bg-purple-100 text-purple-800', + 'bg-pink-100 text-pink-800', + ] + + // Picked consistently based on the value + const pickedColor = + colors[ + Math.abs( + value + .toString() + .split('') + .reduce((acc: string, char: string) => acc + char.charCodeAt(0), 0) + ) % colors.length + ] + + return ( + + {value} + + ) +} diff --git a/components/data-table/columns.tsx b/components/data-table/columns.tsx index b1e77d6c..a75524e8 100644 --- a/components/data-table/columns.tsx +++ b/components/data-table/columns.tsx @@ -12,15 +12,16 @@ import { formatCell } from '@/components/data-table/cell' import type { Action } from '@/components/data-table/cells/actions/types' export enum ColumnFormat { - Code = 'code', - Number = 'number', + ColoredBadge = 'colored-badge', + RelatedTime = 'related-time', NumberShort = 'number-short', CodeToggle = 'code-toggle', - RelatedTime = 'related-time', Duration = 'duration', Boolean = 'boolean', Action = 'action', + Number = 'number', Badge = 'badge', + Code = 'code', Link = 'link', None = 'none', } From 2d8358d4be13311288095b890e8e50e55d9c6be0 Mon Sep 17 00:00:00 2001 From: Duyet Le Date: Sun, 3 Dec 2023 18:24:48 +0700 Subject: [PATCH 2/2] feat: add common errors --- app/[query]/clickhouse-queries.ts | 31 +++++++++++++++++++ .../data-table/cells/colored-badge-format.tsx | 2 +- components/menu/menu-items-config.ts | 11 +++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/[query]/clickhouse-queries.ts b/app/[query]/clickhouse-queries.ts index 7f384d6d..d696afa3 100644 --- a/app/[query]/clickhouse-queries.ts +++ b/app/[query]/clickhouse-queries.ts @@ -225,6 +225,37 @@ export const queries: Array = [ client: ColumnFormat.Code, }, }, + { + name: 'common-errors', + description: + 'This table `system.errors` contains error codes and the number of times each error has been triggered. Furthermore, we can see when the error last occurred coupled with the exact error message', + sql: ` + SELECT + name, + code, + value, + last_error_time, + last_error_message, + last_error_trace AS remote + FROM system.errors + ORDER BY last_error_time DESC + LIMIT 1000 + `, + columns: [ + 'name', + 'code', + 'value', + 'last_error_time', + 'last_error_message', + 'remote', + ], + columnFormats: { + name: ColumnFormat.ColoredBadge, + code: ColumnFormat.ColoredBadge, + last_error_time: ColumnFormat.RelatedTime, + remote: ColumnFormat.Code, + }, + }, { name: 'expensive-queries', description: 'Most expensive queries finished over last 24 hours', diff --git a/components/data-table/cells/colored-badge-format.tsx b/components/data-table/cells/colored-badge-format.tsx index be520034..28418bdb 100644 --- a/components/data-table/cells/colored-badge-format.tsx +++ b/components/data-table/cells/colored-badge-format.tsx @@ -25,7 +25,7 @@ export function ColoredBadgeFormat({ value .toString() .split('') - .reduce((acc: string, char: string) => acc + char.charCodeAt(0), 0) + .reduce((acc: number, char: string) => acc + char.charCodeAt(0), 0) ) % colors.length ] diff --git a/components/menu/menu-items-config.ts b/components/menu/menu-items-config.ts index 322e2c85..2a21f839 100644 --- a/components/menu/menu-items-config.ts +++ b/components/menu/menu-items-config.ts @@ -24,6 +24,17 @@ export const menuItemsConfig: MenuItem[] = [ description: 'Queries that have been run including successed, failed queries with resourses usage details', }, + { + title: 'Failed Queries', + href: '/failed-queries', + description: 'Which queries have failed?', + }, + { + title: 'Latest Common Errors', + href: '/common-errors', + description: + 'Exploring the system.errors table to see when the error last occurred', + }, { title: 'Most Expensive Queries', href: '/expensive-queries',