Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TSVB] Greater Than or Equal to Interval Pattern #13872

Merged
merged 7 commits into from
Sep 26, 2017
4 changes: 4 additions & 0 deletions src/core_plugins/metrics/common/interval_regexp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dateMath from '@elastic/datemath';
export const GTE_INTERVAL_RE = new RegExp(`^>=([\\d\\.]*\\s*(${dateMath.units.join('|')}))$`);
export const INTERVAL_STRING_RE = new RegExp('^([0-9\\.]*)\\s*(' + dateMath.units.join('|') + ')$');

Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const IndexPattern = props => {
/>
</div>
<label className="vis_editor__label" htmlFor={htmlId('interval')}>
Interval (auto, 1m, 1d, 1w, 1y)
Interval (auto, 1m, 1d, 1w, 1y, &gt;=1m)
</label>
<input
id={htmlId('interval')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const MetricsRequestHandlerProvider = function (Private, Notifier, config, timef
name: 'metrics',
handler: function (vis /*, appState, uiState, queryFilter*/) {
const timezone = Private(timezoneProvider)();

return new Promise((resolve) => {
const panel = vis.params;
if (panel && panel.id) {
Expand Down
17 changes: 10 additions & 7 deletions src/core_plugins/metrics/public/lib/validate_interval.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { parseInterval } from 'ui/utils/parse_interval';
import { GTE_INTERVAL_RE } from '../../common/interval_regexp';
export function validateInterval(timefilter, panel, maxBuckets) {
const { interval } = panel;
const { min, max } = timefilter.getBounds();
// No need to check auto it will return around 100
if (!interval) return;
if (interval === 'auto') return;
const greaterThanMatch = interval.match(GTE_INTERVAL_RE);
if (greaterThanMatch) return;
const duration = parseInterval(interval);
if (!duration) {
throw new Error(`Invalid interval: ${interval} is not a valid interval`);
}
const span = max.valueOf() - min.valueOf();
const buckets = Math.floor(span / duration.asMilliseconds());
if (buckets > maxBuckets) {
throw new Error(`Max buckets exceeded: ${buckets} is greater than ${maxBuckets}, try a larger time interval in the panel options.`);
if (duration) {
const span = max.valueOf() - min.valueOf();
const buckets = Math.floor(span / duration.asMilliseconds());
if (buckets > maxBuckets) {
throw new Error(`Max buckets exceeded: ${buckets} is greater than ${maxBuckets}, try a larger time interval in the panel options.`);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@ describe('getBucketSize', () => {
expect(result).to.have.property('intervalString', '1d');
});

it('returns overriden buckets (>=2d)', () => {
const result = getBucketSize(req, '>=2d');
expect(result).to.have.property('bucketSize', 86400 * 2);
expect(result).to.have.property('intervalString', '2d');
});

it('returns overriden buckets (>=10s)', () => {
const result = getBucketSize(req, '>=10s');
expect(result).to.have.property('bucketSize', 30);
expect(result).to.have.property('intervalString', '30s');
});

});
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import calculateAuto from './calculate_auto';
import moment from 'moment';
import unitToSeconds from './unit_to_seconds';
import {
INTERVAL_STRING_RE,
GTE_INTERVAL_RE
} from '../../../../common/interval_regexp';
export default (req, interval) => {
const from = moment.utc(req.payload.timerange.min);
const to = moment.utc(req.payload.timerange.max);
Expand All @@ -9,7 +13,19 @@ export default (req, interval) => {
if (bucketSize < 1) bucketSize = 1; // don't go too small
let intervalString = `${bucketSize}s`;

const matches = interval && interval.match(/^([\d]+)([shmdwMy]|ms)$/);
const gteAutoMatch = interval && interval.match(GTE_INTERVAL_RE);
if (gteAutoMatch) {
const intervalStringMatch = gteAutoMatch[1].match(INTERVAL_STRING_RE);
const gteBucketSize = Number(intervalStringMatch[1]) * unitToSeconds(intervalStringMatch[2]);
if (gteBucketSize >= bucketSize) {
return {
bucketSize: gteBucketSize,
intervalString: gteAutoMatch[1]
};
}
}

const matches = interval && interval.match(INTERVAL_STRING_RE);
if (matches) {
bucketSize = Number(matches[1]) * unitToSeconds(matches[2]);
intervalString = interval;
Expand Down