diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts
index ddb4d6ed549..b7f67ffc0e7 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 max lines 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 max lines if limit is set', () => {
+ const customData = { ...(instanceSettings.jsonData || {}), maxLines: 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..eb33c7ef285 100644
--- a/public/app/plugins/datasource/loki/datasource.ts
+++ b/public/app/plugins/datasource/loki/datasource.ts
@@ -9,11 +9,11 @@ import LanguageProvider from './language_provider';
import { mergeStreamsToLogs } from './result_transformer';
import { formatQuery, parseQuery } from './query_utils';
-export const DEFAULT_LIMIT = 1000;
+export const DEFAULT_MAX_LINES = 1000;
const DEFAULT_QUERY_PARAMS = {
direction: 'BACKWARD',
- limit: DEFAULT_LIMIT,
+ limit: DEFAULT_MAX_LINES,
regexp: '',
query: '',
};
@@ -29,10 +29,13 @@ function serializeParams(data: any) {
export default class LokiDatasource {
languageProvider: LanguageProvider;
+ maxLines: number;
/** @ngInject */
constructor(private instanceSettings, private backendSrv, private templateSrv) {
this.languageProvider = new LanguageProvider(this);
+ const settingsData = instanceSettings.jsonData || {};
+ this.maxLines = parseInt(settingsData.maxLines, 10) || DEFAULT_MAX_LINES;
}
_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.maxLines);
logs.series = makeSeriesForLogs(logs.rows, intervalMs);
return logs;
}
@@ -61,6 +64,7 @@ export default class LokiDatasource {
...parseQuery(interpolated),
start,
end,
+ limit: this.maxLines,
};
}
@@ -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..d209b51730a 100644
--- a/public/app/plugins/datasource/loki/partials/config.html
+++ b/public/app/plugins/datasource/loki/partials/config.html
@@ -1,2 +1,16 @@