Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
29d308e4
Commit
29d308e4
authored
Jul 19, 2016
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(alerting): refactoring alert model to use conditions concept
parent
0f555d6a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
131 additions
and
146 deletions
+131
-146
public/app/plugins/panel/graph/alert_tab_ctrl.ts
+55
-50
public/app/plugins/panel/graph/partials/tab_alerting.html
+76
-96
No files found.
public/app/plugins/panel/graph/alert_tab_ctrl.ts
View file @
29d308e4
...
...
@@ -19,27 +19,23 @@ var alertQueryDef = new QueryPartDef({
defaultParams
:
[
'#A'
,
'5m'
,
'now'
,
'avg'
]
});
var
reducerAvgDef
=
new
QueryPartDef
({
type
:
'avg'
,
params
:
[],
defaultParams
:
[]
});
export
class
AlertTabCtrl
{
panel
:
any
;
panelCtrl
:
any
;
metricTargets
;
handlers
=
[{
text
:
'Grafana'
,
value
:
1
},
{
text
:
'External'
,
value
:
0
}];
transforms
=
[
{
text
:
'Aggregation'
,
type
:
'aggregation'
,
},
{
text
:
'Linear Forecast'
,
type
:
'forecast'
,
},
conditionTypes
=
[
{
text
:
'Query'
,
value
:
'query'
},
{
text
:
'Alert state'
,
value
:
'alert_state'
},
];
aggregators
=
[
'avg'
,
'sum'
,
'min'
,
'max'
,
'last'
];
alert
:
any
;
thresholds
:
any
;
query
:
any
;
queryParams
:
any
;
transformDef
:
any
;
conditionModels
:
any
;
levelOpList
=
[
{
text
:
'>'
,
value
:
'>'
},
{
text
:
'<'
,
value
:
'<'
},
...
...
@@ -76,14 +72,10 @@ export class AlertTabCtrl {
alert
.
warn
=
this
.
getThresholdWithDefaults
(
alert
.
warn
);
alert
.
crit
=
this
.
getThresholdWithDefaults
(
alert
.
crit
);
alert
.
query
=
alert
.
query
||
{};
alert
.
query
.
refId
=
alert
.
query
.
refId
||
'A'
;
alert
.
query
.
from
=
alert
.
query
.
from
||
'5m'
;
alert
.
query
.
to
=
alert
.
query
.
to
||
'now'
;
alert
.
transform
=
alert
.
transform
||
{};
alert
.
transform
.
type
=
alert
.
transform
.
type
||
'aggregation'
;
alert
.
transform
.
method
=
alert
.
transform
.
method
||
'avg'
;
alert
.
conditions
=
alert
.
conditions
||
[];
if
(
alert
.
conditions
.
length
===
0
)
{
alert
.
conditions
.
push
(
this
.
buildDefaultCondition
());
}
alert
.
frequency
=
alert
.
frequency
||
'60s'
;
alert
.
handler
=
alert
.
handler
||
1
;
...
...
@@ -93,42 +85,55 @@ export class AlertTabCtrl {
alert
.
name
=
alert
.
name
||
defaultName
;
alert
.
description
=
alert
.
description
||
defaultName
;
// great temp working model
this
.
queryParams
=
{
params
:
[
alert
.
query
.
refId
,
alert
.
query
.
from
,
alert
.
query
.
to
]
};
// init the query part components model
this
.
query
=
new
QueryPart
(
this
.
queryParams
,
alertQueryDef
);
this
.
transformDef
=
_
.
findWhere
(
this
.
transforms
,
{
type
:
alert
.
transform
.
type
});
this
.
conditionModels
=
_
.
reduce
(
alert
.
conditions
,
(
memo
,
value
)
=>
{
memo
.
push
(
this
.
buildConditionModel
(
value
));
return
memo
;
},
[]);
this
.
panelCtrl
.
editingAlert
=
true
;
this
.
panelCtrl
.
render
();
}
queryUpdated
()
{
this
.
alert
.
query
=
{
refId
:
this
.
query
.
params
[
0
],
from
:
this
.
query
.
params
[
1
],
to
:
this
.
query
.
params
[
2
],
buildDefaultCondition
()
{
return
{
type
:
'query'
,
refId
:
'A'
,
from
:
'5m'
,
to
:
'now'
,
reducer
:
'avg'
,
reducerParams
:
[],
};
}
transformChanged
()
{
// clear model
this
.
alert
.
transform
=
{
type
:
this
.
alert
.
transform
.
type
};
this
.
transformDef
=
_
.
findWhere
(
this
.
transforms
,
{
type
:
this
.
alert
.
transform
.
type
});
switch
(
this
.
alert
.
transform
.
type
)
{
case
'aggregation'
:
{
this
.
alert
.
transform
.
method
=
'avg'
;
break
;
}
case
"forecast"
:
{
this
.
alert
.
transform
.
timespan
=
'7d'
;
break
;
}
}
buildConditionModel
(
source
)
{
var
cm
:
any
=
{
source
:
source
,
type
:
source
.
type
};
var
queryPartModel
=
{
params
:
[
source
.
refId
,
source
.
from
,
source
.
to
]
};
cm
.
queryPart
=
new
QueryPart
(
queryPartModel
,
alertQueryDef
);
cm
.
reducerPart
=
new
QueryPart
({
params
:
[]},
reducerAvgDef
);
return
cm
;
}
queryPartUpdated
(
conditionModel
)
{
conditionModel
.
source
.
refId
=
conditionModel
.
queryPart
.
params
[
0
];
conditionModel
.
source
.
from
=
conditionModel
.
queryPart
.
params
[
1
];
conditionModel
.
source
.
to
=
conditionModel
.
queryPart
.
params
[
2
];
}
addCondition
(
type
)
{
var
condition
=
this
.
buildDefaultCondition
();
// add to persited model
this
.
alert
.
conditions
.
push
(
condition
);
// add to view model
this
.
conditionModels
.
push
(
this
.
buildConditionModel
(
condition
));
}
removeCondition
(
index
)
{
this
.
alert
.
conditions
.
splice
(
index
,
1
);
this
.
conditionModels
.
splice
(
index
,
1
);
}
delete
()
{
...
...
public/app/plugins/panel/graph/partials/tab_alerting.html
View file @
29d308e4
...
...
@@ -24,114 +24,94 @@
</div>
<div
ng-if=
"ctrl.alert.enabled"
>
<div
class=
"editor-row"
>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Alert Query
</h5>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form"
>
<query-part-editor
class=
"gf-form-label query-part"
part=
"ctrl.query"
part-updated=
"ctrl.queryUpdated()"
>
</query-part-editor>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Transform using
</span>
<div
class=
"gf-form-select-wrapper"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.alert.transform.type"
ng-options=
"f.type as f.text for f in ctrl.transforms"
ng-change=
"ctrl.transformChanged()"
>
</select>
</div>
</div>
<div
class=
"gf-form"
ng-if=
"ctrl.transformDef.type === 'aggregation'"
>
<span
class=
"gf-form-label"
>
Method
</span>
<div
class=
"gf-form-select-wrapper"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.alert.transform.method"
ng-options=
"f for f in ctrl.aggregators"
>
</select>
</div>
</div>
<div
class=
"gf-form"
ng-if=
"ctrl.transformDef.type === 'forecast'"
>
<span
class=
"gf-form-label"
>
Timespan
</span>
<input
class=
"gf-form-input max-width-5"
type=
"text"
ng-model=
"ctrl.alert.transform.timespan"
ng-change=
"ctrl.ruleUpdated()"
></input>
</div>
<div
class=
"gf-form-group"
>
<h5
class=
"section-heading"
>
Alert Rule
</h5>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-8"
>
Name
</span>
<input
type=
"text"
class=
"gf-form-input width-22"
ng-model=
"ctrl.alert.name"
>
</div>
</div>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Thresholds
</h5>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
<i
class=
"icon-gf icon-gf-warn alert-icon-critical"
></i>
Critcal if
</span>
<metric-segment-model
property=
"ctrl.alert.crit.op"
options=
"ctrl.operatorList"
custom=
"false"
css-class=
"query-segment-operator"
on-change=
"ctrl.thresholdsUpdated()"
></metric-segment-model>
<input
class=
"gf-form-input max-width-7"
type=
"number"
ng-model=
"ctrl.alert.crit.value"
ng-change=
"ctrl.thresholdsUpdated()"
></input>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
<i
class=
"icon-gf icon-gf-warn alert-icon-warn"
></i>
Warn if
</span>
<metric-segment-model
property=
"ctrl.alert.warn.op"
options=
"ctrl.operatorList"
custom=
"false"
css-class=
"query-segment-operator"
on-change=
"ctrl.thresholdsUpdated()"
></metric-segment-model>
<input
class=
"gf-form-input max-width-7"
type=
"number"
ng-model=
"ctrl.alert.warn.value"
ng-change=
"ctrl.thresholdsUpdated()"
></input>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Handler
</span>
<div
class=
"gf-form-select-wrapper"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.alert.handler"
ng-options=
"f.value as f.text for f in ctrl.handlers"
>
</select>
</div>
</div>
</div>
</div>
<div
class=
"editor-row"
>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Execution
</h5>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Handler
</span>
<div
class=
"gf-form-select-wrapper"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.alert.handler"
ng-options=
"f.value as f.text for f in ctrl.handlers"
>
</select>
</div>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Evaluate every
</span>
<input
class=
"gf-form-input max-width-7"
type=
"text"
ng-model=
"ctrl.alert.frequency"
></input>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-8"
>
Evaluate every
</span>
<input
class=
"gf-form-input max-width-7"
type=
"text"
ng-model=
"ctrl.alert.frequency"
></input>
</div>
</div>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Notifications
</h5>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Groups
</span>
<input
class=
"gf-form-input max-width-7"
type=
"text"
ng-model=
"ctrl.alert.notify"
></input>
<!--
<bootstrap-tagsinput ng-model="ctrl.alert.notify" tagclass="label label-tag" placeholder="add tags">
</bootstrap-tagsinput>
-->
</div>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-8"
>
Notifications
</span>
<input
class=
"gf-form-input max-width-22"
type=
"text"
ng-model=
"ctrl.alert.notify"
></input>
<!--
<bootstrap-tagsinput ng-model="ctrl.alert.notify" tagclass="label label-tag" placeholder="add tags">
</bootstrap-tagsinput>
-->
</div>
</div>
<div
class=
"gf-form-group section"
>
<h5
class=
"section-heading"
>
Information
</h5>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label width-10"
>
Alert name
</span>
<input
type=
"text"
class=
"gf-form-input width-22"
ng-model=
"ctrl.alert.name"
>
</div>
<div
class=
"gf-form-inline"
>
<div
class=
"gf-form-group"
>
<h5
class=
"section-heading"
>
Conditions
</h5>
<div
class=
"gf-form-inline"
ng-repeat=
"conditionModel in ctrl.conditionModels"
>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label
width-10"
style=
"margin-top: -73px;"
>
Alert description
</span>
<span
class=
"gf-form-label
"
>
{{$index+1}}
</span>
</div>
<div
class=
"gf-form"
>
<textarea
rows=
"5"
ng-model=
"ctrl.alert.description"
class=
"gf-form-input width-22"
></textarea>
<query-part-editor
class=
"gf-form-label query-part"
part=
"conditionModel.queryPart"
part-updated=
"ctrl.queryPartUpdated(conditionModel)"
>
</query-part-editor>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
Reduce
</span>
<query-part-editor
class=
"gf-form-label query-part"
part=
"conditionModel.reducerPart"
part-updated=
"ctrl.reducerPartUpdated(conditionModel)"
>
</query-part-editor>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
<i
class=
"icon-gf icon-gf-warn alert-icon-critical"
></i>
Critcal if
</span>
<metric-segment-model
property=
"ctrl.alert.crit.op"
options=
"ctrl.operatorList"
custom=
"false"
css-class=
"query-segment-operator"
on-change=
"ctrl.thresholdsUpdated()"
></metric-segment-model>
<input
class=
"gf-form-input max-width-7"
type=
"number"
ng-model=
"ctrl.alert.crit.value"
ng-change=
"ctrl.thresholdsUpdated()"
></input>
</div>
<div
class=
"gf-form"
>
<span
class=
"gf-form-label"
>
<i
class=
"icon-gf icon-gf-warn alert-icon-warn"
></i>
Warn if
</span>
<metric-segment-model
property=
"ctrl.alert.warn.op"
options=
"ctrl.operatorList"
custom=
"false"
css-class=
"query-segment-operator"
on-change=
"ctrl.thresholdsUpdated()"
></metric-segment-model>
<input
class=
"gf-form-input max-width-7"
type=
"number"
ng-model=
"ctrl.alert.warn.value"
ng-change=
"ctrl.thresholdsUpdated()"
></input>
<label
class=
"gf-form-label"
>
<a
class=
"pointer"
tabindex=
"1"
ng-click=
"ctrl.removeCondition($index)"
>
<i
class=
"fa fa-trash"
></i>
</a>
</label>
</div>
</div>
</div>
<div
class=
"gf-form-group"
>
<div
class=
"dropdown"
>
<button
class=
"btn btn-inverse dropdown-toggle gf-form-btn"
data-toggle=
"dropdown"
>
<i
class=
"fa fa-plus"
></i>
Add Condition
</button>
<ul
class=
"dropdown-menu"
role=
"menu"
>
<li
ng-repeat=
"ct in ctrl.conditionTypes"
role=
"menuitem"
>
<a
ng-click=
"ctrl.addCondition(ct.value);"
>
{{ct.text}}
</a>
</li>
</ul>
</div>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment