-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ui: add execution insights to statement and transaction fingerprint details #96440
ui: add execution insights to statement and transaction fingerprint details #96440
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good :) Just some nits and a couple suggestions from me.
Reviewed 37 of 37 files at r1, all commit messages.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @ericharmeling)
pkg/ui/workspaces/cluster-ui/src/api/stmtInsightsApi.ts
line 129 at r1 (raw file):
return ` SELECT ${stmtColumns} FROM
nit: trailing space
pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
line 464 at r1 (raw file):
* FROM ${TXN_INSIGHTS_TABLE_NAME}
nit: trailing space
pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
line 517 at r1 (raw file):
}; filters.execID = req?.txnExecutionID ? req.txnExecutionID : null; filters.fingerprintID = req?.txnFingerprintID ? req.txnFingerprintID : null;
Nit suggestion but can we move these expressions inside the above block like so?
const filters: TxnQueryFilters = {
start: req?.start,
end: req?.end,
execID: req?.txnExecutionID ? req.txnExecutionID : null,
fingerprintID: req?.txnFingerprintID ? req.txnFingerprintID : null,
};
Code quote:
filters.execID = req?.txnExecutionID ? req.txnExecutionID : null;
filters.fingerprintID = req?.txnFingerprintID ? req.txnFingerprintID : null;
pkg/ui/workspaces/cluster-ui/src/insightsTable/insightsTable.tsx
line 83 at r1 (raw file):
placement="bottom" content={ "The latest execution of the statement fingerprint with an insight within the selected time period."
The Loom video shows an ID in this column - should this tooltip say The latest execution ID...
?
Also, I'm not entirely sure if the ...within the selected time period.
bit is necessary since I haven't seen any other tooltips specify this but perhaps others can chime in here.
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/index.ts
line 1 at r1 (raw file):
// Copyright 2022 The Cockroach Authors.
nit: 2023
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.reducer.ts
line 1 at r1 (raw file):
// Copyright 2022 The Cockroach Authors.
nit: 2023
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.sagas.ts
line 1 at r1 (raw file):
// Copyright 2022 The Cockroach Authors.
nit: 2023
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.selectors.ts
line 1 at r1 (raw file):
// Copyright 2022 The Cockroach Authors.
nit: 2023
d2cdbd6
to
5a4eae3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TFTR! I think I got to all of your comments.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @gtr)
pkg/ui/workspaces/cluster-ui/src/api/stmtInsightsApi.ts
line 129 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: trailing space
Done.
pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
line 464 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: trailing space
Done.
pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
line 517 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
Nit suggestion but can we move these expressions inside the above block like so?
const filters: TxnQueryFilters = { start: req?.start, end: req?.end, execID: req?.txnExecutionID ? req.txnExecutionID : null, fingerprintID: req?.txnFingerprintID ? req.txnFingerprintID : null, };
Definitely! Done.
pkg/ui/workspaces/cluster-ui/src/insightsTable/insightsTable.tsx
line 83 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
The Loom video shows an ID in this column - should this tooltip say
The latest execution ID...
?Also, I'm not entirely sure if the
...within the selected time period.
bit is necessary since I haven't seen any other tooltips specify this but perhaps others can chime in here.
Done.
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/index.ts
line 1 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: 2023
Done
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.reducer.ts
line 1 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: 2023
Done
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.sagas.ts
line 1 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: 2023
Done.
pkg/ui/workspaces/cluster-ui/src/store/insights/statementFingerprintInsights/statementFingerprintInsights.selectors.ts
line 1 at r1 (raw file):
Previously, gtr (Gerardo Torres Castro) wrote…
nit: 2023
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you should the network tab? I want to confirm the cache is working and it's not spamming refresh calls
Reviewed 24 of 37 files at r1, 10 of 10 files at r2, all commit messages.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @ericharmeling and @gtr)
pkg/ui/workspaces/cluster-ui/src/api/sqlApi.ts
line 83 at r2 (raw file):
export const LONG_TIMEOUT = "300s"; export const LARGE_RESULT_SIZE = 50000; // 50 kib export const VERY_LARGE_RESULT_SIZE = 500000; // 500 kib
I don't see this used
pkg/ui/workspaces/cluster-ui/src/selectors/insightsCommon.selectors.ts
line 34 at r2 (raw file):
}; export const selectStatementInsightDetailsCombinerByFingerprint = (
did you mean CombineD
?
pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx
line 666 at r2 (raw file):
const isCockroachCloud = useContext(CockroachCloudContext); const insightsColumns = useMemo( () => makeInsightsColumns(isCockroachCloud, false, false),
the second false should not be hard coded, you should use hasAdminRole
that already exists on this file
pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx
line 453 at r2 (raw file):
); const insightsColumns = makeInsightsColumns(true, false, false);
don't hard code the values here. Get the real value for cockroach cloud and hasAdminRole
041b32a
to
a216433
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you should the network tab? I want to confirm the cache is working and it's not spamming refresh calls
Sure thing!
https://www.loom.com/share/89bab56b76a446fc9b2ca81775317e52
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @gtr and @maryliag)
pkg/ui/workspaces/cluster-ui/src/selectors/insightsCommon.selectors.ts
line 34 at r2 (raw file):
Previously, maryliag (Marylia Gutierrez) wrote…
did you mean
CombineD
?
I'm using the naming from the selector above this and below this (selectStatementInsightDetailsCombiner
and selectTxnInsightDetailsCombiner
).
pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx
line 666 at r2 (raw file):
Previously, maryliag (Marylia Gutierrez) wrote…
the second false should not be hard coded, you should use
hasAdminRole
that already exists on this file
Done.
pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx
line 453 at r2 (raw file):
Previously, maryliag (Marylia Gutierrez) wrote…
don't hard code the values here. Get the real value for cockroach cloud and hasAdminRole
Done.
pkg/ui/workspaces/cluster-ui/src/api/sqlApi.ts
line 83 at r2 (raw file):
Previously, maryliag (Marylia Gutierrez) wrote…
I don't see this used
Removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, the changes in this PR do not work on CRDB versions without 06838a1
The SQL API call returns the following error:
code: "42703", message: "executing stmt 1: run-query-via-api: column \"cpu_sql_nanos\" does not exist", severity: "ERROR", …
But the page won't crash. There just won't be any insights on any fingerprint's details page.
There are also some cryptic jest failures that I need to investigate.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @gtr and @maryliag)
a216433
to
0b75cd9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Once you get tests passing (you might need a rebase):
Reviewed 1 of 37 files at r1, 7 of 7 files at r3, all commit messages.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @gtr)
start: req?.start, | ||
end: req?.end, | ||
execID: req?.txnExecutionID ? req.txnExecutionID : null, | ||
fingerprintID: req?.txnFingerprintID ? req.txnFingerprintID : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This can be simplified to req?.txFingerprintID
. You don't need the ternary operator here, the ?
will make the evaluated value null
@@ -75,7 +75,7 @@ export const TransactionInsightDetails: React.FC< | |||
|
|||
useEffect(() => { | |||
const stmtsComplete = | |||
stmts != null && stmts.length === txnDetails?.stmtExecutionIDs?.length; | |||
stmts != null && stmts?.length === txnDetails?.stmtExecutionIDs?.length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You don't need to add the ?
to the second part of the && here. If stmts is nullish the stmts != null &&
will ensure the part after && doesn't get read.
(transactionQueries.length === 1 && | ||
transactionQueries[0].length < textLimit) | ||
!transactionQueries?.length || | ||
(transactionQueries?.length === 1 && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto for the addition of ?
here. !transactionQueries?.length
will ensure that the part after ||
means that transactionQueries has a non-zero length.
statementInsights: StmtInsightEvent[], | ||
fingerprintID: string, | ||
): StmtInsightEvent[] | null => { | ||
if (!statementInsights || statementInsights?.length < 1 || !fingerprintID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can be condensed to (!statementInsights?.length || !fingerprintID)
return null; | ||
} | ||
const insightEvents: StmtInsightEvent[] = []; | ||
statementInsights.forEach(insight => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Try replacing this with an aray.filter, and you can set the var above directly.
@@ -508,6 +558,31 @@ export class TransactionDetails extends React.Component< | |||
</SummaryCard> | |||
</Col> | |||
</Row> | |||
{tableData != null && tableData?.length > 0 && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: tableData?.length &&
); | ||
const tableData: InsightRecommendation[] = []; | ||
if (transactionInsights) { | ||
const tableDataTypes: InsightType[] = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: if you're using this to track the insight types seen already, a set
is prob preferred (although the array size will be small so it's probably not a big deal 🤷 )
0b75cd9
to
7716ab4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TFTR @xinhaoz ! I think I got to all of your comments.
Reviewable status: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @gtr, @maryliag, and @xinhaoz)
pkg/ui/workspaces/cluster-ui/src/api/txnInsightsApi.ts
line 516 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: This can be simplified to
req?.txFingerprintID
. You don't need the ternary operator here, the?
will make the evaluated value null
Done.
pkg/ui/workspaces/cluster-ui/src/insights/workloadInsightDetails/transactionInsightDetails.tsx
line 78 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: You don't need to add the
?
to the second part of the && here. If stmts is nullish thestmts != null &&
will ensure the part after && doesn't get read.
Done.
pkg/ui/workspaces/cluster-ui/src/insights/workloadInsights/util/queriesCell.tsx
line 25 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
Ditto for the addition of
?
here.!transactionQueries?.length
will ensure that the part after||
means that transactionQueries has a non-zero length.
Done.
pkg/ui/workspaces/cluster-ui/src/selectors/insightsCommon.selectors.ts
line 38 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: can be condensed to (!statementInsights?.length || !fingerprintID)
Done.
pkg/ui/workspaces/cluster-ui/src/selectors/insightsCommon.selectors.ts
line 42 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: Try replacing this with an aray.filter, and you can set the var above directly.
Done.
pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx
line 467 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: if you're using this to track the insight types seen already, a
set
is prob preferred (although the array size will be small so it's probably not a big deal 🤷 )
Done (here and in statementDetails
).
pkg/ui/workspaces/cluster-ui/src/transactionDetails/transactionDetails.tsx
line 561 at r3 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: tableData?.length &&
Done.
I've addressed all requested changes.
const req = getStatementDetailsRequestFromProps(this.props); | ||
this.props.refreshStatementDetails(req); | ||
this.refreshStatementInsights(this.props.statementFingerprintID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: if this param is just from the props, why not just put it directly in the function instead as a param?
@@ -271,6 +299,32 @@ function descriptionCell( | |||
} | |||
} | |||
|
|||
function linkCell(insightRec: InsightRecommendation): React.ReactElement { | |||
if (insightRec.execution.execType === InsightExecEnum.STATEMENT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This might be a little clearer with a switch case statement
const isCockroachCloud = useContext(CockroachCloudContext); | ||
const insightsColumns = useMemo( | ||
() => | ||
makeInsightsColumns(isCockroachCloud, this.props.hasAdminRole, false), | ||
[isCockroachCloud], | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's recommended to use hooks inside non-functional components. It can have some weird effects, and also I don't think conditional calls to hooks are allowed (not sure what hte error behaviour will be though, did you get any console warnings?). I believe what you're doing here means these hooks will attach to the parent component (in this case StatementDetails), and since we render something different when we don't have data we'll be conditionally calling these hooks. Maybe you can extract renderOverviewTabContent
into its own component.
…etails This commit adds execution insights to the Statement Fingerprint and Transaction Fingerprint Details pages. Part of cockroachdb#83780. Release note (ui change): Added execution insights to the Statement Fingerprint Details and Transaction Fingerprint Details Pages.
7716ab4
to
2ec730f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @gtr, @maryliag, and @xinhaoz)
pkg/ui/workspaces/cluster-ui/src/insightsTable/insightsTable.tsx
line 303 at r4 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: This might be a little clearer with a switch case statement
Done.
pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx
line 272 at r4 (raw file):
Previously, xinhaoz (Xin Hao Zhang) wrote…
nit: if this param is just from the props, why not just put it directly in the function instead as a param?
Done.
pkg/ui/workspaces/cluster-ui/src/statementDetails/statementDetails.tsx
line 669 at r4 (raw file):
I don't think it's recommended to use hooks inside non-functional components.
That makes sense. I just removed the hook for now. IDK how much we save memoizing the cockroachcloud context.
also I don't think conditional calls to hooks are allowed (not sure what hte error behaviour will be though, did you get any console warnings?). I believe what you're doing here means these hooks will attach to the parent component (in this case StatementDetails), and since we render something different when we don't have data we'll be conditionally calling these hooks
I didn't get any console warnings (from what I'm reading, it's just bad practice), but that's good to know for future reference 😄 !
Tests are passed and I've gotten to everyone's feedback. I'm going to go ahead and bors 😁. |
bors r+ |
Build succeeded: |
cockroachdb#96440 introduced a bug to the Insights Table on the Schema Insights page. This commit fixes that bug. Release note: None Epic: None
97306: kvserver: add storage.keys.tombstone.count metric r=nicktrav a=jbowens Expose the number of tombstones in the storage engine as a timeseries metric. This provides some additional visibility into garbage collection and would help in diagnosing issues like cockroachlabs/support#2084. Epic: None Release note (ops change): Adds a new timeseries metric `storage.keys.tombstone.count` that shows the current count of point and range deletion tombstones across the storage engine. 97309: ui: fixed insights table bug on insights r=ericharmeling a=ericharmeling #96440 introduced a bug to the Insights Table on the Schema Insights page. This commit fixes that bug. Loom: https://www.loom.com/share/0f81bc55371f49418f7f0175bbc5dff4 Release note: None Epic: None Co-authored-by: Jackson Owens <[email protected]> Co-authored-by: Eric Harmeling <[email protected]>
This commit adds execution insights to the Statement Fingerprint and Transaction Fingerprint Details pages.
Part of #83780.
Loom: https://www.loom.com/share/98d2023b672e43fa8016829aa641a829
Note that the SQL queries against the
*_execution_insights
tables are updated toSELECT DISTINCT ON (*_fingerprint_id, problems, causes)
(equivalent toGROUP BY (*_fingerprint_id, problems, causes)
) from the latest results in the tables, rather thanrow_number() OVER ( PARTITION BY stmt_fingerprint_id, problem, causes ORDER BY end_time DESC ) AS rank... WHERE rank = 1
. Both patterns return the same result, but one uses aggregation and the other uses a window function. I find theDISTINCT ON/GROUP BY
pattern easier to understand, I'm not seeing much difference in the planning/execution time between the two over the same set of data, and I'm seeingDISTINCT ON/GROUP BY
coming up as more performant in almost all the secondary sources I've encountered.Release note (ui change): Added execution insights to the Statement Fingerprint Details and Transaction Fingerprint Details Pages.