Commit 3424b642 by Hugo Häggmark Committed by GitHub

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