mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TestDatasource: Add scenario for generating trace data (#59299)
This commit is contained in:
parent
1481ace528
commit
038c97f31c
@ -43,6 +43,7 @@ const (
|
|||||||
rawFrameQuery queryType = "raw_frame"
|
rawFrameQuery queryType = "raw_frame"
|
||||||
csvFileQueryType queryType = "csv_file"
|
csvFileQueryType queryType = "csv_file"
|
||||||
csvContentQueryType queryType = "csv_content"
|
csvContentQueryType queryType = "csv_content"
|
||||||
|
traceType queryType = "trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
type queryType string
|
type queryType string
|
||||||
@ -218,6 +219,11 @@ Timestamps will line up evenly on timeStepSeconds (For example, 60 seconds means
|
|||||||
handler: s.handleCsvContentScenario,
|
handler: s.handleCsvContentScenario,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
s.registerScenario(&Scenario{
|
||||||
|
ID: string(traceType),
|
||||||
|
Name: "Trace",
|
||||||
|
})
|
||||||
|
|
||||||
s.queryMux.HandleFunc("", s.handleFallbackScenario)
|
s.queryMux.HandleFunc("", s.handleFallbackScenario)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +302,18 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props)
|
|||||||
<NodeGraphEditor onChange={(val: NodesQuery) => onChange({ ...query, nodes: val })} query={query} />
|
<NodeGraphEditor onChange={(val: NodesQuery) => onChange({ ...query, nodes: val })} query={query} />
|
||||||
)}
|
)}
|
||||||
{scenarioId === 'server_error_500' && <ErrorEditor onChange={onUpdate} query={query} ds={datasource} />}
|
{scenarioId === 'server_error_500' && <ErrorEditor onChange={onUpdate} query={query} ds={datasource} />}
|
||||||
|
{scenarioId === 'trace' && (
|
||||||
|
<InlineField labelWidth={14} label="Span count">
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
name="spanCount"
|
||||||
|
value={query.spanCount}
|
||||||
|
width={32}
|
||||||
|
onChange={onInputChange}
|
||||||
|
placeholder="10"
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
)}
|
||||||
|
|
||||||
{description && <p>{description}</p>}
|
{description && <p>{description}</p>}
|
||||||
</>
|
</>
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
TimeRange,
|
TimeRange,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
toDataFrame,
|
toDataFrame,
|
||||||
|
MutableDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { DataSourceWithBackend, getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
import { DataSourceWithBackend, getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
import { getSearchFilterScopedVar } from 'app/features/variables/utils';
|
import { getSearchFilterScopedVar } from 'app/features/variables/utils';
|
||||||
@ -70,6 +71,9 @@ export class TestDataDataSource extends DataSourceWithBackend<TestDataQuery> {
|
|||||||
case 'flame_graph':
|
case 'flame_graph':
|
||||||
streams.push(this.flameGraphQuery());
|
streams.push(this.flameGraphQuery());
|
||||||
break;
|
break;
|
||||||
|
case 'trace':
|
||||||
|
streams.push(this.trace(target, options));
|
||||||
|
break;
|
||||||
case 'raw_frame':
|
case 'raw_frame':
|
||||||
streams.push(this.rawFrameQuery(target, options));
|
streams.push(this.rawFrameQuery(target, options));
|
||||||
break;
|
break;
|
||||||
@ -224,6 +228,44 @@ export class TestDataDataSource extends DataSourceWithBackend<TestDataQuery> {
|
|||||||
return of({ data: [flameGraphData] }).pipe(delay(100));
|
return of({ data: [flameGraphData] }).pipe(delay(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace(target: TestDataQuery, options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
|
||||||
|
const frame = new MutableDataFrame({
|
||||||
|
meta: {
|
||||||
|
preferredVisualisationType: 'trace',
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{ name: 'traceID' },
|
||||||
|
{ name: 'spanID' },
|
||||||
|
{ name: 'parentSpanID' },
|
||||||
|
{ name: 'operationName' },
|
||||||
|
{ name: 'serviceName' },
|
||||||
|
{ name: 'serviceTags' },
|
||||||
|
{ name: 'startTime' },
|
||||||
|
{ name: 'duration' },
|
||||||
|
{ name: 'logs' },
|
||||||
|
{ name: 'references' },
|
||||||
|
{ name: 'tags' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const numberOfSpans = options.targets[0].spanCount || 10;
|
||||||
|
const spanIdPrefix = '75c665dfb68';
|
||||||
|
const start = Date.now() - 1000 * 60 * 30;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfSpans; i++) {
|
||||||
|
frame.add({
|
||||||
|
traceID: spanIdPrefix + '10000',
|
||||||
|
spanID: spanIdPrefix + (10000 + i),
|
||||||
|
parentSpanID: i === 0 ? '' : spanIdPrefix + 10000,
|
||||||
|
operationName: `Operation ${i}`,
|
||||||
|
serviceName: `Service ${i}`,
|
||||||
|
startTime: start + i * 100,
|
||||||
|
duration: 300,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return of({ data: [frame] }).pipe(delay(100));
|
||||||
|
}
|
||||||
|
|
||||||
rawFrameQuery(target: TestDataQuery, options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
|
rawFrameQuery(target: TestDataQuery, options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(target.rawFrameContent ?? '[]').map((v: any) => {
|
const data = JSON.parse(target.rawFrameContent ?? '[]').map((v: any) => {
|
||||||
|
@ -27,6 +27,7 @@ export interface TestDataQuery extends DataQuery {
|
|||||||
seriesCount?: number;
|
seriesCount?: number;
|
||||||
usa?: USAQuery;
|
usa?: USAQuery;
|
||||||
errorType?: 'server_panic' | 'frontend_exception' | 'frontend_observable';
|
errorType?: 'server_panic' | 'frontend_exception' | 'frontend_observable';
|
||||||
|
spanCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodesQuery {
|
export interface NodesQuery {
|
||||||
|
Loading…
Reference in New Issue
Block a user