Skip to content

Commit

Permalink
ui: link insights to fingerprint details
Browse files Browse the repository at this point in the history
Now from the Insights page, clicking on the statement
or fingerprint ids, it will bring you to their respective
details page.

This commit also filter out transaction insights that didn't
have their value set yet (meaning they're still 0).

Finally, this commit fixes the start/end values being passed
to the combined statement endpoint, to the correct rounded
values, aligning what we say on the UI.

Fixes #87750

Release note (ui change): The fingerprint id values
for statement and transactions on the insights pages are
links that open the respective details page on the time period
of the execution of that statement/transaction.

Release note (bug fix): Sendind the proper start/end values
to the endpoint used on SQL Activity page, now returning the
full hour as described on the UI.
  • Loading branch information
maryliag committed Oct 20, 2022
1 parent 72ac655 commit 33380e1
Show file tree
Hide file tree
Showing 23 changed files with 237 additions and 41 deletions.
4 changes: 4 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/api/insightsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const txnContentionQuery = `SELECT *
max(collection_ts) AS collection_ts,
sum(contention_duration) AS total_contention_duration
FROM crdb_internal.transaction_contention_events tce
WHERE waiting_txn_fingerprint_id != '\x0000000000000000'
GROUP BY waiting_txn_id, waiting_txn_fingerprint_id),
(SELECT txn_id FROM crdb_internal.cluster_execution_insights)
WHERE total_contention_duration > threshold
Expand Down Expand Up @@ -572,6 +573,7 @@ type ExecutionInsightsResponseRow = {
session_id: string;
txn_id: string;
txn_fingerprint_id: string; // hex string
implicit_txn: boolean;
stmt_id: string;
stmt_fingerprint_id: string; // hex string
query: string;
Expand Down Expand Up @@ -609,6 +611,7 @@ function getStatementInsightsFromClusterExecutionInsightsResponse(
return {
transactionID: row.txn_id,
transactionFingerprintID: row.txn_fingerprint_id,
implicitTxn: row.implicit_txn,
query: row.query,
startTime: start,
endTime: end,
Expand Down Expand Up @@ -651,6 +654,7 @@ const statementInsightsQuery: InsightQuery<
session_id,
txn_id,
encode(txn_fingerprint_id, 'hex') AS txn_fingerprint_id,
implicit_txn,
stmt_id,
encode(stmt_fingerprint_id, 'hex') AS stmt_fingerprint_id,
query AS non_prettified_query,
Expand Down
1 change: 1 addition & 0 deletions pkg/ui/workspaces/cluster-ui/src/insights/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export type StatementInsightEvent = {
transactionID: string;
statementFingerprintID: string;
transactionFingerprintID: string;
implicitTxn: boolean;
startTime: Moment;
elapsedTimeMillis: number;
sessionID: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ import { commonStyles } from "src/common";
import insightTableStyles from "src/insightsTable/insightsTable.module.scss";
import summaryCardStyles from "src/summaryCard/summaryCard.module.scss";
import { CockroachCloudContext } from "../../contexts";
import {
TransactionDetailsLink,
StatementDetailsLink,
} from "../workloadInsights/util";
import { TimeScale } from "../../timeScaleDropdown";

const tableCx = classNames.bind(insightTableStyles);
const summaryCardStylesCx = classNames.bind(summaryCardStyles);
Expand All @@ -48,7 +53,12 @@ export interface StatementInsightDetailsStateProps {
insightError: Error | null;
}

export interface StatementInsightDetailsDispatchProps {
setTimeScale: (ts: TimeScale) => void;
}

export type StatementInsightDetailsProps = StatementInsightDetailsStateProps &
StatementInsightDetailsDispatchProps &
RouteComponentProps<unknown>;

export class StatementInsightDetails extends React.Component<StatementInsightDetailsProps> {
Expand Down Expand Up @@ -196,15 +206,22 @@ export class StatementInsightDetails extends React.Component<StatementInsightDet
/>
<SummaryCardItem
label="Transaction Fingerprint ID"
value={String(insightDetails.transactionFingerprintID)}
value={TransactionDetailsLink(
insightDetails.transactionFingerprintID,
insightDetails.startTime,
this.props.setTimeScale,
)}
/>
<SummaryCardItem
label="Transaction Execution ID"
value={String(insightDetails.transactionID)}
/>
<SummaryCardItem
label="Statement Fingerprint ID"
value={String(insightDetails.statementFingerprintID)}
value={StatementDetailsLink(
insightDetails,
this.props.setTimeScale,
)}
/>
</SummaryCard>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { RouteComponentProps, withRouter } from "react-router-dom";
import {
StatementInsightDetails,
StatementInsightDetailsDispatchProps,
StatementInsightDetailsStateProps,
} from "./statementInsightDetails";
import { AppState } from "src/store";
import {
selectStatementInsightDetails,
selectStatementInsightsError,
} from "src/store/insights/statementInsights";
import { TimeScale } from "../../timeScaleDropdown";
import { actions as sqlStatsActions } from "../../store/sqlStats";

const mapStateToProps = (
state: AppState,
Expand All @@ -31,8 +35,25 @@ const mapStateToProps = (
};
};

const mapDispatchToProps = (
dispatch: Dispatch,
): StatementInsightDetailsDispatchProps => ({
setTimeScale: (ts: TimeScale) => {
dispatch(
sqlStatsActions.updateTimeScale({
ts: ts,
}),
);
},
});

export const StatementInsightDetailsConnected = withRouter(
connect<StatementInsightDetailsStateProps, RouteComponentProps>(
connect<
StatementInsightDetailsStateProps,
StatementInsightDetailsDispatchProps,
RouteComponentProps
>(
mapStateToProps,
mapDispatchToProps,
)(StatementInsightDetails),
);
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import { commonStyles } from "src/common";
import insightTableStyles from "src/insightsTable/insightsTable.module.scss";
import { CockroachCloudContext } from "../../contexts";
import { InsightsError } from "../insightsErrorComponent";
import { TransactionDetailsLink } from "../workloadInsights/util";
import { TimeScale } from "../../timeScaleDropdown";

const tableCx = classNames.bind(insightTableStyles);

Expand All @@ -55,6 +57,7 @@ export interface TransactionInsightDetailsDispatchProps {
refreshTransactionInsightDetails: (
req: TransactionInsightEventDetailsRequest,
) => void;
setTimeScale: (ts: TimeScale) => void;
}

export type TransactionInsightDetailsProps =
Expand Down Expand Up @@ -152,7 +155,11 @@ export class TransactionInsightDetails extends React.Component<TransactionInsigh
<SummaryCard>
<SummaryCardItem
label="Transaction Fingerprint ID"
value={String(insightDetails.fingerprintID)}
value={TransactionDetailsLink(
insightDetails.fingerprintID,
insightDetails.startTime,
this.props.setTimeScale,
)}
/>
</SummaryCard>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import {
selectTransactionInsightDetailsError,
actions,
} from "src/store/insightDetails/transactionInsightDetails";
import { TimeScale } from "../../timeScaleDropdown";
import { actions as sqlStatsActions } from "../../store/sqlStats";
import { Dispatch } from "redux";

const mapStateToProps = (
state: AppState,
Expand All @@ -33,9 +36,18 @@ const mapStateToProps = (
};
};

const mapDispatchToProps = {
const mapDispatchToProps = (
dispatch: Dispatch,
): TransactionInsightDetailsDispatchProps => ({
refreshTransactionInsightDetails: actions.refresh,
};
setTimeScale: (ts: TimeScale) => {
dispatch(
sqlStatsActions.updateTimeScale({
ts: ts,
}),
);
},
});

export const TransactionInsightDetailsConnected = withRouter(
connect<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const statementInsightsPropsFixture: StatementInsightsViewProps = {
statementFingerprintID: "abc",
transactionFingerprintID: "defg",
transactionID: "f72f37ea-b3a0-451f-80b8-dfb27d0bc2a5",
implicitTxn: true,
query:
"SELECT IFNULL(a, b) FROM (SELECT (SELECT code FROM promo_codes WHERE code > $1 ORDER BY code LIMIT _) AS a, (SELECT code FROM promo_codes ORDER BY code LIMIT _) AS b)",
startTime: moment.utc("2022.08.10"),
Expand All @@ -46,6 +47,7 @@ export const statementInsightsPropsFixture: StatementInsightsViewProps = {
statementFingerprintID: "938x3",
transactionFingerprintID: "1971x3",
transactionID: "e72f37ea-b3a0-451f-80b8-dfb27d0bc2a5",
implicitTxn: true,
query: "INSERT INTO vehicles VALUES ($1, $2, __more1_10__)",
startTime: moment.utc("2022.08.10"),
endTime: moment.utc("2022.08.10 00:00:00.25"),
Expand All @@ -71,6 +73,7 @@ export const statementInsightsPropsFixture: StatementInsightsViewProps = {
statementFingerprintID: "hisas",
transactionFingerprintID: "3anc",
transactionID: "f72f37ea-b3a0-451f-80b8-dfb27d0bc2a0",
implicitTxn: true,
query:
"UPSERT INTO vehicle_location_histories VALUES ($1, $2, now(), $3, $4)",
startTime: moment.utc("2022.08.10"),
Expand Down Expand Up @@ -104,4 +107,5 @@ export const statementInsightsPropsFixture: StatementInsightsViewProps = {
refreshStatementInsights: () => {},
onSortChange: () => {},
onFiltersChange: () => {},
setTimeScale: () => {},
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ import {
} from "src/sortedtable";
import { Count, DATE_FORMAT, Duration, limitText } from "src/util";
import { InsightExecEnum, StatementInsightEvent } from "src/insights";
import { InsightCell, insightsTableTitles } from "../util";
import {
InsightCell,
insightsTableTitles,
StatementDetailsLink,
} from "../util";
import { StatementInsights } from "../../../api";
import { Tooltip } from "@cockroachlabs/ui-components";
import { Link } from "react-router-dom";
import classNames from "classnames/bind";
import styles from "../util/workloadInsights.module.scss";
import { TimeScale } from "../../../timeScaleDropdown";

const cx = classNames.bind(styles);

Expand All @@ -35,7 +40,9 @@ interface StatementInsightsTable {
visibleColumns: ColumnDescriptor<StatementInsightEvent>[];
}

export function makeStatementInsightsColumns(): ColumnDescriptor<StatementInsightEvent>[] {
export function makeStatementInsightsColumns(
setTimeScale: (ts: TimeScale) => void,
): ColumnDescriptor<StatementInsightEvent>[] {
const execType = InsightExecEnum.STATEMENT;
return [
{
Expand All @@ -52,7 +59,8 @@ export function makeStatementInsightsColumns(): ColumnDescriptor<StatementInsigh
{
name: "statementFingerprintID",
title: insightsTableTitles.fingerprintID(execType),
cell: (item: StatementInsightEvent) => item.statementFingerprintID,
cell: (item: StatementInsightEvent) =>
StatementDetailsLink(item, setTimeScale),
sort: (item: StatementInsightEvent) => item.statementFingerprintID,
showByDefault: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { PageConfig, PageConfigItem } from "src/pageConfig/pageConfig";
import { Search } from "src/search/search";
import {
calculateActiveFilters,
defaultFilters,
Filter,
getFullFiltersAsStringRecord,
} from "src/queryFilter/filter";
Expand All @@ -48,6 +47,7 @@ import styles from "src/statementsPage/statementsPage.module.scss";
import sortableTableStyles from "src/sortedtable/sortedtable.module.scss";
import ColumnsSelector from "../../../columnsSelector/columnsSelector";
import { SelectOption } from "../../../multiSelectCheckbox/multiSelectCheckbox";
import { TimeScale } from "../../../timeScaleDropdown";

const cx = classNames.bind(styles);
const sortableTableCx = classNames.bind(sortableTableStyles);
Expand All @@ -66,6 +66,7 @@ export type StatementInsightsViewDispatchProps = {
onSortChange: (ss: SortSetting) => void;
refreshStatementInsights: () => void;
onColumnsChange: (selectedColumns: string[]) => void;
setTimeScale: (ts: TimeScale) => void;
};

export type StatementInsightsViewProps = StatementInsightsViewStateProps &
Expand Down Expand Up @@ -101,6 +102,7 @@ export const StatementInsightsView: React.FC<StatementInsightsViewProps> = (
onFiltersChange,
onSortChange,
onColumnsChange,
setTimeScale,
selectedColumnNames,
dropDownSelect,
} = props;
Expand Down Expand Up @@ -194,7 +196,7 @@ export const StatementInsightsView: React.FC<StatementInsightsViewProps> = (
resetPagination();
};

const defaultColumns = makeStatementInsightsColumns();
const defaultColumns = makeStatementInsightsColumns(setTimeScale);

const visibleColumns = defaultColumns.filter(x =>
isSelected(x, selectedColumnNames),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ export const transactionInsightsPropsFixture: TransactionInsightsViewProps = {
refreshTransactionInsights: () => {},
onSortChange: () => {},
onFiltersChange: () => {},
setTimeScale: () => {},
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,27 @@ import {
} from "src/sortedtable";
import { DATE_FORMAT, Duration } from "src/util";
import { InsightExecEnum, TransactionInsightEvent } from "src/insights";
import { InsightCell, insightsTableTitles, QueriesCell } from "../util";
import {
InsightCell,
insightsTableTitles,
QueriesCell,
TransactionDetailsLink,
} from "../util";
import { Link } from "react-router-dom";
import { TimeScale } from "../../../timeScaleDropdown";

interface TransactionInsightsTable {
data: TransactionInsightEvent[];
sortSetting: SortSetting;
onChangeSortSetting: (ss: SortSetting) => void;
pagination: ISortedTablePagination;
renderNoResult?: React.ReactNode;
setTimeScale: (ts: TimeScale) => void;
}

export function makeTransactionInsightsColumns(): ColumnDescriptor<TransactionInsightEvent>[] {
export function makeTransactionInsightsColumns(
setTimeScale: (ts: TimeScale) => void,
): ColumnDescriptor<TransactionInsightEvent>[] {
const execType = InsightExecEnum.TRANSACTION;
return [
{
Expand All @@ -44,7 +53,12 @@ export function makeTransactionInsightsColumns(): ColumnDescriptor<TransactionIn
{
name: "fingerprintID",
title: insightsTableTitles.fingerprintID(execType),
cell: (item: TransactionInsightEvent) => String(item.fingerprintID),
cell: (item: TransactionInsightEvent) =>
TransactionDetailsLink(
item.fingerprintID,
item.startTime,
setTimeScale,
),
sort: (item: TransactionInsightEvent) => item.fingerprintID,
},
{
Expand Down Expand Up @@ -90,7 +104,7 @@ export function makeTransactionInsightsColumns(): ColumnDescriptor<TransactionIn
export const TransactionInsightsTable: React.FC<
TransactionInsightsTable
> = props => {
const columns = makeTransactionInsightsColumns();
const columns = makeTransactionInsightsColumns(props.setTimeScale);
return (
<SortedTable columns={columns} className="statements-table" {...props} />
);
Expand Down
Loading

0 comments on commit 33380e1

Please sign in to comment.