adding within range support: the good, the bad, and the ugly

pull/725/head
Hunter Trujillo 2016-12-21 16:22:38 -07:00 committed by Andrew Watkins
parent 561d73ea22
commit 0da923cb97
5 changed files with 37 additions and 26 deletions

View File

@ -143,9 +143,9 @@ type TriggerValues struct {
Period string `json:"period,omitempty"` // Period length of time before deadman is alerted
Shift string `json:"shift,omitempty"` // Shift is the amount of time to look into the past for the alert to compare to the present
Operator string `json:"operator,omitempty"` // Operator for alert comparison
RangeOperator string `json:"range_operator,omitempty"` // RangeOperator is an optional operator for range comparisons
RangeOperator string `json:"rangeOperator,omitempty"` // RangeOperator is an optional operator for range comparisons
Value string `json:"value,omitempty"` // Value is the boundary value when alert goes critical
RangeValue string `json:"range_value,omitempty"` // RangeValue is an optional value for range comparisons
RangeValue string `json:"rangeValue,omitempty"` // RangeValue is an optional value for range comparisons
}
// Field represent influxql fields and functions from the UI

View File

@ -1,10 +1,22 @@
import AJAX from 'utils/ajax';
function rangeRule(rule) {
if (rule.values.operator === 'within range') {
const {value, rangeValue} = rule.values;
rule.values.operator = 'less than';
rule.values.rangeOperator = 'greater than';
rule.values.value = Math.min(value, rangeValue).toString();
rule.values.rangeValue = Math.max(value, rangeValue).toString();
}
console.log(rule.values);
return rule;
}
export function createRule(kapacitor, rule) {
return AJAX({
method: 'POST',
url: kapacitor.links.rules,
data: rule,
data: rangeRule(rule),
});
}
@ -26,7 +38,7 @@ export function editRule(rule) {
return AJAX({
method: 'PUT',
url: rule.links.self,
data: rule,
data: rangeRule(rule),
});
}

View File

@ -5,6 +5,8 @@ import {OPERATORS, PERIODS, CHANGES, SHIFTS} from 'src/kapacitor/constants';
import _ from 'lodash';
const TABS = ['Threshold', 'Relative', 'Deadman'];
const mapToItems = (arr, type) => arr.map((text) => ({text, type}));
export const ValuesSection = React.createClass({
propTypes: {
rule: PropTypes.shape({
@ -65,7 +67,9 @@ const Threshold = React.createClass({
rule: PropTypes.shape({
values: PropTypes.shape({
operator: PropTypes.string,
rangeOperator: PropTypes.string,
value: PropTypes.string,
rangeValue: PropTypes.string,
}),
}),
onChange: PropTypes.func.isRequired,
@ -74,26 +78,21 @@ const Threshold = React.createClass({
handleDropdownChange(item) {
const newValues = Object.assign({}, this.props.rule.values, {[item.type]: item.text});
this.props.onChange(newValues);
this.props.onChange({...this.props.rule.values, [item.type]: item.text});
},
handleInputChange() {
this.props.onChange(Object.assign({}, this.props.rule.values, {
this.props.onChange({
...this.props.rule.values,
value: this.valueInput.value,
}));
rangeValue: this.valueRangeInput ? this.valueRangeInput.value : '',
});
},
render() {
const {operator, value} = this.props.rule.values;
const {operator, value, rangeValue} = this.props.rule.values;
const {query} = this.props;
function mapToItems(arr, type) {
return arr.map((text) => {
return {text, type};
});
}
const operators = mapToItems(OPERATORS, 'operator');
return (
@ -102,7 +101,10 @@ const Threshold = React.createClass({
<span>{query.fields.length ? query.fields[0].field : 'Select a Metric'}</span>
<p>is</p>
<Dropdown className="size-176 dropdown-kapacitor" items={operators} selected={operator} onChoose={this.handleDropdownChange} />
<input className="form-control input-sm size-166 form-control--green" type="text" ref={(r) => this.valueInput = r} defaultValue={value} onKeyUp={this.handleInputChange}></input>
<input className="form-control input-sm size-166 form-control--green" type="text" ref={(r) => this.valueInput = r} defaultValue={value} onKeyUp={this.handleInputChange} />
{ operator === 'within range' &&
<input className="form-control input-sm size-166 form-control--green" type="text" ref={(r) => this.valueRangeInput = r} defaultValue={rangeValue} onKeyUp={this.handleInputChange} />
}
</div>
);
},
@ -122,22 +124,16 @@ const Relative = React.createClass({
},
handleDropdownChange(item) {
this.props.onChange(Object.assign({}, this.props.rule.values, {[item.type]: item.text}));
this.props.onChange({...this.props.rule.values, [item.type]: item.text});
},
handleInputChange() {
this.props.onChange(Object.assign({}, this.props.rule.values, {value: this.input.value}));
this.props.onChange({...this.props.rule.values, value: this.input.value});
},
render() {
const {change, shift, operator, value} = this.props.rule.values;
function mapToItems(arr, type) {
return arr.map((text) => {
return {text, type};
});
}
const changes = mapToItems(CHANGES, 'change');
const shifts = mapToItems(SHIFTS, 'shift');
const operators = mapToItems(OPERATORS, 'operator');

View File

@ -11,12 +11,13 @@ export const defaultRuleConfigs = {
threshold: {
operator: 'greater than',
value: '',
rangeValue: '',
relation: 'once',
percentile: '90',
},
};
export const OPERATORS = ['greater than', 'equal to or greater', 'equal to or less than', 'less than', 'equal to', 'not equal to'];
export const OPERATORS = ['greater than', 'equal to or greater', 'equal to or less than', 'less than', 'equal to', 'not equal to', 'within range'];
// export const RELATIONS = ['once', 'more than ', 'less than'];
export const PERIODS = ['1m', '5m', '10m', '30m', '1h', '2h', '24h'];
export const CHANGES = ['change', '% change'];

View File

@ -13,8 +13,10 @@ const rootReducer = combineReducers({
rules: rulesReducer,
});
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export default function configureStore(initialState) {
const createPersistentStore = compose(
const createPersistentStore = composeEnhancers(
persistStateEnhancer(),
applyMiddleware(thunkMiddleware, makeQueryExecuter()),
)(createStore);