Commit 26a5e077 by David Kaltschmidt

Loki: query limit configurable in datasource

- Loki queries must contain a limit
- this change makes this limit configurable in the datasource
- keep default at 1000, add tooltip on why inc/dec makes sense
- added tests
parent 6f998541
import LokiDatasource from './datasource'; import LokiDatasource from './datasource';
describe('LokiDatasource', () => { describe('LokiDatasource', () => {
const instanceSettings = { const instanceSettings: any = {
url: 'myloggingurl', 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', () => { describe('when performing testDataSource', () => {
let ds; let ds;
let result; let result;
......
...@@ -29,10 +29,13 @@ function serializeParams(data: any) { ...@@ -29,10 +29,13 @@ function serializeParams(data: any) {
export default class LokiDatasource { export default class LokiDatasource {
languageProvider: LanguageProvider; languageProvider: LanguageProvider;
queryLimit: number;
/** @ngInject */ /** @ngInject */
constructor(private instanceSettings, private backendSrv, private templateSrv) { constructor(private instanceSettings, private backendSrv, private templateSrv) {
this.languageProvider = new LanguageProvider(this); this.languageProvider = new LanguageProvider(this);
const settingsData = instanceSettings.jsonData || {};
this.queryLimit = parseInt(settingsData.queryLimit, 10) || DEFAULT_LIMIT;
} }
_request(apiUrl: string, data?, options?: any) { _request(apiUrl: string, data?, options?: any) {
...@@ -47,7 +50,7 @@ export default class LokiDatasource { ...@@ -47,7 +50,7 @@ export default class LokiDatasource {
} }
mergeStreams(streams: LogsStream[], intervalMs: number): LogsModel { mergeStreams(streams: LogsStream[], intervalMs: number): LogsModel {
const logs = mergeStreamsToLogs(streams); const logs = mergeStreamsToLogs(streams, this.queryLimit);
logs.series = makeSeriesForLogs(logs.rows, intervalMs); logs.series = makeSeriesForLogs(logs.rows, intervalMs);
return logs; return logs;
} }
...@@ -61,6 +64,7 @@ export default class LokiDatasource { ...@@ -61,6 +64,7 @@ export default class LokiDatasource {
...parseQuery(interpolated), ...parseQuery(interpolated),
start, start,
end, end,
limit: this.queryLimit,
}; };
} }
...@@ -77,6 +81,9 @@ export default class LokiDatasource { ...@@ -77,6 +81,9 @@ export default class LokiDatasource {
return Promise.all(queries).then((results: any[]) => { return Promise.all(queries).then((results: any[]) => {
// Flatten streams from multiple queries // Flatten streams from multiple queries
const allStreams: LogsStream[] = results.reduce((acc, response, i) => { const allStreams: LogsStream[] = results.reduce((acc, response, i) => {
if (!response) {
return acc;
}
const streams: LogsStream[] = response.data.streams || []; const streams: LogsStream[] = response.data.streams || [];
// Inject search for match highlighting // Inject search for match highlighting
const search: string = queryTargets[i].regexp; const search: string = queryTargets[i].regexp;
......
<datasource-http-settings current="ctrl.current" no-direct-access="true"> <datasource-http-settings current="ctrl.current" no-direct-access="true">
</datasource-http-settings> </datasource-http-settings>
<div class="gf-form-group">
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-8">Line limit</span>
<input type="text" class="gf-form-input width-8" ng-model="ctrl.current.jsonData.queryLimit" spellcheck='false' placeholder="1000"></input>
<info-popover mode="right-absolute">
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.
</info-popover>
</div>
</div>
</div>
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