mirror of https://github.com/grafana/grafana.git
Typescript: Removes implicit anys (#17625)
* Chore: Remove implicit anys from ResultProcessor and tests * Chore: Removes implicit anys for /loki/**/*.ts * Chore: Removes implicit anys for prometheus/**/*
This commit is contained in:
parent
d6ee96ee64
commit
3424b64299
|
|
@ -11,7 +11,7 @@ jest.mock('@grafana/ui/src/utils/moment_wrapper', () => ({
|
|||
import { ResultProcessor } from './ResultProcessor';
|
||||
import { ExploreItemState, ExploreMode } from 'app/types/explore';
|
||||
import TableModel from 'app/core/table_model';
|
||||
import { toFixed } from '@grafana/ui';
|
||||
import { toFixed, TimeSeries, LogRowModel, LogsMetaItem } from '@grafana/ui';
|
||||
|
||||
const testContext = (options: any = {}) => {
|
||||
const response = [
|
||||
|
|
@ -47,9 +47,9 @@ const testContext = (options: any = {}) => {
|
|||
mode: ExploreMode.Metrics,
|
||||
replacePreviousResults: true,
|
||||
result: { data: response },
|
||||
graphResult: [],
|
||||
graphResult: [] as TimeSeries[],
|
||||
tableResult: new TableModel(),
|
||||
logsResult: { hasUniqueLabels: false, rows: [] },
|
||||
logsResult: { hasUniqueLabels: false, rows: [] as LogRowModel[] },
|
||||
};
|
||||
const combinedOptions = { ...defaultOptions, ...options };
|
||||
const state = ({
|
||||
|
|
@ -174,7 +174,7 @@ describe('ResultProcessor', () => {
|
|||
labels: undefined,
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a message',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1559038519831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -187,7 +187,7 @@ describe('ResultProcessor', () => {
|
|||
labels: undefined,
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a message',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1559038518831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -317,7 +317,7 @@ describe('ResultProcessor', () => {
|
|||
labels: { cluster: 'some-cluster' },
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a previous message 1',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1558038519831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -331,7 +331,7 @@ describe('ResultProcessor', () => {
|
|||
labels: { cluster: 'some-cluster' },
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a previous message 2',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1558038518831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -362,7 +362,7 @@ describe('ResultProcessor', () => {
|
|||
const theResult = resultProcessor.getLogsResult();
|
||||
const expected = {
|
||||
hasUniqueLabels: false,
|
||||
meta: [],
|
||||
meta: [] as LogsMetaItem[],
|
||||
rows: [
|
||||
{
|
||||
entry: 'This is a previous message 1',
|
||||
|
|
@ -371,7 +371,7 @@ describe('ResultProcessor', () => {
|
|||
labels: { cluster: 'some-cluster' },
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a previous message 1',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1558038519831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -385,7 +385,7 @@ describe('ResultProcessor', () => {
|
|||
labels: { cluster: 'some-cluster' },
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a previous message 2',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1558038518831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -399,7 +399,7 @@ describe('ResultProcessor', () => {
|
|||
labels: undefined,
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a message',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1559038519831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -413,7 +413,7 @@ describe('ResultProcessor', () => {
|
|||
labels: undefined,
|
||||
logLevel: 'unknown',
|
||||
raw: 'This is a message',
|
||||
searchWords: [],
|
||||
searchWords: [] as string[],
|
||||
timeEpochMs: 1559038518831,
|
||||
timeFromNow: 'fromNow() jest mocked',
|
||||
timeLocal: 'format() jest mocked',
|
||||
|
|
@ -440,7 +440,7 @@ describe('ResultProcessor', () => {
|
|||
[39.91264531864214, 1559038518831],
|
||||
[40.35179822906545, 1559038519831],
|
||||
],
|
||||
unit: undefined,
|
||||
unit: undefined as string,
|
||||
valueFormater: toFixed,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export class ResultProcessor {
|
|||
return new TableModel();
|
||||
}
|
||||
|
||||
const prevTableResults = this.state.tableResult || [];
|
||||
const prevTableResults: any[] | TableModel = this.state.tableResult || [];
|
||||
const tablesToMerge = this.replacePreviousResults ? this.tables : [].concat(prevTableResults, this.tables);
|
||||
|
||||
return mergeTablesIntoModel(new TableModel(), ...tablesToMerge);
|
||||
|
|
@ -116,13 +116,17 @@ export class ResultProcessor {
|
|||
|
||||
private isSameTimeSeries = (a: TimeSeries | TimeSeries2, b: TimeSeries | TimeSeries2) => {
|
||||
if (a.hasOwnProperty('id') && b.hasOwnProperty('id')) {
|
||||
if (a['id'] !== undefined && b['id'] !== undefined && a['id'] === b['id']) {
|
||||
const aValue = (a as TimeSeries2).id;
|
||||
const bValue = (b as TimeSeries2).id;
|
||||
if (aValue !== undefined && bValue !== undefined && aValue === bValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (a.hasOwnProperty('alias') && b.hasOwnProperty('alias')) {
|
||||
if (a['alias'] !== undefined && b['alias'] !== undefined && a['alias'] === b['alias']) {
|
||||
const aValue = (a as TimeSeries2).alias;
|
||||
const bValue = (b as TimeSeries2).alias;
|
||||
if (aValue !== undefined && bValue !== undefined && aValue === bValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import LokiDatasource from './datasource';
|
||||
import { LokiQuery } from './types';
|
||||
import { getQueryOptions } from 'test/helpers/getQueryOptions';
|
||||
import { SeriesData } from '@grafana/ui';
|
||||
import { SeriesData, DataSourceApi } from '@grafana/ui';
|
||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
|
|
@ -26,8 +26,8 @@ describe('LokiDatasource', () => {
|
|||
const backendSrv = (backendSrvMock as unknown) as BackendSrv;
|
||||
|
||||
const templateSrvMock = ({
|
||||
getAdhocFilters: () => [],
|
||||
replace: a => a,
|
||||
getAdhocFilters: (): any[] => [],
|
||||
replace: (a: string) => a,
|
||||
} as unknown) as TemplateSrv;
|
||||
|
||||
test('should use default max lines when no limit given', () => {
|
||||
|
|
@ -75,8 +75,8 @@ describe('LokiDatasource', () => {
|
|||
});
|
||||
|
||||
describe('when performing testDataSource', () => {
|
||||
let ds;
|
||||
let result;
|
||||
let ds: DataSourceApi<any, any>;
|
||||
let result: any;
|
||||
|
||||
describe('and call succeeds', () => {
|
||||
beforeEach(async () => {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import {
|
|||
DataStreamObserver,
|
||||
LoadingState,
|
||||
DataStreamState,
|
||||
DataQueryResponse,
|
||||
DateTime,
|
||||
} from '@grafana/ui';
|
||||
import { LokiQuery, LokiOptions } from './types';
|
||||
import { BackendSrv } from 'app/core/services/backend_srv';
|
||||
|
|
@ -70,7 +72,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||
this.subscriptions = {};
|
||||
}
|
||||
|
||||
_request(apiUrl: string, data?, options?: any) {
|
||||
_request(apiUrl: string, data?: any, options?: any) {
|
||||
const baseUrl = this.instanceSettings.url;
|
||||
const params = data ? serializeParams(data) : '';
|
||||
const url = `${baseUrl}${apiUrl}?${params}`;
|
||||
|
|
@ -254,11 +256,11 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||
return this.languageProvider.importQueries(queries, originMeta.id);
|
||||
}
|
||||
|
||||
metadataRequest(url) {
|
||||
metadataRequest(url: string) {
|
||||
// HACK to get label values for {job=|}, will be replaced when implementing LokiQueryField
|
||||
const apiUrl = url.replace('v1', 'prom');
|
||||
return this._request(apiUrl, { silent: true }).then(res => {
|
||||
const data = { data: { data: res.data.values || [] } };
|
||||
return this._request(apiUrl, { silent: true }).then((res: DataQueryResponse) => {
|
||||
const data: any = { data: { data: res.data.values || [] } };
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
|
@ -282,7 +284,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||
return getHighlighterExpressionsFromQuery(query.expr);
|
||||
}
|
||||
|
||||
getTime(date, roundUp) {
|
||||
getTime(date: string | DateTime, roundUp: boolean) {
|
||||
if (_.isString(date)) {
|
||||
date = dateMath.parse(date, roundUp);
|
||||
}
|
||||
|
|
@ -357,7 +359,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||
|
||||
testDatasource() {
|
||||
return this._request('/api/prom/label')
|
||||
.then(res => {
|
||||
.then((res: DataQueryResponse) => {
|
||||
if (res && res.data && res.data.values && res.data.values.length > 0) {
|
||||
return { status: 'success', message: 'Data source connected and labels found.' };
|
||||
}
|
||||
|
|
@ -367,7 +369,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
|||
'Data source connected, but no labels received. Verify that Loki and Promtail is configured properly.',
|
||||
};
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err: any) => {
|
||||
let message = 'Loki: ';
|
||||
if (err.statusText) {
|
||||
message += err.statusText;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// @ts-ignore
|
||||
import Plain from 'slate-plain-serializer';
|
||||
|
||||
import LanguageProvider, { LABEL_REFRESH_INTERVAL } from './language_provider';
|
||||
import { advanceTo, clear, advanceBy } from 'jest-date-mock';
|
||||
import { beforeEach } from 'test/lib/common';
|
||||
import { DataQueryResponseData } from '@grafana/ui';
|
||||
|
||||
describe('Language completion provider', () => {
|
||||
const datasource = {
|
||||
metadataRequest: () => ({ data: { data: [] } }),
|
||||
metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }),
|
||||
};
|
||||
|
||||
describe('empty query suggestions', () => {
|
||||
|
|
@ -91,7 +93,7 @@ describe('Language completion provider', () => {
|
|||
|
||||
describe('Query imports', () => {
|
||||
const datasource = {
|
||||
metadataRequest: () => ({ data: { data: [] } }),
|
||||
metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }),
|
||||
};
|
||||
|
||||
it('returns empty queries for unknown origin datasource', async () => {
|
||||
|
|
@ -109,7 +111,8 @@ describe('Query imports', () => {
|
|||
|
||||
it('returns empty query from selector query if label is not available', async () => {
|
||||
const datasourceWithLabels = {
|
||||
metadataRequest: url => (url === '/api/prom/label' ? { data: { data: ['other'] } } : { data: { data: [] } }),
|
||||
metadataRequest: (url: string) =>
|
||||
url === '/api/prom/label' ? { data: { data: ['other'] } } : { data: { data: [] as DataQueryResponseData[] } },
|
||||
};
|
||||
const instance = new LanguageProvider(datasourceWithLabels);
|
||||
const result = await instance.importPrometheusQuery('{foo="bar"}');
|
||||
|
|
@ -118,7 +121,8 @@ describe('Query imports', () => {
|
|||
|
||||
it('returns selector query from selector query with common labels', async () => {
|
||||
const datasourceWithLabels = {
|
||||
metadataRequest: url => (url === '/api/prom/label' ? { data: { data: ['foo'] } } : { data: { data: [] } }),
|
||||
metadataRequest: (url: string) =>
|
||||
url === '/api/prom/label' ? { data: { data: ['foo'] } } : { data: { data: [] as DataQueryResponseData[] } },
|
||||
};
|
||||
const instance = new LanguageProvider(datasourceWithLabels);
|
||||
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
|
||||
|
|
@ -127,7 +131,10 @@ describe('Query imports', () => {
|
|||
|
||||
it('returns selector query from selector query with all labels if logging label list is empty', async () => {
|
||||
const datasourceWithLabels = {
|
||||
metadataRequest: url => (url === '/api/prom/label' ? { data: { data: [] } } : { data: { data: [] } }),
|
||||
metadataRequest: (url: string) =>
|
||||
url === '/api/prom/label'
|
||||
? { data: { data: [] as DataQueryResponseData[] } }
|
||||
: { data: { data: [] as DataQueryResponseData[] } },
|
||||
};
|
||||
const instance = new LanguageProvider(datasourceWithLabels);
|
||||
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
|
||||
|
|
@ -138,7 +145,7 @@ describe('Query imports', () => {
|
|||
|
||||
describe('Labels refresh', () => {
|
||||
const datasource = {
|
||||
metadataRequest: () => ({ data: { data: [] } }),
|
||||
metadataRequest: () => ({ data: { data: [] as DataQueryResponseData[] } }),
|
||||
};
|
||||
const instance = new LanguageProvider(datasource);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export function addLabelToQuery(query: string, key: string, value: string, opera
|
|||
}
|
||||
|
||||
// Add empty selectors to bare metric names
|
||||
let previousWord;
|
||||
let previousWord: string;
|
||||
query = query.replace(metricNameRegexp, (match, word, offset) => {
|
||||
const insideSelector = isPositionInsideChars(query, offset, '{', '}');
|
||||
// Handle "sum by (key) (metric)"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,24 @@
|
|||
import { PrometheusDatasource } from './datasource';
|
||||
import _ from 'lodash';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
export interface CompleterPosition {
|
||||
row: number;
|
||||
column: number;
|
||||
}
|
||||
|
||||
export interface CompleterToken {
|
||||
type: string;
|
||||
value: string;
|
||||
row: number;
|
||||
column: number;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export interface CompleterSession {
|
||||
getTokenAt: (row: number, column: number) => CompleterToken;
|
||||
getTokens: (row: number) => CompleterToken[];
|
||||
}
|
||||
|
||||
export class PromCompleter {
|
||||
labelQueryCache: any;
|
||||
|
|
@ -9,11 +28,11 @@ export class PromCompleter {
|
|||
|
||||
identifierRegexps = [/\[/, /[a-zA-Z0-9_:]/];
|
||||
|
||||
constructor(private datasource: PrometheusDatasource, private templateSrv) {
|
||||
constructor(private datasource: PrometheusDatasource, private templateSrv: TemplateSrv) {
|
||||
this.labelQueryCache = {};
|
||||
this.labelNameCache = {};
|
||||
this.labelValueCache = {};
|
||||
this.templateVariableCompletions = this.templateSrv.variables.map(variable => {
|
||||
this.templateVariableCompletions = this.templateSrv.variables.map((variable: any) => {
|
||||
return {
|
||||
caption: '$' + variable.name,
|
||||
value: '$' + variable.name,
|
||||
|
|
@ -23,8 +42,8 @@ export class PromCompleter {
|
|||
});
|
||||
}
|
||||
|
||||
getCompletions(editor, session, pos, prefix, callback) {
|
||||
const wrappedCallback = (err, completions) => {
|
||||
getCompletions(editor: any, session: CompleterSession, pos: CompleterPosition, prefix: string, callback: Function) {
|
||||
const wrappedCallback = (err: any, completions: any[]) => {
|
||||
completions = completions.concat(this.templateVariableCompletions);
|
||||
return callback(err, completions);
|
||||
};
|
||||
|
|
@ -79,7 +98,7 @@ export class PromCompleter {
|
|||
|
||||
const query = prefix;
|
||||
|
||||
return this.datasource.performSuggestQuery(query, true).then(metricNames => {
|
||||
return this.datasource.performSuggestQuery(query, true).then((metricNames: string[]) => {
|
||||
wrappedCallback(
|
||||
null,
|
||||
metricNames.map(name => {
|
||||
|
|
@ -98,7 +117,7 @@ export class PromCompleter {
|
|||
});
|
||||
}
|
||||
|
||||
getCompletionsForLabelMatcherName(session, pos) {
|
||||
getCompletionsForLabelMatcherName(session: CompleterSession, pos: CompleterPosition) {
|
||||
const metricName = this.findMetricName(session, pos.row, pos.column);
|
||||
if (!metricName) {
|
||||
return Promise.resolve(this.transformToCompletions(['__name__', 'instance', 'job'], 'label name'));
|
||||
|
|
@ -112,7 +131,7 @@ export class PromCompleter {
|
|||
const labelNames = this.transformToCompletions(
|
||||
_.uniq(
|
||||
_.flatten(
|
||||
result.map(r => {
|
||||
result.map((r: any) => {
|
||||
return Object.keys(r);
|
||||
})
|
||||
)
|
||||
|
|
@ -124,7 +143,7 @@ export class PromCompleter {
|
|||
});
|
||||
}
|
||||
|
||||
getCompletionsForLabelMatcherValue(session, pos) {
|
||||
getCompletionsForLabelMatcherValue(session: CompleterSession, pos: CompleterPosition) {
|
||||
const metricName = this.findMetricName(session, pos.row, pos.column);
|
||||
if (!metricName) {
|
||||
return Promise.resolve([]);
|
||||
|
|
@ -150,7 +169,7 @@ export class PromCompleter {
|
|||
return this.getLabelNameAndValueForExpression(metricName, 'metricName').then(result => {
|
||||
const labelValues = this.transformToCompletions(
|
||||
_.uniq(
|
||||
result.map(r => {
|
||||
result.map((r: any) => {
|
||||
return r[labelName];
|
||||
})
|
||||
),
|
||||
|
|
@ -162,12 +181,12 @@ export class PromCompleter {
|
|||
});
|
||||
}
|
||||
|
||||
getCompletionsForBinaryOperator(session, pos) {
|
||||
getCompletionsForBinaryOperator(session: CompleterSession, pos: CompleterPosition) {
|
||||
const keywordOperatorToken = this.findToken(session, pos.row, pos.column, 'keyword.control', null, 'identifier');
|
||||
if (!keywordOperatorToken) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
let rparenToken, expr;
|
||||
let rparenToken: CompleterToken, expr: string;
|
||||
switch (keywordOperatorToken.value) {
|
||||
case 'by':
|
||||
case 'without':
|
||||
|
|
@ -190,7 +209,7 @@ export class PromCompleter {
|
|||
const labelNames = this.transformToCompletions(
|
||||
_.uniq(
|
||||
_.flatten(
|
||||
result.map(r => {
|
||||
result.map((r: any) => {
|
||||
return Object.keys(r);
|
||||
})
|
||||
)
|
||||
|
|
@ -232,7 +251,7 @@ export class PromCompleter {
|
|||
const labelNames = this.transformToCompletions(
|
||||
_.uniq(
|
||||
_.flatten(
|
||||
result.map(r => {
|
||||
result.map((r: any) => {
|
||||
return Object.keys(r);
|
||||
})
|
||||
)
|
||||
|
|
@ -248,7 +267,7 @@ export class PromCompleter {
|
|||
const labelNames = this.transformToCompletions(
|
||||
_.uniq(
|
||||
_.flatten(
|
||||
result.map(r => {
|
||||
result.map((r: any) => {
|
||||
return Object.keys(r);
|
||||
})
|
||||
)
|
||||
|
|
@ -278,27 +297,27 @@ export class PromCompleter {
|
|||
}
|
||||
const { start, end } = this.datasource.getTimeRange();
|
||||
const url = '/api/v1/series?match[]=' + encodeURIComponent(query) + '&start=' + start + '&end=' + end;
|
||||
return this.datasource.metadataRequest(url).then(response => {
|
||||
return this.datasource.metadataRequest(url).then((response: any) => {
|
||||
this.labelQueryCache[expr] = response.data.data;
|
||||
return response.data.data;
|
||||
});
|
||||
}
|
||||
|
||||
transformToCompletions(words, meta) {
|
||||
transformToCompletions(words: string[], meta: any) {
|
||||
return words.map(name => {
|
||||
return {
|
||||
caption: name,
|
||||
value: name,
|
||||
meta: meta,
|
||||
meta,
|
||||
score: Number.MAX_VALUE,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
findMetricName(session, row, column) {
|
||||
findMetricName(session: CompleterSession, row: number, column: number) {
|
||||
let metricName = '';
|
||||
|
||||
let tokens;
|
||||
let tokens: CompleterToken[];
|
||||
const nameLabelNameToken = this.findToken(
|
||||
session,
|
||||
row,
|
||||
|
|
@ -324,11 +343,11 @@ export class PromCompleter {
|
|||
return metricName;
|
||||
}
|
||||
|
||||
findToken(session, row, column, target, value, guard) {
|
||||
let tokens, idx;
|
||||
findToken(session: CompleterSession, row: number, column: number, target: string, value: string, guard: string) {
|
||||
let tokens: CompleterToken[], idx: number;
|
||||
// find index and get column of previous token
|
||||
for (let r = row; r >= 0; r--) {
|
||||
let c;
|
||||
let c: number;
|
||||
tokens = session.getTokens(r);
|
||||
if (r === row) {
|
||||
// current row
|
||||
|
|
@ -368,8 +387,8 @@ export class PromCompleter {
|
|||
return null;
|
||||
}
|
||||
|
||||
findExpressionMatchedParen(session, row, column) {
|
||||
let tokens, idx;
|
||||
findExpressionMatchedParen(session: CompleterSession, row: number, column: number) {
|
||||
let tokens: CompleterToken[], idx: number;
|
||||
let deep = 1;
|
||||
let expression = ')';
|
||||
for (let r = row; r >= 0; r--) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ export class PrometheusConfigCtrl {
|
|||
current: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope) {
|
||||
constructor($scope: any) {
|
||||
this.current.jsonData.httpMethod = this.current.jsonData.httpMethod || 'GET';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,24 @@ import {
|
|||
DataQueryError,
|
||||
DataStreamObserver,
|
||||
LoadingState,
|
||||
DataQueryResponseData,
|
||||
} from '@grafana/ui/src/types';
|
||||
import { ExploreUrlState } from 'app/types/explore';
|
||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TimeRange } from '@grafana/ui/src';
|
||||
import { TimeRange, DateTime } from '@grafana/ui/src';
|
||||
|
||||
export interface PromDataQueryResponse {
|
||||
data: {
|
||||
status: string;
|
||||
data: {
|
||||
resultType: string;
|
||||
results?: DataQueryResponseData[];
|
||||
result?: DataQueryResponseData[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
||||
type: string;
|
||||
|
|
@ -106,7 +118,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
}
|
||||
} else {
|
||||
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
options.transformRequest = data => {
|
||||
options.transformRequest = (data: any) => {
|
||||
return $.param(data);
|
||||
};
|
||||
options.data = data;
|
||||
|
|
@ -279,9 +291,9 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
});
|
||||
|
||||
const allPromise = this.$q.all(allQueryPromise).then((responseList: any) => {
|
||||
let result = [];
|
||||
let result: any[] = [];
|
||||
|
||||
_.each(responseList, (response, index) => {
|
||||
_.each(responseList, (response, index: number) => {
|
||||
if (response.cancelled) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -361,7 +373,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
return query;
|
||||
}
|
||||
|
||||
adjustInterval(interval, minInterval, range, intervalFactor) {
|
||||
adjustInterval(interval: number, minInterval: number, range: number, intervalFactor: number) {
|
||||
// Prometheus will drop queries that might return more than 11000 data points.
|
||||
// Calibrate interval if it is too small.
|
||||
if (interval !== 0 && range / intervalFactor / interval > 11000) {
|
||||
|
|
@ -370,35 +382,39 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
return Math.max(interval * intervalFactor, minInterval, 1);
|
||||
}
|
||||
|
||||
performTimeSeriesQuery(query, start, end) {
|
||||
performTimeSeriesQuery(query: PromQueryRequest, start: number, end: number) {
|
||||
if (start > end) {
|
||||
throw { message: 'Invalid time range' };
|
||||
}
|
||||
|
||||
const url = '/api/v1/query_range';
|
||||
const data = {
|
||||
const data: any = {
|
||||
query: query.expr,
|
||||
start: start,
|
||||
end: end,
|
||||
start,
|
||||
end,
|
||||
step: query.step,
|
||||
};
|
||||
|
||||
if (this.queryTimeout) {
|
||||
data['timeout'] = this.queryTimeout;
|
||||
}
|
||||
|
||||
return this._request(url, data, { requestId: query.requestId, headers: query.headers }).catch((err: any) =>
|
||||
this.handleErrors(err, query)
|
||||
);
|
||||
}
|
||||
|
||||
performInstantQuery(query, time) {
|
||||
performInstantQuery(query: PromQueryRequest, time: number) {
|
||||
const url = '/api/v1/query';
|
||||
const data = {
|
||||
const data: any = {
|
||||
query: query.expr,
|
||||
time: time,
|
||||
time,
|
||||
};
|
||||
|
||||
if (this.queryTimeout) {
|
||||
data['timeout'] = this.queryTimeout;
|
||||
}
|
||||
|
||||
return this._request(url, data, { requestId: query.requestId, headers: query.headers }).catch((err: any) =>
|
||||
this.handleErrors(err, query)
|
||||
);
|
||||
|
|
@ -432,7 +448,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
throw error;
|
||||
};
|
||||
|
||||
performSuggestQuery(query, cache = false) {
|
||||
performSuggestQuery(query: string, cache = false) {
|
||||
const url = '/api/v1/label/__name__/values';
|
||||
|
||||
if (cache && this.metricsNameCache && this.metricsNameCache.expire > Date.now()) {
|
||||
|
|
@ -443,7 +459,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
);
|
||||
}
|
||||
|
||||
return this.metadataRequest(url).then(result => {
|
||||
return this.metadataRequest(url).then((result: PromDataQueryResponse) => {
|
||||
this.metricsNameCache = {
|
||||
data: result.data.data,
|
||||
expire: Date.now() + 60 * 1000,
|
||||
|
|
@ -454,7 +470,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
});
|
||||
}
|
||||
|
||||
metricFindQuery(query) {
|
||||
metricFindQuery(query: string) {
|
||||
if (!query) {
|
||||
return this.$q.when([]);
|
||||
}
|
||||
|
|
@ -481,7 +497,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
};
|
||||
}
|
||||
|
||||
annotationQuery(options) {
|
||||
annotationQuery(options: any) {
|
||||
const annotation = options.annotation;
|
||||
const expr = annotation.expr || '';
|
||||
let tagKeys = annotation.tagKeys || '';
|
||||
|
|
@ -504,8 +520,8 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
const query = this.createQuery({ expr, interval: minStep, refId: 'X' }, queryOptions, start, end);
|
||||
|
||||
const self = this;
|
||||
return this.performTimeSeriesQuery(query, query.start, query.end).then(results => {
|
||||
const eventList = [];
|
||||
return this.performTimeSeriesQuery(query, query.start, query.end).then((results: PromDataQueryResponse) => {
|
||||
const eventList: AnnotationEvent[] = [];
|
||||
tagKeys = tagKeys.split(',');
|
||||
|
||||
_.each(results.data.data.result, series => {
|
||||
|
|
@ -515,7 +531,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
})
|
||||
.value();
|
||||
|
||||
const dupCheck = {};
|
||||
const dupCheck: { [key: number]: boolean } = {};
|
||||
for (const value of series.values) {
|
||||
const valueIsTrue = value[1] === '1'; // e.g. ALERTS
|
||||
if (valueIsTrue || annotation.useValueForTime) {
|
||||
|
|
@ -546,18 +562,18 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
});
|
||||
}
|
||||
|
||||
getTagKeys(options) {
|
||||
getTagKeys(options: any = {}) {
|
||||
const url = '/api/v1/labels';
|
||||
return this.metadataRequest(url).then(result => {
|
||||
return this.metadataRequest(url).then((result: any) => {
|
||||
return _.map(result.data.data, value => {
|
||||
return { text: value };
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getTagValues(options) {
|
||||
getTagValues(options: any = {}) {
|
||||
const url = '/api/v1/label/' + options.key + '/values';
|
||||
return this.metadataRequest(url).then(result => {
|
||||
return this.metadataRequest(url).then((result: any) => {
|
||||
return _.map(result.data.data, value => {
|
||||
return { text: value };
|
||||
});
|
||||
|
|
@ -566,7 +582,8 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
|
||||
testDatasource() {
|
||||
const now = new Date().getTime();
|
||||
return this.performInstantQuery({ expr: '1+1' }, now / 1000).then(response => {
|
||||
const query = { expr: '1+1' } as PromQueryRequest;
|
||||
return this.performInstantQuery(query, now / 1000).then((response: any) => {
|
||||
if (response.data.status === 'success') {
|
||||
return { status: 'success', message: 'Data source is working' };
|
||||
} else {
|
||||
|
|
@ -601,14 +618,14 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
|
||||
loadRules() {
|
||||
this.metadataRequest('/api/v1/rules')
|
||||
.then(res => res.data || res.json())
|
||||
.then(body => {
|
||||
.then((res: any) => res.data || res.json())
|
||||
.then((body: any) => {
|
||||
const groups = _.get(body, ['data', 'groups']);
|
||||
if (groups) {
|
||||
this.ruleMappings = extractRuleMappingFromGroups(groups);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e: any) => {
|
||||
console.log('Rules API is experimental. Ignore next error.');
|
||||
console.error(e);
|
||||
});
|
||||
|
|
@ -645,7 +662,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
return { ...query, expr: expression };
|
||||
}
|
||||
|
||||
getPrometheusTime(date, roundUp) {
|
||||
getPrometheusTime(date: string | DateTime, roundUp: boolean) {
|
||||
if (_.isString(date)) {
|
||||
date = dateMath.parse(date, roundUp);
|
||||
}
|
||||
|
|
@ -660,7 +677,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||
};
|
||||
}
|
||||
|
||||
getOriginalMetricName(labelData) {
|
||||
getOriginalMetricName(labelData: { [key: string]: string }) {
|
||||
return this.resultTransformer.getOriginalMetricName(labelData);
|
||||
}
|
||||
}
|
||||
|
|
@ -685,9 +702,9 @@ export function extractRuleMappingFromGroups(groups: any[]) {
|
|||
return groups.reduce(
|
||||
(mapping, group) =>
|
||||
group.rules
|
||||
.filter(rule => rule.type === 'recording')
|
||||
.filter((rule: any) => rule.type === 'recording')
|
||||
.reduce(
|
||||
(acc, rule) => ({
|
||||
(acc: { [key: string]: string }, rule: any) => ({
|
||||
...acc,
|
||||
[rule.name]: rule.query,
|
||||
}),
|
||||
|
|
@ -697,14 +714,14 @@ export function extractRuleMappingFromGroups(groups: any[]) {
|
|||
);
|
||||
}
|
||||
|
||||
export function prometheusRegularEscape(value) {
|
||||
export function prometheusRegularEscape(value: any) {
|
||||
if (typeof value === 'string') {
|
||||
return value.replace(/'/g, "\\\\'");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function prometheusSpecialRegexEscape(value) {
|
||||
export function prometheusSpecialRegexEscape(value: any) {
|
||||
if (typeof value === 'string') {
|
||||
return prometheusRegularEscape(value.replace(/\\/g, '\\\\\\\\').replace(/[$^*{}\[\]+?.()|]/g, '\\\\$&'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
import { TimeRange } from '@grafana/ui';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { PrometheusDatasource, PromDataQueryResponse } from './datasource';
|
||||
import { PromQueryRequest } from './types';
|
||||
|
||||
export default class PrometheusMetricFindQuery {
|
||||
datasource: any;
|
||||
query: any;
|
||||
range: any;
|
||||
range: TimeRange;
|
||||
|
||||
constructor(datasource, query, timeSrv) {
|
||||
constructor(private datasource: PrometheusDatasource, private query: string, timeSrv: TimeSrv) {
|
||||
this.datasource = datasource;
|
||||
this.query = query;
|
||||
this.range = timeSrv.timeRange();
|
||||
|
|
@ -47,21 +49,21 @@ export default class PrometheusMetricFindQuery {
|
|||
|
||||
labelNamesQuery() {
|
||||
const url = '/api/v1/labels';
|
||||
return this.datasource.metadataRequest(url).then(result => {
|
||||
return this.datasource.metadataRequest(url).then((result: any) => {
|
||||
return _.map(result.data.data, value => {
|
||||
return { text: value };
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
labelValuesQuery(label, metric) {
|
||||
let url;
|
||||
labelValuesQuery(label: string, metric?: string) {
|
||||
let url: string;
|
||||
|
||||
if (!metric) {
|
||||
// return label values globally
|
||||
url = '/api/v1/label/' + label + '/values';
|
||||
|
||||
return this.datasource.metadataRequest(url).then(result => {
|
||||
return this.datasource.metadataRequest(url).then((result: any) => {
|
||||
return _.map(result.data.data, value => {
|
||||
return { text: value };
|
||||
});
|
||||
|
|
@ -71,7 +73,7 @@ export default class PrometheusMetricFindQuery {
|
|||
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
||||
url = '/api/v1/series?match[]=' + encodeURIComponent(metric) + '&start=' + start + '&end=' + end;
|
||||
|
||||
return this.datasource.metadataRequest(url).then(result => {
|
||||
return this.datasource.metadataRequest(url).then((result: any) => {
|
||||
const _labels = _.map(result.data.data, metric => {
|
||||
return metric[label] || '';
|
||||
}).filter(label => {
|
||||
|
|
@ -88,10 +90,10 @@ export default class PrometheusMetricFindQuery {
|
|||
}
|
||||
}
|
||||
|
||||
metricNameQuery(metricFilterPattern) {
|
||||
metricNameQuery(metricFilterPattern: string) {
|
||||
const url = '/api/v1/label/__name__/values';
|
||||
|
||||
return this.datasource.metadataRequest(url).then(result => {
|
||||
return this.datasource.metadataRequest(url).then((result: any) => {
|
||||
return _.chain(result.data.data)
|
||||
.filter(metricName => {
|
||||
const r = new RegExp(metricFilterPattern);
|
||||
|
|
@ -107,9 +109,10 @@ export default class PrometheusMetricFindQuery {
|
|||
});
|
||||
}
|
||||
|
||||
queryResultQuery(query) {
|
||||
queryResultQuery(query: string) {
|
||||
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
||||
return this.datasource.performInstantQuery({ expr: query }, end).then(result => {
|
||||
const instantQuery: PromQueryRequest = { expr: query } as PromQueryRequest;
|
||||
return this.datasource.performInstantQuery(instantQuery, end).then((result: PromDataQueryResponse) => {
|
||||
return _.map(result.data.data.result, metricData => {
|
||||
let text = metricData.metric.__name__ || '';
|
||||
delete metricData.metric.__name__;
|
||||
|
|
@ -129,14 +132,14 @@ export default class PrometheusMetricFindQuery {
|
|||
});
|
||||
}
|
||||
|
||||
metricNameAndLabelsQuery(query) {
|
||||
metricNameAndLabelsQuery(query: string) {
|
||||
const start = this.datasource.getPrometheusTime(this.range.from, false);
|
||||
const end = this.datasource.getPrometheusTime(this.range.to, true);
|
||||
const url = '/api/v1/series?match[]=' + encodeURIComponent(query) + '&start=' + start + '&end=' + end;
|
||||
|
||||
const self = this;
|
||||
return this.datasource.metadataRequest(url).then(result => {
|
||||
return _.map(result.data.data, metric => {
|
||||
return this.datasource.metadataRequest(url).then((result: PromDataQueryResponse) => {
|
||||
return _.map(result.data.data, (metric: { [key: string]: string }) => {
|
||||
return {
|
||||
text: self.datasource.getOriginalMetricName(metric),
|
||||
expandable: true,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { QueryCtrl } from 'app/plugins/sdk';
|
|||
import { PromCompleter } from './completer';
|
||||
import './mode-prometheus';
|
||||
import './snippets/prometheus';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
class PrometheusQueryCtrl extends QueryCtrl {
|
||||
static templateUrl = 'partials/query.editor.html';
|
||||
|
|
@ -18,7 +19,7 @@ class PrometheusQueryCtrl extends QueryCtrl {
|
|||
linkToPrometheus: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $injector, private templateSrv) {
|
||||
constructor($scope: any, $injector: angular.auto.IInjectorService, private templateSrv: TemplateSrv) {
|
||||
super($scope, $injector);
|
||||
|
||||
const target = this.target;
|
||||
|
|
@ -42,7 +43,7 @@ class PrometheusQueryCtrl extends QueryCtrl {
|
|||
this.updateLink();
|
||||
}
|
||||
|
||||
getCompleter(query) {
|
||||
getCompleter(query: string) {
|
||||
return new PromCompleter(this.datasource, this.templateSrv);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import _ from 'lodash';
|
||||
import { QueryHint } from '@grafana/ui/src/types';
|
||||
import { QueryHint, QueryFix } from '@grafana/ui/src/types';
|
||||
|
||||
/**
|
||||
* Number of time series results needed before starting to suggest sum aggregation hints
|
||||
*/
|
||||
export const SUM_HINT_THRESHOLD_COUNT = 20;
|
||||
|
||||
export function getQueryHints(query: string, series?: any[], datasource?: any): QueryHint[] {
|
||||
export function getQueryHints(query: string, series?: any[], datasource?: any): QueryHint[] | null {
|
||||
const hints = [];
|
||||
|
||||
// ..._bucket metric needs a histogram_quantile()
|
||||
|
|
@ -22,7 +22,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any):
|
|||
type: 'ADD_HISTOGRAM_QUANTILE',
|
||||
query,
|
||||
},
|
||||
},
|
||||
} as QueryFix,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any):
|
|||
if (increasing && monotonic) {
|
||||
const simpleMetric = query.trim().match(/^\w+$/);
|
||||
let label = 'Time series is monotonically increasing.';
|
||||
let fix;
|
||||
let fix: QueryFix;
|
||||
if (simpleMetric) {
|
||||
fix = {
|
||||
label: 'Fix by adding rate().',
|
||||
|
|
@ -52,7 +52,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any):
|
|||
type: 'ADD_RATE',
|
||||
query,
|
||||
},
|
||||
};
|
||||
} as QueryFix;
|
||||
} else {
|
||||
label = `${label} Try applying a rate() function.`;
|
||||
}
|
||||
|
|
@ -83,14 +83,14 @@ export function getQueryHints(query: string, series?: any[], datasource?: any):
|
|||
hints.push({
|
||||
type: 'EXPAND_RULES',
|
||||
label,
|
||||
fix: {
|
||||
fix: ({
|
||||
label: 'Expand rules',
|
||||
action: {
|
||||
type: 'EXPAND_RULES',
|
||||
query,
|
||||
mapping: mappingForQuery,
|
||||
},
|
||||
},
|
||||
} as any) as QueryFix,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ export function getQueryHints(query: string, series?: any[], datasource?: any):
|
|||
query: query,
|
||||
preventSubmit: true,
|
||||
},
|
||||
},
|
||||
} as QueryFix,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import _ from 'lodash';
|
||||
import TableModel from 'app/core/table_model';
|
||||
import { TimeSeries, FieldType } from '@grafana/ui';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
|
||||
export class ResultTransformer {
|
||||
constructor(private templateSrv) {}
|
||||
constructor(private templateSrv: TemplateSrv) {}
|
||||
|
||||
transform(response: any, options: any): any[] {
|
||||
const prometheusResult = response.data.data.result;
|
||||
|
|
@ -39,7 +40,7 @@ export class ResultTransformer {
|
|||
return [];
|
||||
}
|
||||
|
||||
transformMetricData(metricData, options, start, end) {
|
||||
transformMetricData(metricData: any, options: any, start: number, end: number) {
|
||||
const dps = [];
|
||||
let metricLabel = null;
|
||||
|
||||
|
|
@ -78,10 +79,10 @@ export class ResultTransformer {
|
|||
};
|
||||
}
|
||||
|
||||
transformMetricDataToTable(md, resultCount: number, refId: string, valueWithRefId?: boolean) {
|
||||
transformMetricDataToTable(md: any, resultCount: number, refId: string, valueWithRefId?: boolean) {
|
||||
const table = new TableModel();
|
||||
let i, j;
|
||||
const metricLabels = {};
|
||||
let i: number, j: number;
|
||||
const metricLabels: { [key: string]: number } = {};
|
||||
|
||||
if (!md || md.length === 0) {
|
||||
return table;
|
||||
|
|
@ -134,7 +135,7 @@ export class ResultTransformer {
|
|||
return table;
|
||||
}
|
||||
|
||||
transformInstantMetricData(md, options) {
|
||||
transformInstantMetricData(md: any, options: any) {
|
||||
const dps = [];
|
||||
let metricLabel = null;
|
||||
metricLabel = this.createMetricLabel(md.metric, options);
|
||||
|
|
@ -142,7 +143,7 @@ export class ResultTransformer {
|
|||
return { target: metricLabel, datapoints: dps, labels: md.metric };
|
||||
}
|
||||
|
||||
createMetricLabel(labelData, options) {
|
||||
createMetricLabel(labelData: { [key: string]: string }, options: any) {
|
||||
let label = '';
|
||||
if (_.isUndefined(options) || _.isEmpty(options.legendFormat)) {
|
||||
label = this.getOriginalMetricName(labelData);
|
||||
|
|
@ -155,7 +156,7 @@ export class ResultTransformer {
|
|||
return label;
|
||||
}
|
||||
|
||||
renderTemplate(aliasPattern, aliasData) {
|
||||
renderTemplate(aliasPattern: string, aliasData: { [key: string]: string }) {
|
||||
const aliasRegex = /\{\{\s*(.+?)\s*\}\}/g;
|
||||
return aliasPattern.replace(aliasRegex, (match, g1) => {
|
||||
if (aliasData[g1]) {
|
||||
|
|
@ -165,7 +166,7 @@ export class ResultTransformer {
|
|||
});
|
||||
}
|
||||
|
||||
getOriginalMetricName(labelData) {
|
||||
getOriginalMetricName(labelData: { [key: string]: string }) {
|
||||
const metricName = labelData.__name__ || '';
|
||||
delete labelData.__name__;
|
||||
const labelPart = _.map(_.toPairs(labelData), label => {
|
||||
|
|
@ -174,7 +175,7 @@ export class ResultTransformer {
|
|||
return metricName + '{' + labelPart + '}';
|
||||
}
|
||||
|
||||
transformToHistogramOverTime(seriesList) {
|
||||
transformToHistogramOverTime(seriesList: TimeSeries[]) {
|
||||
/* t1 = timestamp1, t2 = timestamp2 etc.
|
||||
t1 t2 t3 t1 t2 t3
|
||||
le10 10 10 0 => 10 10 0
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ jest.mock('../datasource');
|
|||
jest.mock('@grafana/ui');
|
||||
|
||||
describe('Prometheus editor completer', () => {
|
||||
function getSessionStub(data) {
|
||||
function getSessionStub(data: any) {
|
||||
return {
|
||||
getTokenAt: jest.fn(() => data.currentToken),
|
||||
getTokens: jest.fn(() => data.tokens),
|
||||
|
|
@ -37,14 +37,14 @@ describe('Prometheus editor completer', () => {
|
|||
});
|
||||
datasourceStub.performSuggestQuery = jest.fn(() => Promise.resolve(['node_cpu']));
|
||||
|
||||
const templateSrv = {
|
||||
const templateSrv: TemplateSrv = ({
|
||||
variables: [
|
||||
{
|
||||
name: 'var_name',
|
||||
options: [{ text: 'foo', value: 'foo', selected: false }, { text: 'bar', value: 'bar', selected: true }],
|
||||
},
|
||||
],
|
||||
};
|
||||
} as any) as TemplateSrv;
|
||||
const completer = new PromCompleter(datasourceStub, templateSrv);
|
||||
|
||||
describe('When inside brackets', () => {
|
||||
|
|
@ -55,7 +55,7 @@ describe('Prometheus editor completer', () => {
|
|||
line: 'node_cpu[',
|
||||
});
|
||||
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 10 }, '[', (s, res) => {
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 10 }, '[', (s: any, res: any) => {
|
||||
expect(res[0].caption).toEqual('$__interval');
|
||||
expect(res[0].value).toEqual('[$__interval');
|
||||
expect(res[0].meta).toEqual('range vector');
|
||||
|
|
@ -86,7 +86,7 @@ describe('Prometheus editor completer', () => {
|
|||
line: 'node_cpu{j}',
|
||||
});
|
||||
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 10 }, 'j', (s, res) => {
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 10 }, 'j', (s: any, res: any) => {
|
||||
expect(res[0].meta).toEqual('label name');
|
||||
});
|
||||
});
|
||||
|
|
@ -118,7 +118,7 @@ describe('Prometheus editor completer', () => {
|
|||
line: '{__name__=~"node_cpu",j}',
|
||||
});
|
||||
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'j', (s, res) => {
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'j', (s: any, res: any) => {
|
||||
expect(res[0].meta).toEqual('label name');
|
||||
});
|
||||
});
|
||||
|
|
@ -149,7 +149,7 @@ describe('Prometheus editor completer', () => {
|
|||
line: 'node_cpu{job="n"}',
|
||||
});
|
||||
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 15 }, 'n', (s, res) => {
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 15 }, 'n', (s: any, res: any) => {
|
||||
expect(res[0].meta).toEqual('label value');
|
||||
});
|
||||
});
|
||||
|
|
@ -185,7 +185,7 @@ describe('Prometheus editor completer', () => {
|
|||
line: '(count(node_cpu)) by (m)',
|
||||
});
|
||||
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'm', (s, res) => {
|
||||
return completer.getCompletions(editor, session, { row: 0, column: 23 }, 'm', (s: any, res: any) => {
|
||||
expect(res[0].meta).toEqual('label name');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
// @ts-ignore
|
||||
import q from 'q';
|
||||
import {
|
||||
alignRange,
|
||||
|
|
@ -8,7 +9,7 @@ import {
|
|||
prometheusSpecialRegexEscape,
|
||||
} from '../datasource';
|
||||
import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
||||
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||
import { DataSourceInstanceSettings, DataQueryResponseData } from '@grafana/ui';
|
||||
import { PromOptions } from '../types';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
|
|
@ -17,8 +18,8 @@ import { CustomVariable } from 'app/features/templating/custom_variable';
|
|||
jest.mock('../metric_find_query');
|
||||
|
||||
const DEFAULT_TEMPLATE_SRV_MOCK = {
|
||||
getAdhocFilters: () => [],
|
||||
replace: a => a,
|
||||
getAdhocFilters: () => [] as any[],
|
||||
replace: (a: string) => a,
|
||||
};
|
||||
|
||||
describe('PrometheusDatasource', () => {
|
||||
|
|
@ -179,7 +180,7 @@ describe('PrometheusDatasource', () => {
|
|||
];
|
||||
|
||||
ctx.ds.performTimeSeriesQuery = jest.fn().mockReturnValue(responseMock);
|
||||
return ctx.ds.query(ctx.query).then(result => {
|
||||
return ctx.ds.query(ctx.query).then((result: any) => {
|
||||
const results = result.data;
|
||||
return expect(results).toMatchObject(expected);
|
||||
});
|
||||
|
|
@ -209,7 +210,7 @@ describe('PrometheusDatasource', () => {
|
|||
const expected = ['1', '2', '4', '+Inf'];
|
||||
|
||||
ctx.ds.performTimeSeriesQuery = jest.fn().mockReturnValue(responseMock);
|
||||
return ctx.ds.query(ctx.query).then(result => {
|
||||
return ctx.ds.query(ctx.query).then((result: any) => {
|
||||
const seriesLabels = _.map(result.data, 'target');
|
||||
return expect(seriesLabels).toEqual(expected);
|
||||
});
|
||||
|
|
@ -412,7 +413,7 @@ const backendSrv = {
|
|||
} as any;
|
||||
|
||||
const templateSrv = ({
|
||||
getAdhocFilters: () => [],
|
||||
getAdhocFilters: (): any[] => [],
|
||||
replace: jest.fn(str => str),
|
||||
} as unknown) as TemplateSrv;
|
||||
|
||||
|
|
@ -424,7 +425,7 @@ const timeSrv = ({
|
|||
|
||||
describe('PrometheusDatasource', () => {
|
||||
describe('When querying prometheus with one target using query editor target spec', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
const query = {
|
||||
range: { from: time({ seconds: 63 }), to: time({ seconds: 183 }) },
|
||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series' }],
|
||||
|
|
@ -452,7 +453,7 @@ describe('PrometheusDatasource', () => {
|
|||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
|
||||
await ctx.ds.query(query).then(data => {
|
||||
await ctx.ds.query(query).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -468,7 +469,7 @@ describe('PrometheusDatasource', () => {
|
|||
});
|
||||
});
|
||||
describe('When querying prometheus with one target which returns multiple series', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
const start = 60;
|
||||
const end = 360;
|
||||
const step = 60;
|
||||
|
|
@ -502,7 +503,7 @@ describe('PrometheusDatasource', () => {
|
|||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
|
||||
await ctx.ds.query(query).then(data => {
|
||||
await ctx.ds.query(query).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -536,7 +537,7 @@ describe('PrometheusDatasource', () => {
|
|||
});
|
||||
});
|
||||
describe('When querying prometheus with one target and instant = true', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
const urlExpected = 'proxied/api/v1/query?query=' + encodeURIComponent('test{job="testjob"}') + '&time=123';
|
||||
const query = {
|
||||
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
|
||||
|
|
@ -563,7 +564,7 @@ describe('PrometheusDatasource', () => {
|
|||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
|
||||
await ctx.ds.query(query).then(data => {
|
||||
await ctx.ds.query(query).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -578,7 +579,7 @@ describe('PrometheusDatasource', () => {
|
|||
});
|
||||
});
|
||||
describe('When performing annotationQuery', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
|
||||
const options: any = {
|
||||
annotation: {
|
||||
|
|
@ -620,7 +621,7 @@ describe('PrometheusDatasource', () => {
|
|||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
|
||||
await ctx.ds.annotationQuery(options).then(data => {
|
||||
await ctx.ds.annotationQuery(options).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -640,7 +641,7 @@ describe('PrometheusDatasource', () => {
|
|||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
|
||||
await ctx.ds.annotationQuery(options).then(data => {
|
||||
await ctx.ds.annotationQuery(options).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -725,7 +726,7 @@ describe('PrometheusDatasource', () => {
|
|||
});
|
||||
|
||||
describe('When resultFormat is table and instant = true', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
const query = {
|
||||
range: { from: time({ seconds: 63 }), to: time({ seconds: 123 }) },
|
||||
targets: [{ expr: 'test{job="testjob"}', format: 'time_series', instant: true }],
|
||||
|
|
@ -750,7 +751,7 @@ describe('PrometheusDatasource', () => {
|
|||
|
||||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
await ctx.ds.query(query).then(data => {
|
||||
await ctx.ds.query(query).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -766,7 +767,7 @@ describe('PrometheusDatasource', () => {
|
|||
data: {
|
||||
data: {
|
||||
resultType: 'matrix',
|
||||
result: [],
|
||||
result: [] as DataQueryResponseData[],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -963,7 +964,7 @@ describe('PrometheusDatasource', () => {
|
|||
data: {
|
||||
data: {
|
||||
resultType: 'matrix',
|
||||
result: [],
|
||||
result: [] as DataQueryResponseData[],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1232,7 +1233,7 @@ describe('PrometheusDatasource', () => {
|
|||
data: {
|
||||
data: {
|
||||
resultType: 'matrix',
|
||||
result: [],
|
||||
result: [] as DataQueryResponseData[],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1293,7 +1294,7 @@ describe('PrometheusDatasource for POST', () => {
|
|||
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||
|
||||
describe('When querying prometheus with one target using query editor target spec', () => {
|
||||
let results;
|
||||
let results: any;
|
||||
const urlExpected = 'proxied/api/v1/query_range';
|
||||
const dataExpected = {
|
||||
query: 'test{job="testjob"}',
|
||||
|
|
@ -1324,7 +1325,7 @@ describe('PrometheusDatasource for POST', () => {
|
|||
};
|
||||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
await ctx.ds.query(query).then(data => {
|
||||
await ctx.ds.query(query).then((data: any) => {
|
||||
results = data;
|
||||
});
|
||||
});
|
||||
|
|
@ -1344,7 +1345,7 @@ describe('PrometheusDatasource for POST', () => {
|
|||
const options = { dashboardId: 1, panelId: 2 };
|
||||
|
||||
const httpOptions = {
|
||||
headers: {},
|
||||
headers: {} as { [key: string]: number | undefined },
|
||||
};
|
||||
|
||||
it('with proxy access tracing headers should be added', () => {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// @ts-ignore
|
||||
import Plain from 'slate-plain-serializer';
|
||||
|
||||
import LanguageProvider from '../language_provider';
|
||||
|
||||
describe('Language completion provider', () => {
|
||||
const datasource = {
|
||||
metadataRequest: () => ({ data: { data: [] } }),
|
||||
metadataRequest: () => ({ data: { data: [] as any[] } }),
|
||||
};
|
||||
|
||||
describe('empty query suggestions', () => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { PrometheusDatasource } from '../datasource';
|
||||
import PrometheusMetricFindQuery from '../metric_find_query';
|
||||
//@ts-ignore
|
||||
import q from 'q';
|
||||
import { toUtc } from '@grafana/ui/src/utils/moment_wrapper';
|
||||
import { DataSourceInstanceSettings } from '@grafana/ui';
|
||||
|
|
@ -22,7 +23,7 @@ describe('PrometheusMetricFindQuery', () => {
|
|||
datasourceRequest: jest.fn(() => Promise.resolve({})),
|
||||
},
|
||||
templateSrvMock: {
|
||||
replace: a => a,
|
||||
replace: (a: string) => a,
|
||||
},
|
||||
timeSrvMock: {
|
||||
timeRange: () => ({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { ResultTransformer } from '../result_transformer';
|
||||
import { DataQueryResponseData } from '@grafana/ui';
|
||||
|
||||
describe('Prometheus Result Transformer', () => {
|
||||
const ctx: any = {};
|
||||
|
||||
beforeEach(() => {
|
||||
ctx.templateSrv = {
|
||||
replace: str => str,
|
||||
replace: (str: string) => str,
|
||||
};
|
||||
ctx.resultTransformer = new ResultTransformer(ctx.templateSrv);
|
||||
});
|
||||
|
|
@ -16,7 +17,7 @@ describe('Prometheus Result Transformer', () => {
|
|||
status: 'success',
|
||||
data: {
|
||||
resultType: '',
|
||||
result: null,
|
||||
result: null as DataQueryResponseData[],
|
||||
},
|
||||
};
|
||||
const series = ctx.resultTransformer.transform({ data: response }, {});
|
||||
|
|
@ -27,7 +28,7 @@ describe('Prometheus Result Transformer', () => {
|
|||
status: 'success',
|
||||
data: {
|
||||
resultType: '',
|
||||
result: null,
|
||||
result: null as DataQueryResponseData[],
|
||||
},
|
||||
};
|
||||
const table = ctx.resultTransformer.transform({ data: response }, { format: 'table' });
|
||||
|
|
@ -168,7 +169,7 @@ describe('Prometheus Result Transformer', () => {
|
|||
});
|
||||
|
||||
it('should throw error when data in wrong format', () => {
|
||||
const seriesList = [{ rows: [] }, { datapoints: [] }];
|
||||
const seriesList = [{ rows: [] as any[] }, { datapoints: [] as any[] }];
|
||||
expect(() => {
|
||||
ctx.resultTransformer.transformToHistogramOverTime(seriesList);
|
||||
}).toThrow();
|
||||
|
|
@ -176,7 +177,7 @@ describe('Prometheus Result Transformer', () => {
|
|||
|
||||
it('should throw error when prometheus returned non-timeseries', () => {
|
||||
// should be { metric: {}, values: [] } for timeseries
|
||||
const metricData = { metric: {}, value: [] };
|
||||
const metricData = { metric: {}, value: [] as any[] };
|
||||
expect(() => {
|
||||
ctx.resultTransformer.transformMetricData(metricData, { step: 1 }, 1000, 2000);
|
||||
}).toThrow();
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ export interface PromQueryRequest extends PromQuery {
|
|||
requestId?: string;
|
||||
start: number;
|
||||
end: number;
|
||||
headers?: any;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue