mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Revert stepMode functionality (#38982)
* Revert "Prometheus: add functionality to specify desired step interval in dashboards panels (#36422)" This reverts commitddf5b65c51. Co-authored-by: Ivana Huckova <ivana.huckova@gmail.com> * Revert "Explore: add functionality for supporting different step modes in prometheus (#37829)" This reverts commitf433cfd8d9. Co-authored-by: Ivana Huckova <ivana.huckova@gmail.com> * Revert stepMode BE implementation from #36796 Co-authored-by: "Ivana Huckova" <ivana.huckova@gmail.com>
This commit is contained in:
@@ -3,20 +3,16 @@ import React, { memo } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
|
||||
// Types
|
||||
import { InlineFormLabel, RadioButtonGroup, Select } from '@grafana/ui';
|
||||
import { PromQuery, StepMode } from '../types';
|
||||
import { InlineFormLabel, RadioButtonGroup } from '@grafana/ui';
|
||||
import { PromQuery } from '../types';
|
||||
import { PromExemplarField } from './PromExemplarField';
|
||||
import { PrometheusDatasource } from '../datasource';
|
||||
import { STEP_MODES } from './PromQueryEditor';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
|
||||
export interface PromExploreExtraFieldProps {
|
||||
queryType: string;
|
||||
stepValue: string;
|
||||
stepMode: StepMode;
|
||||
query: PromQuery;
|
||||
onStepModeChange: (option: SelectableValue<StepMode>) => void;
|
||||
onStepIntervalChange: (e: React.SyntheticEvent<HTMLInputElement>) => void;
|
||||
onStepChange: (e: React.SyntheticEvent<HTMLInputElement>) => void;
|
||||
onKeyDownFunc: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
||||
onQueryTypeChange: (value: string) => void;
|
||||
onChange: (value: PromQuery) => void;
|
||||
@@ -24,18 +20,7 @@ export interface PromExploreExtraFieldProps {
|
||||
}
|
||||
|
||||
export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
|
||||
({
|
||||
queryType,
|
||||
stepValue,
|
||||
stepMode,
|
||||
query,
|
||||
onChange,
|
||||
onStepModeChange,
|
||||
onStepIntervalChange,
|
||||
onQueryTypeChange,
|
||||
onKeyDownFunc,
|
||||
datasource,
|
||||
}) => {
|
||||
({ queryType, stepValue, query, onChange, onStepChange, onQueryTypeChange, onKeyDownFunc, datasource }) => {
|
||||
const rangeOptions = [
|
||||
{ value: 'range', label: 'Range', description: 'Run query over a range of time.' },
|
||||
{
|
||||
@@ -82,20 +67,11 @@ export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
|
||||
>
|
||||
Step
|
||||
</InlineFormLabel>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
className={'select-container'}
|
||||
width={16}
|
||||
isSearchable={false}
|
||||
options={STEP_MODES}
|
||||
onChange={onStepModeChange}
|
||||
value={stepMode}
|
||||
/>
|
||||
<input
|
||||
type={'text'}
|
||||
className="gf-form-input width-4"
|
||||
placeholder={'auto'}
|
||||
onChange={onStepIntervalChange}
|
||||
onChange={onStepChange}
|
||||
onKeyDown={onKeyDownFunc}
|
||||
value={stepValue}
|
||||
/>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { memo, FC, useEffect } from 'react';
|
||||
|
||||
// Types
|
||||
import { ExploreQueryFieldProps, SelectableValue } from '@grafana/data';
|
||||
import { ExploreQueryFieldProps } from '@grafana/data';
|
||||
|
||||
import { PrometheusDatasource } from '../datasource';
|
||||
import { PromQuery, PromOptions, StepMode } from '../types';
|
||||
import { PromQuery, PromOptions } from '../types';
|
||||
|
||||
import PromQueryField from './PromQueryField';
|
||||
import { PromExploreExtraField } from './PromExploreExtraField';
|
||||
@@ -26,19 +26,7 @@ export const PromExploreQueryEditor: FC<Props> = (props: Props) => {
|
||||
onChange(nextQuery);
|
||||
}
|
||||
|
||||
function onChangeStepMode(mode: StepMode) {
|
||||
const { query, onChange } = props;
|
||||
const nextQuery = { ...query, stepMode: mode };
|
||||
onChange(nextQuery);
|
||||
}
|
||||
|
||||
function onStepModeChange(option: SelectableValue<StepMode>) {
|
||||
if (option.value) {
|
||||
onChangeStepMode(option.value);
|
||||
}
|
||||
}
|
||||
|
||||
function onStepIntervalChange(e: React.SyntheticEvent<HTMLInputElement>) {
|
||||
function onStepChange(e: React.SyntheticEvent<HTMLInputElement>) {
|
||||
if (e.currentTarget.value !== query.interval) {
|
||||
onChangeQueryStep(e.currentTarget.value);
|
||||
}
|
||||
@@ -78,10 +66,8 @@ export const PromExploreQueryEditor: FC<Props> = (props: Props) => {
|
||||
// Select "both" as default option when Explore is opened. In legacy requests, range and instant can be undefined. In this case, we want to run queries with "both".
|
||||
queryType={query.range === query.instant ? 'both' : query.instant ? 'instant' : 'range'}
|
||||
stepValue={query.interval || ''}
|
||||
stepMode={query.stepMode || 'min'}
|
||||
onQueryTypeChange={onQueryTypeChange}
|
||||
onStepModeChange={onStepModeChange}
|
||||
onStepIntervalChange={onStepIntervalChange}
|
||||
onStepChange={onStepChange}
|
||||
onKeyDownFunc={onReturnKeyDown}
|
||||
query={query}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { PureComponent } from 'react';
|
||||
// Types
|
||||
import { InlineFormLabel, LegacyForms, Select } from '@grafana/ui';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { PromQuery, StepMode } from '../types';
|
||||
import { PromQuery } from '../types';
|
||||
|
||||
import PromQueryField from './PromQueryField';
|
||||
import PromLink from './PromLink';
|
||||
@@ -24,29 +24,11 @@ const INTERVAL_FACTOR_OPTIONS: Array<SelectableValue<number>> = map([1, 2, 3, 4,
|
||||
label: '1/' + value,
|
||||
}));
|
||||
|
||||
export const DEFAULT_STEP_MODE: SelectableValue<StepMode> = {
|
||||
value: 'min',
|
||||
label: 'Minimum',
|
||||
};
|
||||
|
||||
export const STEP_MODES: Array<SelectableValue<StepMode>> = [
|
||||
DEFAULT_STEP_MODE,
|
||||
{
|
||||
value: 'max',
|
||||
label: 'Maximum',
|
||||
},
|
||||
{
|
||||
value: 'exact',
|
||||
label: 'Exact',
|
||||
},
|
||||
];
|
||||
|
||||
interface State {
|
||||
legendFormat?: string;
|
||||
formatOption: SelectableValue<string>;
|
||||
interval?: string;
|
||||
intervalFactorOption: SelectableValue<number>;
|
||||
stepMode: SelectableValue<StepMode>;
|
||||
instant: boolean;
|
||||
exemplar: boolean;
|
||||
}
|
||||
@@ -63,7 +45,6 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
legendFormat: '',
|
||||
interval: '',
|
||||
exemplar: true,
|
||||
stepMode: DEFAULT_STEP_MODE.value,
|
||||
};
|
||||
const query = Object.assign({}, defaultQuery, props.query);
|
||||
this.query = query;
|
||||
@@ -76,8 +57,6 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
formatOption: FORMAT_OPTIONS.find((option) => option.value === query.format) || FORMAT_OPTIONS[0],
|
||||
intervalFactorOption:
|
||||
INTERVAL_FACTOR_OPTIONS.find((option) => option.value === query.intervalFactor) || INTERVAL_FACTOR_OPTIONS[0],
|
||||
// Step mode
|
||||
stepMode: STEP_MODES.find((option) => option.value === query.stepMode) || DEFAULT_STEP_MODE,
|
||||
// Switch options
|
||||
instant: Boolean(query.instant),
|
||||
exemplar: Boolean(query.exemplar),
|
||||
@@ -110,11 +89,6 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
this.setState({ intervalFactorOption: option }, this.onRunQuery);
|
||||
};
|
||||
|
||||
onStepChange = (option: SelectableValue<StepMode>) => {
|
||||
this.query.stepMode = option.value;
|
||||
this.setState({ stepMode: option }, this.onRunQuery);
|
||||
};
|
||||
|
||||
onLegendChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const legendFormat = e.currentTarget.value;
|
||||
this.query.legendFormat = legendFormat;
|
||||
@@ -136,7 +110,7 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
|
||||
render() {
|
||||
const { datasource, query, range, data } = this.props;
|
||||
const { formatOption, instant, interval, intervalFactorOption, stepMode, legendFormat, exemplar } = this.state;
|
||||
const { formatOption, instant, interval, intervalFactorOption, legendFormat, exemplar } = this.state;
|
||||
|
||||
return (
|
||||
<PromQueryField
|
||||
@@ -170,37 +144,27 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel
|
||||
width={5}
|
||||
width={7}
|
||||
tooltip={
|
||||
<>
|
||||
Use 'Minimum' or 'Maximum' step mode to set the lower or upper bounds
|
||||
respectively on the interval between data points. For example, set "minimum 1h" to hint
|
||||
that measurements were not taken more frequently. Use the 'Exact' step mode to set an
|
||||
exact interval between data points. <code>$__interval</code> and <code>$__rate_interval</code> are
|
||||
supported.
|
||||
An additional lower limit for the step parameter of the Prometheus query and for the{' '}
|
||||
<code>$__interval</code> and <code>$__rate_interval</code> variables. The limit is absolute and not
|
||||
modified by the "Resolution" setting.
|
||||
</>
|
||||
}
|
||||
>
|
||||
Step
|
||||
Min step
|
||||
</InlineFormLabel>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
className={'select-container'}
|
||||
width={16}
|
||||
isSearchable={false}
|
||||
options={STEP_MODES}
|
||||
onChange={this.onStepChange}
|
||||
value={stepMode}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
className="gf-form-input width-4"
|
||||
placeholder="15s"
|
||||
className="gf-form-input width-8"
|
||||
placeholder={interval}
|
||||
onChange={this.onIntervalChange}
|
||||
onBlur={this.onRunQuery}
|
||||
value={interval}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="gf-form">
|
||||
<div className="gf-form-label">Resolution</div>
|
||||
<Select
|
||||
@@ -211,11 +175,12 @@ export class PromQueryEditor extends PureComponent<PromQueryEditorProps, State>
|
||||
value={intervalFactorOption}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="gf-form">
|
||||
<div className="gf-form-label width-7">Format</div>
|
||||
<Select
|
||||
menuShouldPortal
|
||||
className={'select-container'}
|
||||
className="select-container"
|
||||
width={16}
|
||||
isSearchable={false}
|
||||
options={FORMAT_OPTIONS}
|
||||
|
||||
@@ -16,8 +16,7 @@ exports[`PromExploreQueryEditor should render component 1`] = `
|
||||
onChange={[MockFunction]}
|
||||
onKeyDownFunc={[Function]}
|
||||
onQueryTypeChange={[Function]}
|
||||
onStepIntervalChange={[Function]}
|
||||
onStepModeChange={[Function]}
|
||||
onStepChange={[Function]}
|
||||
query={
|
||||
Object {
|
||||
"expr": "",
|
||||
@@ -26,7 +25,6 @@ exports[`PromExploreQueryEditor should render component 1`] = `
|
||||
}
|
||||
}
|
||||
queryType="both"
|
||||
stepMode="min"
|
||||
stepValue="1s"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
|
||||
<FormLabel
|
||||
tooltip={
|
||||
<React.Fragment>
|
||||
Use 'Minimum' or 'Maximum' step mode to set the lower or upper bounds respectively on the interval between data points. For example, set "minimum 1h" to hint that measurements were not taken more frequently. Use the 'Exact' step mode to set an exact interval between data points.
|
||||
An additional lower limit for the step parameter of the Prometheus query and for the
|
||||
|
||||
<code>
|
||||
$__interval
|
||||
</code>
|
||||
@@ -39,47 +40,18 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
|
||||
<code>
|
||||
$__rate_interval
|
||||
</code>
|
||||
are supported.
|
||||
variables. The limit is absolute and not modified by the "Resolution" setting.
|
||||
</React.Fragment>
|
||||
}
|
||||
width={5}
|
||||
width={7}
|
||||
>
|
||||
Step
|
||||
Min step
|
||||
</FormLabel>
|
||||
<Select
|
||||
className="select-container"
|
||||
isSearchable={false}
|
||||
menuShouldPortal={true}
|
||||
onChange={[Function]}
|
||||
options={
|
||||
Array [
|
||||
Object {
|
||||
"label": "Minimum",
|
||||
"value": "min",
|
||||
},
|
||||
Object {
|
||||
"label": "Maximum",
|
||||
"value": "max",
|
||||
},
|
||||
Object {
|
||||
"label": "Exact",
|
||||
"value": "exact",
|
||||
},
|
||||
]
|
||||
}
|
||||
value={
|
||||
Object {
|
||||
"label": "Minimum",
|
||||
"value": "min",
|
||||
}
|
||||
}
|
||||
width={16}
|
||||
/>
|
||||
<input
|
||||
className="gf-form-input width-4"
|
||||
className="gf-form-input width-8"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
placeholder="15s"
|
||||
placeholder=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
@@ -192,7 +164,6 @@ exports[`Render PromQueryEditor with basic options should render 1`] = `
|
||||
"interval": "",
|
||||
"legendFormat": "",
|
||||
"refId": "A",
|
||||
"stepMode": "min",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
prometheusRegularEscape,
|
||||
prometheusSpecialRegexEscape,
|
||||
} from './datasource';
|
||||
import { PromOptions, PromQuery, StepMode } from './types';
|
||||
import { PromOptions, PromQuery } from './types';
|
||||
import { VariableHide } from '../../../features/variables/types';
|
||||
import { describe } from '../../../../test/lib/common';
|
||||
import { QueryOptions } from 'app/types';
|
||||
@@ -1685,60 +1685,6 @@ describe('PrometheusDatasource', () => {
|
||||
templateSrvStub.replace = jest.fn((a: string) => a);
|
||||
});
|
||||
});
|
||||
|
||||
describe('adjustInterval', () => {
|
||||
const dynamicInterval = 15;
|
||||
const stepInterval = 35;
|
||||
const range = 1642;
|
||||
describe('when max step option is used', () => {
|
||||
it('should return the minimum interval', () => {
|
||||
let intervalFactor = 1;
|
||||
let interval = ds.adjustInterval(dynamicInterval, stepInterval, range, intervalFactor, 'max');
|
||||
expect(interval).toBe(dynamicInterval * intervalFactor);
|
||||
|
||||
intervalFactor = 3;
|
||||
interval = ds.adjustInterval(dynamicInterval, stepInterval, range, intervalFactor, 'max');
|
||||
expect(interval).toBe(stepInterval);
|
||||
});
|
||||
});
|
||||
describe('when min step option is used', () => {
|
||||
it('should return the maximum interval', () => {
|
||||
let intervalFactor = 1;
|
||||
let interval = ds.adjustInterval(dynamicInterval, stepInterval, range, intervalFactor, 'min');
|
||||
expect(interval).toBe(stepInterval);
|
||||
|
||||
intervalFactor = 3;
|
||||
interval = ds.adjustInterval(dynamicInterval, stepInterval, range, intervalFactor, 'min');
|
||||
expect(interval).toBe(dynamicInterval * intervalFactor);
|
||||
});
|
||||
});
|
||||
describe('when exact step option is used', () => {
|
||||
it('should return the stepInterval * intervalFactor', () => {
|
||||
let intervalFactor = 3;
|
||||
let interval = ds.adjustInterval(dynamicInterval, stepInterval, range, intervalFactor, 'exact');
|
||||
expect(interval).toBe(stepInterval * intervalFactor);
|
||||
});
|
||||
});
|
||||
it('should not return a value less than the safe interval', () => {
|
||||
let newStepInterval = 0.13;
|
||||
let intervalFactor = 1;
|
||||
let stepMode: StepMode = 'min';
|
||||
let safeInterval = range / 11000;
|
||||
if (safeInterval > 1) {
|
||||
safeInterval = Math.ceil(safeInterval);
|
||||
}
|
||||
let interval = ds.adjustInterval(dynamicInterval, newStepInterval, range, intervalFactor, stepMode);
|
||||
expect(interval).toBeGreaterThanOrEqual(safeInterval);
|
||||
|
||||
stepMode = 'max';
|
||||
interval = ds.adjustInterval(dynamicInterval, newStepInterval, range, intervalFactor, stepMode);
|
||||
expect(interval).toBeGreaterThanOrEqual(safeInterval);
|
||||
|
||||
stepMode = 'exact';
|
||||
interval = ds.adjustInterval(dynamicInterval, newStepInterval, range, intervalFactor, stepMode);
|
||||
expect(interval).toBeGreaterThanOrEqual(safeInterval);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PrometheusDatasource for POST', () => {
|
||||
|
||||
@@ -39,11 +39,9 @@ import {
|
||||
PromQueryRequest,
|
||||
PromScalarData,
|
||||
PromVectorData,
|
||||
StepMode,
|
||||
} from './types';
|
||||
import { PrometheusVariableSupport } from './variables';
|
||||
import PrometheusMetricFindQuery from './metric_find_query';
|
||||
import { DEFAULT_STEP_MODE } from './components/PromQueryEditor';
|
||||
|
||||
export const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
|
||||
const EXEMPLARS_NOT_AVAILABLE = 'Exemplars for this query are not available.';
|
||||
@@ -417,12 +415,11 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
end: 0,
|
||||
};
|
||||
const range = Math.ceil(end - start);
|
||||
// target.stepMode specifies whether to use min, max or exact step
|
||||
const stepMode = target.stepMode || (DEFAULT_STEP_MODE.value as StepMode);
|
||||
|
||||
// options.interval is the dynamically calculated interval
|
||||
let interval: number = rangeUtil.intervalToSeconds(options.interval);
|
||||
// Minimum interval ("Min step"), if specified for the query, or same as interval otherwise.
|
||||
const stepInterval = rangeUtil.intervalToSeconds(
|
||||
const minInterval = rangeUtil.intervalToSeconds(
|
||||
this.templateSrv.replace(target.interval || options.interval, options.scopedVars)
|
||||
);
|
||||
// Scrape interval as specified for the query ("Min step") or otherwise taken from the datasource.
|
||||
@@ -433,7 +430,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
|
||||
const intervalFactor = target.intervalFactor || 1;
|
||||
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
|
||||
const adjustedInterval = this.adjustInterval(interval, stepInterval, range, intervalFactor, stepMode);
|
||||
const adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
|
||||
let scopedVars = {
|
||||
...options.scopedVars,
|
||||
...this.getRangeScopedVars(options.range),
|
||||
@@ -486,13 +483,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
return { __rate_interval: { text: rateInterval + 's', value: rateInterval + 's' } };
|
||||
}
|
||||
|
||||
adjustInterval(
|
||||
dynamicInterval: number,
|
||||
stepInterval: number,
|
||||
range: number,
|
||||
intervalFactor: number,
|
||||
stepMode: StepMode
|
||||
) {
|
||||
adjustInterval(interval: number, minInterval: number, range: number, intervalFactor: number) {
|
||||
// Prometheus will drop queries that might return more than 11000 data points.
|
||||
// Calculate a safe interval as an additional minimum to take into account.
|
||||
// Fractional safeIntervals are allowed, however serve little purpose if the interval is greater than 1
|
||||
@@ -501,20 +492,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
if (safeInterval > 1) {
|
||||
safeInterval = Math.ceil(safeInterval);
|
||||
}
|
||||
|
||||
//Calculate adjusted interval based on the current step option
|
||||
let adjustedInterval = safeInterval;
|
||||
if (stepMode === 'min') {
|
||||
adjustedInterval = Math.max(dynamicInterval * intervalFactor, stepInterval, safeInterval);
|
||||
} else if (stepMode === 'max') {
|
||||
adjustedInterval = Math.min(dynamicInterval * intervalFactor, stepInterval);
|
||||
if (adjustedInterval < safeInterval) {
|
||||
adjustedInterval = safeInterval;
|
||||
}
|
||||
} else if (stepMode === 'exact') {
|
||||
adjustedInterval = Math.max(stepInterval * intervalFactor, safeInterval);
|
||||
}
|
||||
return adjustedInterval;
|
||||
return Math.max(interval * intervalFactor, minInterval, safeInterval);
|
||||
}
|
||||
|
||||
performTimeSeriesQuery(query: PromQueryRequest, start: number, end: number) {
|
||||
|
||||
@@ -10,7 +10,6 @@ export interface PromQuery extends DataQuery {
|
||||
hinting?: boolean;
|
||||
interval?: string;
|
||||
intervalFactor?: number;
|
||||
stepMode?: StepMode;
|
||||
legendFormat?: string;
|
||||
valueWithRefId?: boolean;
|
||||
requestId?: string;
|
||||
@@ -18,8 +17,6 @@ export interface PromQuery extends DataQuery {
|
||||
showingTable?: boolean;
|
||||
}
|
||||
|
||||
export type StepMode = 'min' | 'max' | 'exact';
|
||||
|
||||
export interface PromOptions extends DataSourceJsonData {
|
||||
timeInterval: string;
|
||||
queryTimeout: string;
|
||||
|
||||
Reference in New Issue
Block a user