@grafana/data#DataQueryResponse TypeScript Examples
The following examples show how to use
@grafana/data#DataQueryResponse.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
runInstantQuery = (
target: LokiQuery,
options: DataQueryRequest<LokiQuery>,
responseListLength: number
): Observable<DataQueryResponse> => {
const timeNs = this.getTime(options.range.to, true);
const query = {
query: parseQuery(target.expr).query,
time: `${timeNs + (1e9 - (timeNs % 1e9))}`,
limit: Math.min(options.maxDataPoints || Infinity, this.maxLines),
};
return this._request(INSTANT_QUERY_ENDPOINT, query).pipe(
catchError((err: any) => this.throwUnless(err, err.cancelled, target)),
filter((response: any) => (response.cancelled ? false : true)),
map((response: { data: LokiResponse }) => {
if (response.data.data.resultType === LokiResultType.Stream) {
throw new Error('Metrics mode does not support logs. Use an aggregation or switch to Logs mode.');
}
return {
data: [lokiResultsToTableModel(response.data.data.result, responseListLength, target.refId, true)],
key: `${target.refId}_instant`,
};
})
);
};
Example #2
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
private exploreQuery(queries: PromQueryRequest[], activeTargets: PromQuery[], end: number) {
let runningQueriesCount = queries.length;
const subQueries = queries.map((query, index) => {
const target = activeTargets[index];
let observable: Observable<any> = null;
if (query.instant) {
observable = from(this.performInstantQuery(query, end));
} else {
observable = from(this.performTimeSeriesQuery(query, query.start, query.end));
}
return observable.pipe(
// Decrease the counter here. We assume that each request returns only single value and then completes
// (should hold until there is some streaming requests involved).
tap(() => runningQueriesCount--),
filter((response: any) => (response.cancelled ? false : true)),
map((response: any) => {
const data = this.processResult(response, query, target, queries.length);
return {
data,
key: query.requestId,
state: runningQueriesCount === 0 ? LoadingState.Done : LoadingState.Loading,
} as DataQueryResponse;
})
);
});
return merge(...subQueries);
}
Example #3
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
async query(options: DataQueryRequest<StackdriverQuery>): Promise<DataQueryResponse> {
const result: DataQueryResponse[] = [];
const data = await this.getTimeSeries(options);
if (data.results) {
Object.values(data.results).forEach((queryRes: any) => {
if (!queryRes.series) {
return;
}
const unit = this.resolvePanelUnitFromTargets(options.targets);
queryRes.series.forEach((series: any) => {
let timeSerie: any = {
target: series.name,
datapoints: series.points,
refId: queryRes.refId,
meta: queryRes.meta,
};
if (unit) {
timeSerie = { ...timeSerie, unit };
}
result.push(timeSerie);
});
});
return { data: result };
} else {
return { data: [] };
}
}
Example #4
Source File: InputDatasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
query(options: DataQueryRequest<InputQuery>): Promise<DataQueryResponse> {
const results: DataFrame[] = [];
for (const query of options.targets) {
if (query.hide) {
continue;
}
let data = this.data;
if (query.data) {
data = query.data.map(v => toDataFrame(v));
}
for (let i = 0; i < data.length; i++) {
results.push({
...data[i],
refId: query.refId,
});
}
}
return Promise.resolve({ data: results });
}
Example #5
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
convertResponseToDataFrames = (result: any): DataQueryResponse => {
const data: DataFrame[] = [];
if (!result || !result.data) {
return { data };
}
// Series are either at the root or under a node called 'series'
const series = result.data.series || result.data;
if (!_.isArray(series)) {
throw { message: 'Missing series in result', data: result };
}
for (let i = 0; i < series.length; i++) {
const s = series[i];
for (let y = 0; y < s.datapoints.length; y++) {
s.datapoints[y][1] *= 1000;
}
const frame = toDataFrame(s);
// Metrictank metadata
if (s.meta) {
frame.meta = {
custom: {
request: result.data.meta, // info for the whole request
info: s.meta, // Array of metadata
},
};
}
data.push(frame);
}
return { data };
};
Example #6
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
async query(options: DataQueryRequest<GraphiteQuery>): Promise<DataQueryResponse> {
const graphOptions = {
from: this.translateTime(options.rangeRaw.from, false, options.timezone),
until: this.translateTime(options.rangeRaw.to, true, options.timezone),
targets: options.targets,
format: (options as any).format,
cacheTimeout: options.cacheTimeout || this.cacheTimeout,
maxDataPoints: options.maxDataPoints,
};
const params = this.buildGraphiteParams(graphOptions, options.scopedVars);
if (params.length === 0) {
return Promise.resolve({ data: [] });
}
if (this.isMetricTank) {
params.push('meta=true');
}
const httpOptions: any = {
method: 'POST',
url: '/render',
data: params.join('&'),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
this.addTracingHeaders(httpOptions, options);
if (options.panelId) {
httpOptions.requestId = this.name + '.panelId.' + options.panelId;
}
return this.doGraphiteRequest(httpOptions).then(this.convertResponseToDataFrames);
}
Example #7
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
runLegacyQuery = (
target: LokiQuery,
options: { range?: TimeRange; maxDataPoints?: number; reverse?: boolean }
): Observable<DataQueryResponse> => {
if (target.liveStreaming) {
return this.runLiveQuery(target, options);
}
const range = options.range
? { start: this.getTime(options.range.from, false), end: this.getTime(options.range.to, true) }
: {};
const query: LokiLegacyQueryRequest = {
...DEFAULT_QUERY_PARAMS,
...parseQuery(target.expr),
...range,
limit: Math.min(options.maxDataPoints || Infinity, this.maxLines),
refId: target.refId,
};
return this._request(LEGACY_QUERY_ENDPOINT, query).pipe(
catchError((err: any) => this.throwUnless(err, err.cancelled, target)),
filter((response: any) => !response.cancelled),
map((response: { data: LokiLegacyStreamResponse }) => ({
data: lokiLegacyStreamsToDataframes(
response.data,
query,
this.maxLines,
this.instanceSettings.jsonData,
options.reverse
),
key: `${target.refId}_log`,
}))
);
};
Example #8
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
processQueryResult(queries: any, res: any): DataQueryResponse {
const data: TestData[] = [];
let error: DataQueryError | undefined = undefined;
for (const query of queries) {
const results = res.data.results[query.refId];
for (const t of results.tables || []) {
const table = t as TableData;
table.refId = query.refId;
table.name = query.alias;
data.push(table);
}
for (const series of results.series || []) {
data.push({ target: series.name, datapoints: series.points, refId: query.refId, tags: series.tags });
}
if (results.error) {
error = {
message: results.error,
};
}
}
return { data, error };
}
Example #9
Source File: runStreams.ts From grafana-chinese with Apache License 2.0 | 6 votes |
export function runStream(target: TestDataQuery, req: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
const query = defaults(target.stream, defaultQuery);
if ('signal' === query.type) {
return runSignalStream(target, query, req);
}
if ('logs' === query.type) {
return runLogsStream(target, query, req);
}
if ('fetch' === query.type) {
return runFetchStream(target, query, req);
}
throw new Error(`Unknown Stream Type: ${query.type}`);
}
Example #10
Source File: metrics_panel_ctrl.ts From grafana-chinese with Apache License 2.0 | 6 votes |
handleQueryResult(result: DataQueryResponse) {
this.loading = false;
if (this.dashboard.snapshot) {
this.panel.snapshotData = result.data;
}
if (!result || !result.data) {
console.log('Data source query result invalid, missing data field:', result);
result = { data: [] };
}
try {
this.events.emit(PanelEvents.dataReceived, result.data);
} catch (err) {
this.processDataError(err);
}
}
Example #11
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
query(options: DataQueryRequest<PromQuery>): Observable<DataQueryResponse> {
const start = this.getPrometheusTime(options.range.from, false);
const end = this.getPrometheusTime(options.range.to, true);
const { queries, activeTargets } = this.prepareTargets(options, start, end);
// No valid targets, return the empty result to save a round trip.
if (!queries || !queries.length) {
return of({
data: [],
state: LoadingState.Done,
});
}
if (options.app === CoreApp.Explore) {
return this.exploreQuery(queries, activeTargets, end);
}
return this.panelsQuery(queries, activeTargets, end, options.requestId);
}
Example #12
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
/**
* Runs live queries which in this case means creating a websocket and listening on it for new logs.
* This returns a bit different dataFrame than runQueries as it returns single dataframe even if there are multiple
* Loki streams, sets only common labels on dataframe.labels and has additional dataframe.fields.labels for unique
* labels per row.
*/
runLiveQuery = (target: LokiQuery, options: { maxDataPoints?: number }): Observable<DataQueryResponse> => {
const liveTarget = this.createLiveTarget(target, options);
return from(this.getVersion()).pipe(
mergeMap(version =>
iif(
() => version === 'v1',
defer(() => this.streams.getStream(liveTarget)),
defer(() => {
const legacyTarget = this.createLegacyLiveTarget(target, options);
return this.streams.getLegacyStream(legacyTarget);
})
)
),
map(data => ({
data,
key: `loki-${liveTarget.refId}`,
state: LoadingState.Streaming,
}))
);
};
Example #13
Source File: datasource_srv.ts From grafana-chinese with Apache License 2.0 | 6 votes |
query(request: DataQueryRequest): Promise<DataQueryResponse> {
if (this.queryResolver) {
return this.queryResolver;
}
return new Promise(resolver => {
setTimeout(() => {
resolver(this.result);
});
});
}
Example #14
Source File: runRequest.test.ts From grafana-chinese with Apache License 2.0 | 6 votes |
reset() {
this.wasStarted = false;
this.isUnsubbed = false;
this.results = [];
this.request = {
range: {
from: this.fromStartTime,
to: this.toStartTime,
raw: { from: '1h', to: 'now' },
},
targets: [
{
refId: 'A',
},
],
} as DataQueryRequest;
this.ds = {
query: (request: DataQueryRequest) => {
return new Observable<DataQueryResponse>(subscriber => {
this.subscriber = subscriber;
this.wasStarted = true;
if (this.error) {
throw this.error;
}
return () => {
this.isUnsubbed = true;
};
});
},
} as DataSourceApi;
}
Example #15
Source File: MixedDataSource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
query(request: DataQueryRequest<DataQuery>): Observable<DataQueryResponse> {
// Remove any invalid queries
const queries = request.targets.filter(t => {
return t.datasource !== MIXED_DATASOURCE_NAME;
});
if (!queries.length) {
return of({ data: [] } as DataQueryResponse); // nothing
}
// Build groups of queries to run in parallel
const sets: { [key: string]: DataQuery[] } = groupBy(queries, 'datasource');
const mixed: BatchedQueries[] = [];
for (const key in sets) {
const targets = sets[key];
const dsName = targets[0].datasource;
mixed.push({
datasource: getDataSourceSrv().get(dsName),
targets,
});
}
return this.batchQueries(mixed, request);
}
Example #16
Source File: MixedDataSource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
batchQueries(mixed: BatchedQueries[], request: DataQueryRequest<DataQuery>): Observable<DataQueryResponse> {
const runningQueries = mixed.filter(this.isQueryable).map((query, i) =>
from(query.datasource).pipe(
mergeMap((api: DataSourceApi) => {
const dsRequest = cloneDeep(request);
dsRequest.requestId = `mixed-${i}-${dsRequest.requestId || ''}`;
dsRequest.targets = query.targets;
return from(api.query(dsRequest)).pipe(
map(response => {
return {
...response,
data: response.data || [],
state: LoadingState.Loading,
key: `mixed-${i}-${response.key || ''}`,
} as DataQueryResponse;
})
);
})
)
);
return forkJoin(runningQueries).pipe(map(this.markAsDone), mergeAll());
}
Example #17
Source File: DataSourceWithBackend.ts From grafana-chinese with Apache License 2.0 | 6 votes |
/**
* This makes the arrow library loading async.
*/
async toDataQueryResponse(rsp: any): Promise<DataQueryResponse> {
const { resultsToDataFrames } = await import(
/* webpackChunkName: "apache-arrow-util" */ '@grafana/data/src/dataframe/ArrowDataFrame'
);
return { data: resultsToDataFrames(rsp) };
}
Example #18
Source File: MixedDataSource.ts From grafana-chinese with Apache License 2.0 | 6 votes |
private markAsDone(responses: DataQueryResponse[]): DataQueryResponse[] {
const { length } = responses;
if (length === 0) {
return responses;
}
responses[length - 1].state = LoadingState.Done;
return responses;
}
Example #19
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 5 votes |
query(options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
const queries: any[] = [];
const streams: Array<Observable<DataQueryResponse>> = [];
// Start streams and prepare queries
for (const target of options.targets) {
if (target.hide) {
continue;
}
if (target.scenarioId === 'streaming_client') {
streams.push(runStream(target, options));
} else {
queries.push({
...target,
intervalMs: options.intervalMs,
maxDataPoints: options.maxDataPoints,
datasourceId: this.id,
alias: templateSrv.replace(target.alias || ''),
});
}
}
if (queries.length) {
const req: Promise<DataQueryResponse> = getBackendSrv()
.datasourceRequest({
method: 'POST',
url: '/api/tsdb/query',
data: {
from: options.range.from.valueOf().toString(),
to: options.range.to.valueOf().toString(),
queries: queries,
},
// This sets up a cancel token
requestId: options.requestId,
})
.then((res: any) => this.processQueryResult(queries, res));
streams.push(from(req));
}
return merge(...streams);
}
Example #20
Source File: datasource_srv.ts From grafana-chinese with Apache License 2.0 | 5 votes |
queryResolver: Promise<DataQueryResponse>;
Example #21
Source File: runStreams.ts From grafana-chinese with Apache License 2.0 | 5 votes |
export function runSignalStream(
target: TestDataQuery,
query: StreamingQuery,
req: DataQueryRequest<TestDataQuery>
): Observable<DataQueryResponse> {
return new Observable<DataQueryResponse>(subscriber => {
const streamId = `signal-${req.panelId}-${target.refId}`;
const maxDataPoints = req.maxDataPoints || 1000;
const data = new CircularDataFrame({
append: 'tail',
capacity: maxDataPoints,
});
data.refId = target.refId;
data.name = target.alias || 'Signal ' + target.refId;
data.addField({ name: 'time', type: FieldType.time });
data.addField({ name: 'value', type: FieldType.number });
const { spread, speed, bands, noise } = query;
for (let i = 0; i < bands; i++) {
const suffix = bands > 1 ? ` ${i + 1}` : '';
data.addField({ name: 'Min' + suffix, type: FieldType.number });
data.addField({ name: 'Max' + suffix, type: FieldType.number });
}
let value = Math.random() * 100;
let timeoutId: any = null;
const addNextRow = (time: number) => {
value += (Math.random() - 0.5) * spread;
let idx = 0;
data.fields[idx++].values.add(time);
data.fields[idx++].values.add(value);
let min = value;
let max = value;
for (let i = 0; i < bands; i++) {
min = min - Math.random() * noise;
max = max + Math.random() * noise;
data.fields[idx++].values.add(min);
data.fields[idx++].values.add(max);
}
};
// Fill the buffer on init
if (true) {
let time = Date.now() - maxDataPoints * speed;
for (let i = 0; i < maxDataPoints; i++) {
addNextRow(time);
time += speed;
}
}
const pushNextEvent = () => {
addNextRow(Date.now());
subscriber.next({
data: [data],
key: streamId,
});
timeoutId = setTimeout(pushNextEvent, speed);
};
// Send first event in 5ms
setTimeout(pushNextEvent, 5);
return () => {
console.log('unsubscribing to stream ' + streamId);
clearTimeout(timeoutId);
};
});
}
Example #22
Source File: runStreams.ts From grafana-chinese with Apache License 2.0 | 5 votes |
export function runLogsStream(
target: TestDataQuery,
query: StreamingQuery,
req: DataQueryRequest<TestDataQuery>
): Observable<DataQueryResponse> {
return new Observable<DataQueryResponse>(subscriber => {
const streamId = `logs-${req.panelId}-${target.refId}`;
const maxDataPoints = req.maxDataPoints || 1000;
const data = new CircularDataFrame({
append: 'tail',
capacity: maxDataPoints,
});
data.refId = target.refId;
data.name = target.alias || 'Logs ' + target.refId;
data.addField({ name: 'time', type: FieldType.time });
data.addField({ name: 'line', type: FieldType.string });
const { speed } = query;
let timeoutId: any = null;
const pushNextEvent = () => {
data.values.time.add(Date.now());
data.values.line.add(getRandomLine());
subscriber.next({
data: [data],
key: streamId,
});
timeoutId = setTimeout(pushNextEvent, speed);
};
// Send first event in 5ms
setTimeout(pushNextEvent, 5);
return () => {
console.log('unsubscribing to stream ' + streamId);
clearTimeout(timeoutId);
};
});
}
Example #23
Source File: runStreams.ts From grafana-chinese with Apache License 2.0 | 5 votes |
export function runFetchStream(
target: TestDataQuery,
query: StreamingQuery,
req: DataQueryRequest<TestDataQuery>
): Observable<DataQueryResponse> {
return new Observable<DataQueryResponse>(subscriber => {
const streamId = `fetch-${req.panelId}-${target.refId}`;
const maxDataPoints = req.maxDataPoints || 1000;
let data = new CircularDataFrame({
append: 'tail',
capacity: maxDataPoints,
});
data.refId = target.refId;
data.name = target.alias || 'Fetch ' + target.refId;
let reader: ReadableStreamReader<Uint8Array>;
const csv = new CSVReader({
callback: {
onHeader: (fields: Field[]) => {
// Clear any existing fields
if (data.fields.length) {
data = new CircularDataFrame({
append: 'tail',
capacity: maxDataPoints,
});
data.refId = target.refId;
data.name = 'Fetch ' + target.refId;
}
for (const field of fields) {
data.addField(field);
}
},
onRow: (row: any[]) => {
data.add(row);
},
},
});
const processChunk = (value: ReadableStreamReadResult<Uint8Array>): any => {
if (value.value) {
const text = new TextDecoder().decode(value.value);
csv.readCSV(text);
}
subscriber.next({
data: [data],
key: streamId,
state: value.done ? LoadingState.Done : LoadingState.Streaming,
});
if (value.done) {
console.log('Finished stream');
subscriber.complete(); // necessary?
return;
}
return reader.read().then(processChunk);
};
fetch(new Request(query.url)).then(response => {
reader = response.body.getReader();
reader.read().then(processChunk);
});
return () => {
// Cancel fetch?
console.log('unsubscribing to stream ' + streamId);
};
});
}
Example #24
Source File: datasource_srv.ts From grafana-chinese with Apache License 2.0 | 5 votes |
constructor(name?: string, result?: DataQueryResponse, meta?: any) {
super({ name: name ? name : 'MockDataSourceApi' } as DataSourceInstanceSettings);
if (result) {
this.result = result;
}
this.meta = meta || ({} as DataSourcePluginMeta);
}
Example #25
Source File: datasource_srv.ts From grafana-chinese with Apache License 2.0 | 5 votes |
result: DataQueryResponse = { data: [] };
Example #26
Source File: datasource.ts From grafana-kdb-datasource-ws with Apache License 2.0 | 5 votes |
query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
var prefilterResultCount = options.targets.length;
if (prefilterResultCount == 0) {
return new Promise((resolve) => {
resolve({ data: [] });
});
}
var allRefIDs = [];
var blankRefIDs = [];
var validRequestList = [];
var errorList = [];
for (var i = 0; i < prefilterResultCount; i++) {
//Inject variables into target
this.injectVariables(options.targets[i], options.scopedVars, options.range);
// for some reason randomWalk is defaulted
if (options.targets[i].queryType == 'randomWalk') {
options.targets[i].queryType = 'selectQuery';
}
allRefIDs.push(options.targets[i].refId);
options.targets[i].range = options.range;
if (
(!options.targets[i].table && options.targets[i].queryType === 'selectQuery') ||
(options.targets[i].queryType === 'functionQuery' && options.targets[i].kdbFunction === '') ||
options.targets[i].hide === true
) {
blankRefIDs.push(options.targets[i].refId);
} else if (!options.targets[i].queryError) {
blankRefIDs.push(options.targets[i].refId);
} else if (options.targets[i].queryError.error.indexOf(true) !== -1) {
errorList.push({
refId: options.targets[i].refId,
errorMessage: options.targets[i].queryError.message[options.targets[i].queryError.error.indexOf(true)],
});
} else validRequestList.push(options.targets[i]);
}
var nrBlankRequests = blankRefIDs.length;
var requestList = validRequestList.map((target) => {
return this.buildKdbRequest(target);
});
var nrRequests: number = requestList.length;
if (!this.ws || this.ws.readyState > 1)
return this.connectWS().then((connectStatus) => {
if (connectStatus === true && nrRequests > 0)
return this.sendQueries(nrRequests, requestList, nrBlankRequests, blankRefIDs, errorList).then(
(series: any) => {
return this.buildDataFrames(series);
}
);
else if (connectStatus === true && nrRequests === 0)
return this.emptyQueries(nrBlankRequests, blankRefIDs, errorList).then(() => {
return { data: [] };
});
else
return this.connectFail(prefilterResultCount, allRefIDs).then(() => {
return { data: [] };
});
});
else {
return this.webSocketWait().then(() => {
if (nrRequests > 0)
return this.sendQueries(nrRequests, requestList, nrBlankRequests, blankRefIDs, errorList).then(
(series: any) => {
return this.buildDataFrames(series);
}
);
else
return this.emptyQueries(nrBlankRequests, blankRefIDs, errorList).then(() => {
return { data: [] };
});
});
}
}
Example #27
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 5 votes |
/**
* Attempts to send a query to /loki/api/v1/query_range but falls back to the legacy endpoint if necessary.
*/
runRangeQueryWithFallback = (
target: LokiQuery,
options: RangeQueryOptions,
responseListLength = 1
): Observable<DataQueryResponse> => {
// target.maxLines value already preprocessed
// available cases:
// 1) empty input -> mapped to NaN, falls back to dataSource.maxLines limit
// 2) input with at least 1 character and that is either incorrect (value in the input field is not a number) or negative
// - mapped to 0, falls back to the limit of 0 lines
// 3) default case - correct input, mapped to the value from the input field
let linesLimit = 0;
if (target.maxLines === undefined) {
// no target.maxLines, using options.maxDataPoints
linesLimit = Math.min(options.maxDataPoints || Infinity, this.maxLines);
} else {
// using target.maxLines
if (isNaN(target.maxLines)) {
linesLimit = this.maxLines;
} else {
linesLimit = target.maxLines;
}
}
const queryOptions = { ...options, maxDataPoints: linesLimit };
if (target.liveStreaming) {
return this.runLiveQuery(target, queryOptions);
}
const query = this.createRangeQuery(target, queryOptions);
return this._request(RANGE_QUERY_ENDPOINT, query).pipe(
catchError((err: any) => this.throwUnless(err, err.cancelled || err.status === 404, target)),
filter((response: any) => (response.cancelled ? false : true)),
switchMap((response: { data: LokiResponse; status: number }) =>
iif<DataQueryResponse, DataQueryResponse>(
() => response.status === 404,
defer(() => this.runLegacyQuery(target, queryOptions)),
defer(() =>
processRangeQueryResponse(
response.data,
target,
query,
responseListLength,
linesLimit,
this.instanceSettings.jsonData,
options.reverse
)
)
)
)
);
};
Example #28
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 5 votes |
testDatasource() {
// Consider only last 10 minutes otherwise request takes too long
const startMs = Date.now() - 10 * 60 * 1000;
const start = `${startMs}000000`; // API expects nanoseconds
return this._request('/loki/api/v1/label', { start })
.pipe(
catchError((err: any) => {
if (err.status === 404) {
return of(err);
}
throw err;
}),
switchMap((response: { data: { values: string[] }; status: number }) =>
iif<DataQueryResponse, any>(
() => response.status === 404,
defer(() => this._request('/api/prom/label', { start })),
defer(() => of(response))
)
),
map(res => {
const values: any[] = res?.data?.data || res?.data?.values || [];
const testResult =
values.length > 0
? { status: 'success', message: 'Data source connected and labels found.' }
: {
status: 'error',
message:
'Data source connected, but no labels received. Verify that Loki and Promtail is configured properly.',
};
return testResult;
}),
catchError((err: any) => {
let message = 'Loki: ';
if (err.statusText) {
message += err.statusText;
} else {
message += 'Cannot connect to Loki';
}
if (err.status) {
message += `. ${err.status}`;
}
if (err.data && err.data.message) {
message += `. ${err.data.message}`;
} else if (err.data) {
message += `. ${err.data}`;
}
return of({ status: 'error', message: message });
})
)
.toPromise();
}
Example #29
Source File: datasource.ts From grafana-chinese with Apache License 2.0 | 5 votes |
query(options: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> {
const subQueries: Array<Observable<DataQueryResponse>> = [];
const filteredTargets = options.targets
.filter(target => target.expr && !target.hide)
.map(target => ({
...target,
expr: this.templateSrv.replace(target.expr, options.scopedVars, this.interpolateQueryExpr),
}));
if (options.exploreMode === ExploreMode.Metrics) {
filteredTargets.forEach(target =>
subQueries.push(
this.runInstantQuery(target, options, filteredTargets.length),
this.runRangeQueryWithFallback(target, options, filteredTargets.length)
)
);
} else {
filteredTargets.forEach(target =>
subQueries.push(
this.runRangeQueryWithFallback(target, options, filteredTargets.length).pipe(
map(dataQueryResponse => {
if (options.exploreMode === ExploreMode.Logs && dataQueryResponse.data.find(d => isTimeSeries(d))) {
throw new Error(
'Logs mode does not support queries that return time series data. Please perform a logs query or switch to Metrics mode.'
);
} else {
return dataQueryResponse;
}
})
)
)
);
}
// No valid targets, return the empty result to save a round trip.
if (isEmpty(subQueries)) {
return of({
data: [],
state: LoadingState.Done,
});
}
return merge(...subQueries);
}