Skip to content

Commit

Permalink
ui: add limit and sort to fingerprints pages
Browse files Browse the repository at this point in the history
This commit adds new knobs to the sql stats
fingerprint pages. Users can now specify a
limit and sort priority with their sql stats
fingerprints requests.

Closes: cockroachdb#97876
Part of: cockroachdb#97875

Release note: None
  • Loading branch information
xinhaoz committed Mar 20, 2023
1 parent 19a5821 commit e3684ab
Show file tree
Hide file tree
Showing 20 changed files with 424 additions and 86 deletions.
41 changes: 39 additions & 2 deletions pkg/ui/workspaces/cluster-ui/src/api/statementsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// licenses/APL.txt.

import { cockroach } from "@cockroachlabs/crdb-protobuf-client";
import { fetchData } from "src/api";
import { fetchData } from "src/api/fetchData";
import {
FixFingerprintHexValue,
HexStringToInt64String,
Expand Down Expand Up @@ -43,13 +43,48 @@ export type ErrorWithKey = {
key: string;
};

export const SqlStatsSortOptions = cockroach.server.serverpb.StatsSortOptions;
export type SqlStatsSortType = cockroach.server.serverpb.StatsSortOptions;

export const DEFAULT_STATS_REQ_OPTIONS = {
limit: 100,
sort: SqlStatsSortOptions.SERVICE_LAT,
};

// The required fields to create a stmts request.
type StmtReqFields = {
limit: number;
sort: SqlStatsSortType;
start: moment.Moment;
end: moment.Moment;
};

export function createCombinedStmtsRequest({
limit,
sort,
start,
end,
}: StmtReqFields): StatementsRequest {
return new cockroach.server.serverpb.CombinedStatementsStatsRequest({
start: Long.fromNumber(start.unix()),
end: Long.fromNumber(end.unix()),
limit: Long.fromNumber(limit ?? DEFAULT_STATS_REQ_OPTIONS.limit),
fetch_mode:
new cockroach.server.serverpb.CombinedStatementsStatsRequest.FetchMode({
sort: sort,
}),
});
}

export const getCombinedStatements = (
req: StatementsRequest,
): Promise<cockroach.server.serverpb.StatementsResponse> => {
): Promise<SqlStatsResponse> => {
const queryStr = propsToQueryString({
start: req.start.toInt(),
end: req.end.toInt(),
"fetch_mode.stats_type": FetchStatsMode.StmtStatsOnly,
"fetch_mode.sort": req.fetch_mode.sort,
limit: req.limit.toInt(),
});
return fetchData(
cockroach.server.serverpb.StatementsResponse,
Expand All @@ -67,6 +102,8 @@ export const getFlushedTxnStatsApi = (
start: req.start.toInt(),
end: req.end.toInt(),
"fetch_mode.stats_type": FetchStatsMode.TxnStatsOnly,
"fetch_mode.sort": req.fetch_mode?.sort,
limit: req.limit.toInt() ?? DEFAULT_STATS_REQ_OPTIONS.limit,
});
return fetchData(
cockroach.server.serverpb.StatementsResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { StatementDiagnosticsReport } from "../api";
import { cockroach } from "@cockroachlabs/crdb-protobuf-client";
import ILatencyInfo = cockroach.sql.ILatencyInfo;
import { AggregateStatistics } from "src/statementsTable";
import { DEFAULT_STATS_REQ_OPTIONS } from "../api/statementsApi";

type IStatementStatistics = protos.cockroach.sql.IStatementStatistics;
type IExecStats = protos.cockroach.sql.IExecStats;
Expand Down Expand Up @@ -587,6 +588,8 @@ const statementsPagePropsFixture: StatementsPageProps = {
// Aggregate key values in these statements will need to change if implementation
// of 'statementKey' in appStats.ts changes.
statementsError: null,
limit: DEFAULT_STATS_REQ_OPTIONS.limit,
reqSortSetting: DEFAULT_STATS_REQ_OPTIONS.sort,
timeScale: {
windowSize: moment.duration(5, "day"),
sampleSize: moment.duration(5, "minutes"),
Expand Down Expand Up @@ -615,6 +618,8 @@ const statementsPagePropsFixture: StatementsPageProps = {
onColumnsChange: noop,
onSortingChange: noop,
onFilterChange: noop,
onChangeLimit: noop,
onChangeReqSort: noop,
};

export const statementsPagePropsWithRequestError: StatementsPageProps = {
Expand Down
105 changes: 80 additions & 25 deletions pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ import {
import { ISortedTablePagination } from "../sortedtable";
import styles from "./statementsPage.module.scss";
import { EmptyStatementsPlaceholder } from "./emptyStatementsPlaceholder";
import { cockroach } from "@cockroachlabs/crdb-protobuf-client";
import { InlineAlert } from "@cockroachlabs/ui-components";
import sortableTableStyles from "src/sortedtable/sortedtable.module.scss";
import ColumnsSelector from "../columnsSelector/columnsSelector";
import { SelectOption } from "../multiSelectCheckbox/multiSelectCheckbox";
import { UIConfigState } from "../store";
import { StatementsRequest } from "src/api/statementsApi";
import Long from "long";
import {
SqlStatsSortType,
StatementsRequest,
createCombinedStmtsRequest,
} from "src/api/statementsApi";
import ClearStats from "../sqlActivity/clearStats";
import LoadingError from "../sqlActivity/errorComponent";
import {
Expand All @@ -78,7 +80,14 @@ import {
StatementDiagnosticsReport,
} from "../api";
import { filteredStatementsData } from "../sqlActivity/util";
import { STATS_LONG_LOADING_DURATION } from "../util/constants";
import { Dropdown } from "src/dropdown";
import {
STATS_LONG_LOADING_DURATION,
limitOptions,
stmtRequestSortOptions,
getSortLabel,
} from "src/util/sqlActivityConstants";
import { Button } from "src/button";

const cx = classNames.bind(styles);
const sortableTableCx = classNames.bind(sortableTableStyles);
Expand Down Expand Up @@ -114,14 +123,17 @@ export interface StatementsPageDispatchProps {
onStatementClick?: (statement: string) => void;
onColumnsChange?: (selectedColumns: string[]) => void;
onTimeScaleChange: (ts: TimeScale) => void;
onChangeLimit: (limit: number) => void;
onChangeReqSort: (sort: SqlStatsSortType) => void;
}

export interface StatementsPageStateProps {
statements: AggregateStatistics[];
isDataValid: boolean;
isReqInFlight: boolean;
lastUpdated: moment.Moment | null;
timeScale: TimeScale;
limit: number;
reqSortSetting: SqlStatsSortType;
statementsError: Error | null;
apps: string[];
databases: string[];
Expand All @@ -141,17 +153,27 @@ export interface StatementsPageState {
pagination: ISortedTablePagination;
filters?: Filters;
activeFilters?: number;
timeScale: TimeScale;
limit: number;
reqSortSetting: SqlStatsSortType;
}

export type StatementsPageProps = StatementsPageDispatchProps &
StatementsPageStateProps &
RouteComponentProps<unknown>;

function stmtsRequestFromTimeScale(ts: TimeScale): StatementsRequest {
const [start, end] = toRoundedDateRange(ts);
return new cockroach.server.serverpb.CombinedStatementsStatsRequest({
start: Long.fromNumber(start.unix()),
end: Long.fromNumber(end.unix()),
type RequestParams = Pick<
StatementsPageState,
"limit" | "reqSortSetting" | "timeScale"
>;

function stmtsRequestFromParams(params: RequestParams): StatementsRequest {
const [start, end] = toRoundedDateRange(params.timeScale);
return createCombinedStmtsRequest({
start,
end,
limit: params.limit,
sort: params.reqSortSetting,
});
}

Expand Down Expand Up @@ -191,6 +213,9 @@ export class StatementsPage extends React.Component<
pageSize: 20,
current: 1,
},
limit: this.props.limit,
timeScale: this.props.timeScale,
reqSortSetting: this.props.reqSortSetting,
};
const stateFromHistory = this.getStateFromHistory();
this.state = merge(defaultState, stateFromHistory);
Expand Down Expand Up @@ -250,9 +275,17 @@ export class StatementsPage extends React.Component<
};

changeTimeScale = (ts: TimeScale): void => {
if (this.props.onTimeScaleChange) {
this.props.onTimeScaleChange(ts);
}
this.setState(prevState => ({
...prevState,
timeScale: ts,
}));
};

updateRequestParams = (): void => {
this.props.onChangeLimit(this.state.limit);
this.props.onChangeReqSort(this.state.reqSortSetting);
this.props.onTimeScaleChange(this.state.timeScale);
this.refreshStatements();
};

resetPagination = (): void => {
Expand All @@ -267,7 +300,7 @@ export class StatementsPage extends React.Component<
};

refreshStatements = (): void => {
const req = stmtsRequestFromTimeScale(this.props.timeScale);
const req = stmtsRequestFromParams(this.state);
this.props.refreshStatements(req);
};

Expand Down Expand Up @@ -336,21 +369,14 @@ export class StatementsPage extends React.Component<
);
}

componentDidUpdate = (prevProps: StatementsPageProps): void => {
componentDidUpdate = (): void => {
this.updateQueryParams();
if (!this.props.isTenant) {
this.props.refreshNodes();
if (!this.props.hasViewActivityRedactedRole) {
this.props.refreshStatementDiagnosticsRequests();
}
}

if (
prevProps.timeScale !== this.props.timeScale ||
(prevProps.isDataValid && !this.props.isDataValid)
) {
this.refreshStatements();
}
};

componentWillUnmount(): void {
Expand All @@ -359,8 +385,11 @@ export class StatementsPage extends React.Component<

onChangePage = (current: number): void => {
const { pagination } = this.state;
this.setState({ pagination: { ...pagination, current } });
this.props.onPageChanged != null && this.props.onPageChanged(current);
this.setState(prevState => ({
...prevState,
pagination: { ...pagination, current },
}));
this.props.onPageChanged(current);
};

onSubmitSearchField = (search: string): void => {
Expand Down Expand Up @@ -440,6 +469,14 @@ export class StatementsPage extends React.Component<
);
};

onChangeLimit = (newLimit: number): void => {
this.setState(prevState => ({ ...prevState, limit: newLimit }));
};

onChangeReqSort = (newSort: SqlStatsSortType): void => {
this.setState(prevState => ({ ...prevState, reqSortSetting: newSort }));
};

renderStatements = (regions: string[]): React.ReactElement => {
const { pagination, filters, activeFilters } = this.state;
const {
Expand Down Expand Up @@ -612,12 +649,30 @@ export class StatementsPage extends React.Component<
/>
</PageConfigItem>
<PageConfigItem className={commonStyles("separator")}>
<Dropdown items={limitOptions} onChange={this.onChangeLimit}>
Limit: {this.state.limit ?? "N/A"}
</Dropdown>
</PageConfigItem>
<PageConfigItem>
<Dropdown
items={stmtRequestSortOptions}
onChange={this.onChangeReqSort}
>
Sort By: {getSortLabel(this.state.reqSortSetting)}
</Dropdown>
</PageConfigItem>
<PageConfigItem>
<TimeScaleDropdown
options={timeScale1hMinOptions}
currentScale={this.props.timeScale}
currentScale={this.state.timeScale}
setTimeScale={this.changeTimeScale}
/>
</PageConfigItem>
<PageConfigItem>
<Button size="small" onClick={this.updateRequestParams}>
Submit Request
</Button>
</PageConfigItem>
{hasAdminRole && (
<PageConfigItem
className={`${commonStyles("separator")} ${cx(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { Dispatch } from "redux";
import { AppState, uiConfigActions } from "src/store";
import { actions as statementDiagnosticsActions } from "src/store/statementDiagnostics";
import { actions as analyticsActions } from "src/store/analytics";
import { actions as localStorageActions } from "src/store/localStorage";
import {
actions as localStorageActions,
updateStmtsPageLimitAction,
updateStmsPageReqSortAction,
} from "src/store/localStorage";
import { actions as sqlStatsActions } from "src/store/sqlStats";
import { actions as databasesListActions } from "src/store/databasesList";
import { actions as nodesActions } from "../store/nodes";
Expand All @@ -38,14 +42,18 @@ import {
selectSearch,
selectStatementsLastUpdated,
} from "./statementsPage.selectors";
import { selectTimeScale } from "../store/utils/selectors";
import {
selectTimeScale,
selectStmtsPageLimit,
selectStmtsPageReqSort,
} from "../store/utils/selectors";
import {
selectIsTenant,
selectHasViewActivityRedactedRole,
selectHasAdminRole,
} from "../store/uiConfig";
import { nodeRegionsByIDSelector } from "../store/nodes";
import { StatementsRequest } from "src/api/statementsApi";
import { SqlStatsSortType, StatementsRequest } from "src/api/statementsApi";
import { TimeScale } from "../timeScaleDropdown";
import {
StatementsPageRoot,
Expand Down Expand Up @@ -102,6 +110,8 @@ export const ConnectedStatementsPage = withRouter(
lastUpdated: selectStatementsLastUpdated(state),
statementsError: selectStatementsLastError(state),
totalFingerprints: selectTotalFingerprints(state),
limit: selectStmtsPageLimit(state),
reqSortSetting: selectStmtsPageReqSort(state),
},
activePageProps: mapStateToRecentStatementsPageProps(state),
}),
Expand Down Expand Up @@ -241,6 +251,10 @@ export const ConnectedStatementsPage = withRouter(
selectedColumns.length === 0 ? " " : selectedColumns.join(","),
}),
),
onChangeLimit: (limit: number) =>
dispatch(updateStmtsPageLimitAction(limit)),
onChangeReqSort: (sort: SqlStatsSortType) =>
dispatch(updateStmsPageReqSortAction(sort)),
},
activePageProps: mapDispatchToRecentStatementsPageProps(dispatch),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import {
} from "src/util";
import styles from "./statementsTableContent.module.scss";
import { EllipsisVertical } from "@cockroachlabs/icons";
import { getBasePath, StatementDiagnosticsReport } from "../api";
import { getBasePath } from "src/api/basePath";
import { StatementDiagnosticsReport } from "src/api/statementDiagnosticsApi";
import moment from "moment";

export type NodeNames = { [nodeId: string]: string };
Expand Down
Loading

0 comments on commit e3684ab

Please sign in to comment.