diff --git a/packages/cluster-ui/package.json b/packages/cluster-ui/package.json index acf8b3426..b822f8d73 100644 --- a/packages/cluster-ui/package.json +++ b/packages/cluster-ui/package.json @@ -27,7 +27,7 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", - "@cockroachlabs/crdb-protobuf-client": "^0.0.6", + "@cockroachlabs/crdb-protobuf-client": "^0.0.7", "@cockroachlabs/icons": "0.3.0", "@cockroachlabs/ui-components": "0.2.14-alpha.0", "@popperjs/core": "^2.4.0", diff --git a/packages/cluster-ui/src/barCharts/barCharts.tsx b/packages/cluster-ui/src/barCharts/barCharts.tsx index ace9ed96d..c84f57299 100644 --- a/packages/cluster-ui/src/barCharts/barCharts.tsx +++ b/packages/cluster-ui/src/barCharts/barCharts.tsx @@ -35,13 +35,16 @@ const latencyBars = [ ]; const maxMemUsageBars = [ - bar("max-mem-usage", (d: StatementStatistics) => d.stats.max_mem_usage?.mean), + bar( + "max-mem-usage", + (d: StatementStatistics) => d.stats.exec_stats.max_mem_usage?.mean, + ), ]; const networkBytesBars = [ bar( "network-bytes", - (d: StatementStatistics) => d.stats.bytes_sent_over_network?.mean, + (d: StatementStatistics) => d.stats.exec_stats.network_bytes?.mean, ), ]; @@ -66,15 +69,12 @@ const latencyStdDev = bar( const maxMemUsageStdDev = bar( cx("max-mem-usage-dev"), (d: StatementStatistics) => - stdDevLong(d.stats.max_mem_usage, d.stats.exec_stat_collection_count), + stdDevLong(d.stats.exec_stats.max_mem_usage, d.stats.exec_stats.count), ); const networkBytesStdDev = bar( cx("network-bytes-dev"), (d: StatementStatistics) => - stdDevLong( - d.stats.bytes_sent_over_network, - d.stats.exec_stat_collection_count, - ), + stdDevLong(d.stats.exec_stats.network_bytes, d.stats.exec_stats.count), ); export const countBarChart = barChartFactory("grey", countBars, approximify); diff --git a/packages/cluster-ui/src/statementDetails/statementDetails.fixture.ts b/packages/cluster-ui/src/statementDetails/statementDetails.fixture.ts index 2ed64fb26..ffda04487 100644 --- a/packages/cluster-ui/src/statementDetails/statementDetails.fixture.ts +++ b/packages/cluster-ui/src/statementDetails/statementDetails.fixture.ts @@ -2,9 +2,34 @@ import Long from "long"; import { createMemoryHistory } from "history"; import { noop } from "lodash"; import { StatementDetailsProps } from "./statementDetails"; +import { ExecStats } from "../util"; const history = createMemoryHistory({ initialEntries: ["/statements"] }); +const execStats: Required = { + count: Long.fromNumber(1), + network_bytes: { + mean: 4160407, + squared_diffs: 47880000000000, + }, + max_mem_usage: { + mean: 4160407, + squared_diffs: 47880000000000, + }, + contention_time: { + mean: 4160407, + squared_diffs: 47880000000000, + }, + network_messages: { + mean: 4160407, + squared_diffs: 47880000000000, + }, + max_disk_usage: { + mean: 4160407, + squared_diffs: 47880000000000, + }, +}; + const statementStats: any = { count: Long.fromNumber(36958), first_attempt_count: Long.fromNumber(36958), @@ -73,15 +98,7 @@ const statementStats: any = { ], }, }, - bytes_sent_over_network: { - mean: 4160407, - squared_diffs: 47880000000000, - }, - max_mem_usage: { - mean: 4160407, - squared_diffs: 47880000000000, - }, - exec_stat_collection_count: 1, + exec_stats: execStats, }; export const getStatementDetailsPropsFixture = (): StatementDetailsProps => ({ diff --git a/packages/cluster-ui/src/statementDetails/statementDetails.tsx b/packages/cluster-ui/src/statementDetails/statementDetails.tsx index 94d215d39..8e0ffb89e 100644 --- a/packages/cluster-ui/src/statementDetails/statementDetails.tsx +++ b/packages/cluster-ui/src/statementDetails/statementDetails.tsx @@ -479,7 +479,7 @@ export class StatementDetails extends React.Component< Max memory usage {formatNumberForDisplay( - stats.max_mem_usage.mean, + stats.exec_stats.max_mem_usage.mean, Bytes, )} @@ -488,7 +488,7 @@ export class StatementDetails extends React.Component< Network usage {formatNumberForDisplay( - stats.bytes_sent_over_network.mean, + stats.exec_stats.network_bytes.mean, Bytes, )} @@ -663,10 +663,10 @@ export class StatementDetails extends React.Component< }, { name: "Network Bytes Sent", - value: stats.bytes_sent_over_network, + value: stats.exec_stats.network_bytes, bar: genericBarChart( - stats.bytes_sent_over_network, - stats.count, + stats.exec_stats.network_bytes, + stats.exec_stats.count, Bytes, ), format: Bytes, diff --git a/packages/cluster-ui/src/statementsPage/statementsPage.fixture.ts b/packages/cluster-ui/src/statementsPage/statementsPage.fixture.ts index 4d41e48b6..8efb57643 100644 --- a/packages/cluster-ui/src/statementsPage/statementsPage.fixture.ts +++ b/packages/cluster-ui/src/statementsPage/statementsPage.fixture.ts @@ -9,10 +9,35 @@ import { RequestError } from "src/util"; type IStatementDiagnosticsReport = cockroach.server.serverpb.IStatementDiagnosticsReport; type IStatementStatistics = protos.cockroach.sql.IStatementStatistics; +type IExecStats = protos.cockroach.sql.IExecStats; const history = createMemoryHistory({ initialEntries: ["/statements"]}); -const statementStats: IStatementStatistics = { +const execStats: Required = { + "count": Long.fromNumber(180), + "network_bytes": { + "mean": 80, + "squared_diffs": 0.01, + }, + "max_mem_usage": { + "mean": 80, + "squared_diffs": 0.01, + }, + "contention_time": { + "mean": 80, + "squared_diffs": 0.01, + }, + "network_messages": { + "mean": 80, + "squared_diffs": 0.01, + }, + "max_disk_usage": { + "mean": 80, + "squared_diffs": 0.01, + }, +}; + +const statementStats: Required = { "count": Long.fromNumber(180000), "first_attempt_count": Long.fromNumber(50000), "max_retries": Long.fromNumber(10), @@ -20,6 +45,8 @@ const statementStats: IStatementStatistics = { "mean": 1, "squared_diffs": 0, }, + "legacy_last_err": "", + "legacy_last_err_redacted": "", "parse_lat": { "mean": 0, "squared_diffs": 0, @@ -40,6 +67,15 @@ const statementStats: IStatementStatistics = { "mean": 0.00006233333333333315, "squared_diffs": 5.786666666666667e-10, }, + "bytes_read": { + "mean": 80, + "squared_diffs": 0.01, + }, + "rows_read": { + "mean": 10, + "squared_diffs": 1, + }, + exec_stats: execStats, "sensitive_info": { "last_err": "", "most_recent_plan_description": { @@ -148,23 +184,6 @@ const statementStats: IStatementStatistics = { ], }, }, - "bytes_read": { - "mean": 80, - "squared_diffs": 0.01, - }, - "rows_read": { - "mean": 10, - "squared_diffs": 1, - }, - "bytes_sent_over_network": { - "mean": 80, - "squared_diffs": 0.01, - }, - "max_mem_usage": { - "mean": 80, - "squared_diffs": 0.01, - }, - "exec_stat_collection_count": Long.fromNumber(180), }; const diagnosticsReports: IStatementDiagnosticsReport[] = [ diff --git a/packages/cluster-ui/src/statementsTable/statementsTable.tsx b/packages/cluster-ui/src/statementsTable/statementsTable.tsx index 7fcfd0d3f..58e19e295 100644 --- a/packages/cluster-ui/src/statementsTable/statementsTable.tsx +++ b/packages/cluster-ui/src/statementsTable/statementsTable.tsx @@ -80,14 +80,14 @@ function makeCommonColumns( title: StatementTableTitle.maxMemUsage, className: cx("statements-table__col-max-mem-usage"), cell: maxMemUsageBar, - sort: stmt => FixLong(Number(stmt.stats.max_mem_usage.mean)), + sort: stmt => FixLong(Number(stmt.stats.exec_stats.max_mem_usage.mean)), }, { name: "networkBytes", title: StatementTableTitle.networkBytes, className: cx("statements-table__col-network-bytes"), cell: networkBytesBar, - sort: stmt => FixLong(Number(stmt.stats.bytes_sent_over_network.mean)), + sort: stmt => FixLong(Number(stmt.stats.exec_stats.network_bytes.mean)), }, { name: "retries", diff --git a/packages/cluster-ui/src/transactionsPage/utils.ts b/packages/cluster-ui/src/transactionsPage/utils.ts index c18545b4a..4c61f9684 100644 --- a/packages/cluster-ui/src/transactionsPage/utils.ts +++ b/packages/cluster-ui/src/transactionsPage/utils.ts @@ -4,7 +4,7 @@ import { SelectOptions } from "./filter"; import { AggregateStatistics } from "../statementsTable"; import Long from "long"; import _ from "lodash"; -import { aggregateNumericStats, FixLong } from "../util"; +import { addExecStats, aggregateNumericStats, FixLong } from "../util"; type Statement = protos.cockroach.server.serverpb.StatementsResponse.ICollectedStatementStatistics; type TransactionStats = protos.cockroach.sql.ITransactionStatistics; @@ -125,46 +125,6 @@ const withFingerprint = function( }; }; -function addExecStats(a: ExecStats, b: ExecStats): Required { - let execStatCountA = FixLong(a.count).toInt(); - const execStatCountB = FixLong(b.count).toInt(); - if (execStatCountA === 0 && execStatCountB === 0) { - // If both counts are zero, artificially set the one count to one to avoid - // division by zero when calculating the mean in addNumericStats. - execStatCountA = 1; - } - return { - count: a.count.add(b.count), - network_bytes: - a.network_bytes && b.network_bytes - ? aggregateNumericStats( - a.network_bytes, - b.network_bytes, - execStatCountA, - execStatCountB, - ) - : null, - max_mem_usage: - a.max_mem_usage && b.max_mem_usage - ? aggregateNumericStats( - a.max_mem_usage, - b.max_mem_usage, - execStatCountA, - execStatCountB, - ) - : null, - contention_time: - a.contention_time && b.contention_time - ? aggregateNumericStats( - a.contention_time, - b.contention_time, - execStatCountA, - execStatCountB, - ) - : null, - }; -} - // addTransactionStats adds together two stat objects into one using their counts to compute a new // average for the numeric statistics. It's modeled after the similar `addStatementStats` function function addTransactionStats( diff --git a/packages/cluster-ui/src/util/appStats.spec.ts b/packages/cluster-ui/src/util/appStats.spec.ts index 72a1efbf0..7add5c7f5 100644 --- a/packages/cluster-ui/src/util/appStats.spec.ts +++ b/packages/cluster-ui/src/util/appStats.spec.ts @@ -8,6 +8,7 @@ import { NumericStat, flattenStatementStats, StatementStatistics, + ExecStats, combineStatementStats, } from "./appStats"; import IExplainTreePlanNode = protos.cockroach.sql.IExplainTreePlanNode; @@ -159,6 +160,17 @@ function randomStat(scale = 1): NumericStat { }; } +function randomExecStats(count = 10): Required { + return { + count: Long.fromNumber(randomInt(count)), + network_bytes: randomStat(), + max_mem_usage: randomStat(), + contention_time: randomStat(), + network_messages: randomStat(), + max_disk_usage: randomStat(), + }; +} + function randomStats( sensitiveInfo?: ISensitiveInfo, ): Required { @@ -166,7 +178,6 @@ function randomStats( // tslint:disable:variable-name const first_attempt_count = randomInt(count); const max_retries = randomInt(count - first_attempt_count); - const exec_stat_collection_count = randomInt(count); // tslint:enable:variable-name return { @@ -184,10 +195,7 @@ function randomStats( sensitive_info: sensitiveInfo || makeSensitiveInfo(null, null), legacy_last_err: "", legacy_last_err_redacted: "", - bytes_sent_over_network: randomStat(), - max_mem_usage: randomStat(), - exec_stat_collection_count: Long.fromNumber(exec_stat_collection_count), - contention_time: randomStat(), + exec_stats: randomExecStats(count), }; } diff --git a/packages/cluster-ui/src/util/appStats.ts b/packages/cluster-ui/src/util/appStats.ts index 4745b92b0..79ef1cf85 100644 --- a/packages/cluster-ui/src/util/appStats.ts +++ b/packages/cluster-ui/src/util/appStats.ts @@ -4,6 +4,7 @@ import * as protos from "@cockroachlabs/crdb-protobuf-client"; import { FixLong } from "src/util/fixLong"; export type StatementStatistics = protos.cockroach.sql.IStatementStatistics; +export type ExecStats = protos.cockroach.sql.IExecStats; export type CollectedStatementStatistics = protos.cockroach.server.serverpb.StatementsResponse.ICollectedStatementStatistics; export interface NumericStat { @@ -54,19 +55,64 @@ export function coalesceSensitiveInfo( }; } +export function addMaybeUnsetNumericStat( + a: NumericStat, + b: NumericStat, + countA: number, + countB: number, +): NumericStat { + return a && b ? aggregateNumericStats(a, b, countA, countB) : null; +} + +export function addExecStats(a: ExecStats, b: ExecStats): Required { + let countA = FixLong(a.count).toInt(); + const countB = FixLong(b.count).toInt(); + if (countA === 0 && countB === 0) { + // If both counts are zero, artificially set the one count to one to avoid + // division by zero when calculating the mean in addNumericStats. + countA = 1; + } + return { + count: a.count.add(b.count), + network_bytes: addMaybeUnsetNumericStat( + a.network_bytes, + b.network_bytes, + countA, + countB, + ), + max_mem_usage: addMaybeUnsetNumericStat( + a.max_mem_usage, + b.max_mem_usage, + countA, + countB, + ), + contention_time: addMaybeUnsetNumericStat( + a.contention_time, + b.contention_time, + countA, + countB, + ), + network_messages: addMaybeUnsetNumericStat( + a.network_messages, + b.network_messages, + countA, + countB, + ), + max_disk_usage: addMaybeUnsetNumericStat( + a.max_disk_usage, + b.max_disk_usage, + countA, + countB, + ), + }; +} + export function addStatementStats( a: StatementStatistics, b: StatementStatistics, ): Required { const countA = FixLong(a.count).toInt(); const countB = FixLong(b.count).toInt(); - let execStatCountA = FixLong(a.exec_stat_collection_count).toInt(); - const execStatCountB = FixLong(b.exec_stat_collection_count).toInt(); - if (execStatCountA === 0 && execStatCountB === 0) { - // If both counts are zero, artificially set the one count to one to avoid - // division by zero when calculating the mean in addNumericStats. - execStatCountA = 1; - } return { count: a.count.add(b.count), first_attempt_count: a.first_attempt_count.add(b.first_attempt_count), @@ -99,36 +145,7 @@ export function addStatementStats( sensitive_info: coalesceSensitiveInfo(a.sensitive_info, b.sensitive_info), legacy_last_err: "", legacy_last_err_redacted: "", - bytes_sent_over_network: - a.bytes_sent_over_network && b.bytes_sent_over_network - ? aggregateNumericStats( - a.bytes_sent_over_network, - b.bytes_sent_over_network, - execStatCountA, - execStatCountB, - ) - : null, - max_mem_usage: - a.max_mem_usage && b.max_mem_usage - ? aggregateNumericStats( - a.max_mem_usage, - b.max_mem_usage, - execStatCountA, - execStatCountB, - ) - : null, - exec_stat_collection_count: a.exec_stat_collection_count.add( - b.exec_stat_collection_count, - ), - contention_time: - a.contention_time && b.contention_time - ? aggregateNumericStats( - a.contention_time, - b.contention_time, - execStatCountA, - execStatCountB, - ) - : null, + exec_stats: addExecStats(a.exec_stats, b.exec_stats), }; } diff --git a/yarn.lock b/yarn.lock index 1543eb269..d4f05cbcb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1478,10 +1478,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@cockroachlabs/crdb-protobuf-client@^0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@cockroachlabs/crdb-protobuf-client/-/crdb-protobuf-client-0.0.6.tgz#e3ccc5b81987be7c525c6f71d52e2a2fced22deb" - integrity sha512-8A9QiLJ/9PlFJTtzzMTMCGb/VCt3jckHtwt/XWWqbFyZn4JuekUhZVM3XwiWf/vYG+rtrVaRpxuUKy8dLMw1pA== +"@cockroachlabs/crdb-protobuf-client@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@cockroachlabs/crdb-protobuf-client/-/crdb-protobuf-client-0.0.7.tgz#b0b405f04acc56932ed698a7d532c71c0b7f43bd" + integrity sha512-LjpKVeeeIrUG91uxi5jq3g6AXU6oj/HgvfnhL2YJaUeVC4S12AcSVMLMQ2S06mgB7pVXBs66mH2Lt4R0s6l4Lg== "@cockroachlabs/icons@0.3.0", "@cockroachlabs/icons@^0.3.0": version "0.3.0"