diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index ddb4d6ed549..dddd208d3a1 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -1,10 +1,39 @@ import LokiDatasource from './datasource'; describe('LokiDatasource', () => { - const instanceSettings = { + const instanceSettings: any = { url: 'myloggingurl', }; + describe('when querying', () => { + const backendSrvMock = { datasourceRequest: jest.fn() }; + + const templateSrvMock = { + getAdhocFilters: () => [], + replace: a => a, + }; + + const range = { from: 'now-6h', to: 'now' }; + + test('should use default limit when no limit given', () => { + const ds = new LokiDatasource(instanceSettings, backendSrvMock, templateSrvMock); + backendSrvMock.datasourceRequest = jest.fn(); + ds.query({ range, targets: [{ expr: 'foo' }] }); + expect(backendSrvMock.datasourceRequest.mock.calls.length).toBe(1); + expect(backendSrvMock.datasourceRequest.mock.calls[0][0].url).toContain('limit=1000'); + }); + + test('should use custom limit if set', () => { + const customData = { ...(instanceSettings.jsonData || {}), queryLimit: 20 }; + const customSettings = { ...instanceSettings, jsonData: customData }; + const ds = new LokiDatasource(customSettings, backendSrvMock, templateSrvMock); + backendSrvMock.datasourceRequest = jest.fn(); + ds.query({ range, targets: [{ expr: 'foo' }] }); + expect(backendSrvMock.datasourceRequest.mock.calls.length).toBe(1); + expect(backendSrvMock.datasourceRequest.mock.calls[0][0].url).toContain('limit=20'); + }); + }); + describe('when performing testDataSource', () => { let ds; let result; diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index ebbe6bb4b56..1ea10965737 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -29,10 +29,13 @@ function serializeParams(data: any) { export default class LokiDatasource { languageProvider: LanguageProvider; + queryLimit: number; /** @ngInject */ constructor(private instanceSettings, private backendSrv, private templateSrv) { this.languageProvider = new LanguageProvider(this); + const settingsData = instanceSettings.jsonData || {}; + this.queryLimit = parseInt(settingsData.queryLimit, 10) || DEFAULT_LIMIT; } _request(apiUrl: string, data?, options?: any) { @@ -47,7 +50,7 @@ export default class LokiDatasource { } mergeStreams(streams: LogsStream[], intervalMs: number): LogsModel { - const logs = mergeStreamsToLogs(streams); + const logs = mergeStreamsToLogs(streams, this.queryLimit); logs.series = makeSeriesForLogs(logs.rows, intervalMs); return logs; } @@ -61,6 +64,7 @@ export default class LokiDatasource { ...parseQuery(interpolated), start, end, + limit: this.queryLimit, }; } @@ -77,6 +81,9 @@ export default class LokiDatasource { return Promise.all(queries).then((results: any[]) => { // Flatten streams from multiple queries const allStreams: LogsStream[] = results.reduce((acc, response, i) => { + if (!response) { + return acc; + } const streams: LogsStream[] = response.data.streams || []; // Inject search for match highlighting const search: string = queryTargets[i].regexp; diff --git a/public/app/plugins/datasource/loki/partials/config.html b/public/app/plugins/datasource/loki/partials/config.html index 8e79cc0adcc..f13b00314bb 100644 --- a/public/app/plugins/datasource/loki/partials/config.html +++ b/public/app/plugins/datasource/loki/partials/config.html @@ -1,2 +1,16 @@ - \ No newline at end of file + + +
+
+
+ Line limit + + + Loki queries must contain a limit of maximum number of lines returned (default: 1000). + Increase this limit to have a bigger result set for ad-hoc analysis. + Decrease this limit if your browser becomes sluggish when displaying the log results. + +
+
+