From 08d8190c022b7f3071999dc88408584b1e3d86ea Mon Sep 17 00:00:00 2001 From: Peter Holmberg Date: Wed, 11 Mar 2020 12:19:06 +0000 Subject: [PATCH] PanelInspector: Add Stats Tab (#22683) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add tab * add process measurement * Fixed some design issues * Align tabs margin Co-authored-by: Torkel Ödegaard --- packages/grafana-data/src/types/datasource.ts | 4 + packages/grafana-data/src/types/panel.ts | 3 +- .../components/Inspector/InspectHeader.tsx | 9 +- .../components/Inspector/PanelInspector.tsx | 88 +++++++++---------- .../features/dashboard/state/runRequest.ts | 7 +- 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 57a47c3f809..3c15e2b200b 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -434,6 +434,10 @@ export interface DataQueryRequest { endTime?: number; } +export interface DataQueryTimings { + dataProcessingTime: number; +} + export interface QueryFix { type: string; label: string; diff --git a/packages/grafana-data/src/types/panel.ts b/packages/grafana-data/src/types/panel.ts index 1eea8a3db7c..a195d3fe646 100644 --- a/packages/grafana-data/src/types/panel.ts +++ b/packages/grafana-data/src/types/panel.ts @@ -1,5 +1,5 @@ import { ComponentClass, ComponentType } from 'react'; -import { DataQueryError, DataQueryRequest } from './datasource'; +import { DataQueryError, DataQueryRequest, DataQueryTimings } from './datasource'; import { GrafanaPlugin, PluginMeta } from './plugin'; import { ScopedVars } from './ScopedVars'; import { LoadingState } from './data'; @@ -19,6 +19,7 @@ export interface PanelData { state: LoadingState; series: DataFrame[]; request?: DataQueryRequest; + timings?: DataQueryTimings; error?: DataQueryError; // Contains the range from the request or a shifted time range if a request uses relative time timeRange: TimeRange; diff --git a/public/app/features/dashboard/components/Inspector/InspectHeader.tsx b/public/app/features/dashboard/components/Inspector/InspectHeader.tsx index 0568e83efbb..600477a886a 100644 --- a/public/app/features/dashboard/components/Inspector/InspectHeader.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectHeader.tsx @@ -44,7 +44,7 @@ export const InspectHeader: FC = ({

{panel.title}

{formatStats(stats)}
- + {tabs.map((t, index) => { return ( { background-color: ${headerBackground}; z-index: 1; flex-grow: 0; - padding: ${theme.spacing.sm} ${theme.spacing.sm} 0 ${theme.spacing.lg}; `, actions: css` display: flex; align-items: baseline; justify-content: space-between; - margin-bottom: ${theme.spacing.md}; + margin: ${theme.spacing.md}; + `, + tabsBar: css` + padding-left: ${theme.spacing.md}; `, iconWrapper: css` cursor: pointer; @@ -88,6 +90,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => { `, titleWrapper: css` margin-bottom: ${theme.spacing.lg}; + padding: ${theme.spacing.sm} ${theme.spacing.sm} 0 ${theme.spacing.lg}; `, }; }); diff --git a/public/app/features/dashboard/components/Inspector/PanelInspector.tsx b/public/app/features/dashboard/components/Inspector/PanelInspector.tsx index 40866f9dfa4..3dd66406fd4 100644 --- a/public/app/features/dashboard/components/Inspector/PanelInspector.tsx +++ b/public/app/features/dashboard/components/Inspector/PanelInspector.tsx @@ -28,17 +28,18 @@ interface Props { export enum InspectTab { Data = 'data', - Raw = 'raw', + Request = 'request', Issue = 'issue', Meta = 'meta', // When result metadata exists Error = 'error', + Stats = 'stats', } interface State { // The last raw response last: PanelData; - // Data frem the last response + // Data from the last response data: DataFrame[]; // The selected data frame @@ -50,7 +51,7 @@ interface State { // If the datasource supports custom metadata metaDS?: DataSourceApi; - stats: { requestTime: number; queries: number; dataSources: number }; + stats: { requestTime: number; queries: number; dataSources: number; processingTime: number }; drawerWidth: string; } @@ -63,8 +64,8 @@ export class PanelInspector extends PureComponent { data: [], selected: 0, tab: props.selectedTab || InspectTab.Data, - drawerWidth: '40%', - stats: { requestTime: 0, queries: 0, dataSources: 0 }, + drawerWidth: '50%', + stats: { requestTime: 0, queries: 0, dataSources: 0, processingTime: 0 }, }; } @@ -90,6 +91,7 @@ export class PanelInspector extends PureComponent { const targets = lastResult.request?.targets || []; const requestTime = lastResult.request?.endTime ? lastResult.request?.endTime - lastResult.request.startTime : -1; const dataSources = new Set(targets.map(t => t.datasource)).size; + const processingTime = lastResult.timings?.dataProcessingTime || -1; // Find the first DataSource wanting to show custom metadata if (data && targets.length) { @@ -123,6 +125,7 @@ export class PanelInspector extends PureComponent { requestTime, queries: targets.length, dataSources, + processingTime, }, })); } @@ -163,11 +166,7 @@ export class PanelInspector extends PureComponent { if (!metaDS || !metaDS.components?.MetadataInspector) { return
No Metadata Inspector
; } - return ( - - - - ); + return ; } renderDataTab() { @@ -232,32 +231,44 @@ export class PanelInspector extends PureComponent { ); } - renderIssueTab() { - return TODO: show issue form; - } - renderErrorTab(error?: DataQueryError) { if (!error) { return null; } if (error.data) { return ( - + <>

{error.data.message}

-
-            {error.data.error}
-          
-
+ + ); } return
{error.message}
; } - renderRawJsonTab(last: PanelData) { + renderRequestTab() { + return ; + } + + renderStatsTab() { + const { stats } = this.state; return ( - - - + + + + + + + + + + + +
Query time{`${stats.requestTime === -1 ? 'N/A' : stats.requestTime + 'ms'}`}
Data processing time{`${ + stats.processingTime === -1 + ? 'N/A' + : Math.round((stats.processingTime + Number.EPSILON) * 100) / 100 + 'ms' + }`}
); } @@ -270,6 +281,9 @@ export class PanelInspector extends PureComponent { tabs.push({ label: 'Data', value: InspectTab.Data }); } + tabs.push({ label: 'Stats', value: InspectTab.Stats }); + tabs.push({ label: 'Request', value: InspectTab.Request }); + if (this.state.metaDS) { tabs.push({ label: 'Meta Data', value: InspectTab.Meta }); } @@ -278,8 +292,6 @@ export class PanelInspector extends PureComponent { tabs.push({ label: 'Error', value: InspectTab.Error }); } - tabs.push({ label: 'Raw JSON', value: InspectTab.Raw }); - return ( { return ( - {tab === InspectTab.Data ? ( - this.renderDataTab() - ) : ( - - {({ width, height }) => { - if (width === 0) { - return null; - } - return ( -
- {tab === InspectTab.Meta && this.renderMetadataInspector()} - {tab === InspectTab.Issue && this.renderIssueTab()} - {tab === InspectTab.Raw && this.renderRawJsonTab(last)} - {tab === InspectTab.Error && this.renderErrorTab(error)} -
- ); - }} -
- )} + + {tab === InspectTab.Data && this.renderDataTab()} + {tab === InspectTab.Meta && this.renderMetadataInspector()} + {tab === InspectTab.Request && this.renderRequestTab()} + {tab === InspectTab.Error && this.renderErrorTab(error)} + {tab === InspectTab.Stats && this.renderStatsTab()} +
); diff --git a/public/app/features/dashboard/state/runRequest.ts b/public/app/features/dashboard/state/runRequest.ts index 09da05e1244..dcf207c5102 100644 --- a/public/app/features/dashboard/state/runRequest.ts +++ b/public/app/features/dashboard/state/runRequest.ts @@ -216,8 +216,13 @@ export function preProcessPanelData(data: PanelData, lastResult: PanelData): Pan } // Make sure the data frames are properly formatted + const STARTTIME = performance.now(); + const processedDataFrames = getProcessedDataFrames(series); + const STOPTIME = performance.now(); + return { ...data, - series: getProcessedDataFrames(series), + series: processedDataFrames, + timings: { dataProcessingTime: STOPTIME - STARTTIME }, }; }