Snapshots: Use the grafana datasource to render snapshot (#54870)

This commit is contained in:
Ryan McKinley 2022-09-09 13:16:24 -07:00 committed by GitHub
parent dbb33eaba9
commit c49c238974
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 40 deletions

View File

@ -7,8 +7,6 @@ import {
DataQuery,
PanelData,
DataTransformerConfig,
getValueFormat,
formattedValueToString,
DataFrameJSON,
LoadingState,
dataFrameToJSON,
@ -16,6 +14,7 @@ import {
} from '@grafana/data';
import { config } from '@grafana/runtime';
import { PanelModel } from 'app/features/dashboard/state';
import { GrafanaQueryType } from 'app/plugins/datasource/grafana/types';
import { Randomize, randomizeData } from './randomizer';
@ -74,8 +73,8 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
withTransforms: false,
})
);
const dsref = panel.datasource;
const frames = randomizeData(getPanelDataFrames(data), rand);
const rawFrameContent = JSON.stringify(frames);
const grafanaVersion = `${config.buildInfo.version} (${config.buildInfo.commit})`;
const queries = saveModel?.targets ?? [];
const html = `<table width="100%">
@ -84,15 +83,16 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
<td >${info.panelType} @ ${saveModel.pluginVersion ?? grafanaVersion}</td>
</tr>
<tr>
<th>Queries&nbsp;(${queries.length})</th>
<th>Queries</th>
<td>${queries
.map((t: DataQuery) => {
return `${t.refId}[${t.datasource?.type}]`;
const ds = t.datasource ?? dsref;
return `${t.refId}[${ds?.type}]`;
})
.join(', ')}</td>
</tr>
${getTransformsRow(saveModel)}
${getDataRow(data, rawFrameContent)}
${getDataRow(data, frames)}
${getAnnotationsRow(data)}
<tr>
<th>Grafana</th>
@ -108,11 +108,11 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
{
refId: 'A',
datasource: {
type: 'testdata',
uid: '${testdata}',
type: 'grafana',
uid: 'grafana',
},
rawFrameContent,
scenarioId: 'raw_frame',
queryType: GrafanaQueryType.Snapshot,
snapshot: frames,
},
],
};
@ -137,8 +137,8 @@ export async function getDebugDashboard(panel: PanelModel, rand: Randomize, time
type: 'table',
title: 'Annotations',
datasource: {
type: 'testdata',
uid: '${testdata}',
type: 'grafana',
uid: 'grafana',
},
targets: [
{
@ -174,19 +174,22 @@ function getTransformsRow(saveModel: any): string {
</tr>`;
}
function getDataRow(data: PanelData, raw: string): string {
function getDataRow(data: PanelData, frames: DataFrameJSON[]): string {
let frameCount = data.series.length ?? 0;
let fieldCount = 0;
let rowCount = 0;
for (const frame of data.series) {
fieldCount += frame.fields.length;
rowCount += frame.length;
}
return (
'<tr>' +
'<th>Data</th>' +
'<td>' +
`${data.state !== LoadingState.Done ? data.state : ''} ` +
`${frameCount} frames, ${fieldCount} fields` +
`(${formattedValueToString(getValueFormat('decbytes')(raw?.length))} JSON)` +
`${frameCount} frames, ${fieldCount} fields, ` +
`${rowCount} rows ` +
// `(${formattedValueToString(getValueFormat('decbytes')(raw?.length))} JSON)` +
'</td>' +
'</tr>'
);
@ -211,8 +214,8 @@ const embeddedDataTemplate: any = {
id: 2,
title: 'Reproduced with embedded data',
datasource: {
type: 'testdata',
uid: '${testdata}',
type: 'grafana',
uid: 'grafana',
},
gridPos: {
h: 13,
@ -283,23 +286,4 @@ const embeddedDataTemplate: any = {
},
],
schemaVersion: 37,
templating: {
list: [
{
current: {
selected: true,
text: 'gdev-testdata',
value: 'gdev-testdata',
},
hide: 0,
includeAll: false,
multi: false,
name: 'testdata',
options: [],
query: 'testdata',
skipUrlSync: false,
type: 'datasource',
},
],
},
};

View File

@ -1,3 +1,4 @@
import pluralize from 'pluralize';
import React, { PureComponent } from 'react';
import {
@ -9,7 +10,7 @@ import {
DataFrame,
} from '@grafana/data';
import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { InlineField, Select, Alert, Input, InlineFieldRow } from '@grafana/ui';
import { InlineField, Select, Alert, Input, InlineFieldRow, InlineLabel } from '@grafana/ui';
import { hasAlphaPanels } from 'app/core/config';
import { SearchQuery } from 'app/features/search/service';
@ -344,6 +345,18 @@ export class QueryEditor extends PureComponent<Props, State> {
);
}
renderSnapshotQuery() {
const { query } = this.props;
return (
<InlineFieldRow>
<InlineField label="Snapshot" grow={true} labelWidth={labelWidth}>
<InlineLabel>{pluralize('frame', query.snapshot?.length ?? 0, true)}</InlineLabel>
</InlineField>
</InlineFieldRow>
);
}
onSearchChange = (search: SearchQuery) => {
const { query, onChange, onRunQuery } = this.props;
@ -362,6 +375,18 @@ export class QueryEditor extends PureComponent<Props, State> {
const { queryType } = query;
// Only show "snapshot" when it already exists
let queryTypes = this.queryTypes;
if (queryType === GrafanaQueryType.Snapshot) {
queryTypes = [
...this.queryTypes,
{
label: 'Snapshot',
value: queryType,
},
];
}
return (
<>
{queryType === GrafanaQueryType.Search && (
@ -373,14 +398,15 @@ export class QueryEditor extends PureComponent<Props, State> {
<InlineFieldRow>
<InlineField label="Query type" grow={true} labelWidth={labelWidth}>
<Select
options={this.queryTypes}
value={this.queryTypes.find((v) => v.value === queryType) || this.queryTypes[0]}
options={queryTypes}
value={queryTypes.find((v) => v.value === queryType) || queryTypes[0]}
onChange={this.onQueryTypeChange}
/>
</InlineField>
</InlineFieldRow>
{queryType === GrafanaQueryType.LiveMeasurements && this.renderMeasurementsQuery()}
{queryType === GrafanaQueryType.List && this.renderListPublicFiles()}
{queryType === GrafanaQueryType.Snapshot && this.renderSnapshotQuery()}
{queryType === GrafanaQueryType.Search && (
<SearchEditor value={query.search ?? {}} onChange={this.onSearchChange} />
)}

View File

@ -14,6 +14,8 @@ import {
MutableDataFrame,
parseLiveChannelAddress,
toDataFrame,
dataFrameFromJSON,
LoadingState,
} from '@grafana/data';
import {
DataSourceWithBackend,
@ -82,6 +84,15 @@ export class GrafanaDatasource extends DataSourceWithBackend<GrafanaQuery> {
if (target.hide) {
continue;
}
if (target.queryType === GrafanaQueryType.Snapshot) {
results.push(
of({
data: (target.snapshot ?? []).map((v) => dataFrameFromJSON(v)),
state: LoadingState.Done,
})
);
continue;
}
if (target.queryType === GrafanaQueryType.LiveMeasurements) {
let channel = templateSrv.replace(target.channel, request.scopedVars);
const { filter } = target;

View File

@ -1,4 +1,4 @@
import { DataQuery } from '@grafana/data';
import { DataQuery, DataFrameJSON } from '@grafana/data';
import { LiveDataFilter } from '@grafana/runtime';
import { SearchQuery } from 'app/features/search/service';
@ -9,6 +9,7 @@ import { SearchQuery } from 'app/features/search/service';
export enum GrafanaQueryType {
LiveMeasurements = 'measurements',
Annotations = 'annotations',
Snapshot = 'snapshot',
// backend
RandomWalk = 'randomWalk',
@ -24,6 +25,7 @@ export interface GrafanaQuery extends DataQuery {
buffer?: number;
path?: string; // for list and read
search?: SearchQuery;
snapshot?: DataFrameJSON[];
}
export const defaultQuery: GrafanaQuery = {