Commit d0f96230 by bergquist

feat(alertlistpanel): support state filter

ref #5981
parent b49a642c
......@@ -25,13 +25,14 @@ func ValidateOrgAlert(c *middleware.Context) {
}
}
// GET /api/alerts/rules/
// GET /api/alerts
func GetAlerts(c *middleware.Context) Response {
query := models.GetAlertsQuery{
OrgId: c.OrgId,
State: c.QueryStrings("state"),
DashboardId: c.QueryInt64("dashboardId"),
PanelId: c.QueryInt64("panelId"),
Limit: c.QueryInt64("limit"),
}
if err := bus.Dispatch(&query); err != nil {
......
......@@ -17,6 +17,7 @@ func GetAnnotations(c *middleware.Context) Response {
DashboardId: c.QueryInt64("dashboardId"),
PanelId: c.QueryInt64("panelId"),
Limit: c.QueryInt64("limit"),
NewState: c.QueryStrings("newState"),
}
repo := annotations.GetRepository()
......
......@@ -119,6 +119,7 @@ type GetAlertsQuery struct {
State []string
DashboardId int64
PanelId int64
Limit int64
Result []*Alert
}
......
......@@ -15,6 +15,7 @@ type ItemQuery struct {
AlertId int64 `json:"alertId"`
DashboardId int64 `json:"dashboardId"`
PanelId int64 `json:"panelId"`
NewState []string `json:"newState"`
Limit int64 `json:"alertId"`
}
......
......@@ -87,6 +87,11 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error {
sql.WriteString(")")
}
if query.Limit != 0 {
sql.WriteString(" LIMIT ?")
params = append(params, query.Limit)
}
alerts := make([]*m.Alert, 0)
if err := x.Sql(sql.String(), params...).Find(&alerts); err != nil {
return err
......
......@@ -3,6 +3,7 @@ package sqlstore
import (
"bytes"
"fmt"
"strings"
"github.com/go-xorm/xorm"
"github.com/grafana/grafana/pkg/services/annotations"
......@@ -63,6 +64,13 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I
params = append(params, string(query.Type))
}
if len(query.NewState) > 0 {
sql.WriteString(` AND new_state IN (?` + strings.Repeat(",?", len(query.NewState)-1) + ")")
for _, v := range query.NewState {
params = append(params, v)
}
}
if query.Limit == 0 {
query.Limit = 10
}
......
......@@ -88,7 +88,7 @@ export class AlertTabCtrl {
getAlertHistory() {
this.backendSrv.get(`/api/annotations?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}&limit=50`).then(res => {
this.alertHistory = _.map(res, ah => {
ah.time = moment(ah.timestamp).format('MMM D, YYYY HH:mm:ss');
ah.time = moment(ah.time).format('MMM D, YYYY HH:mm:ss');
ah.stateModel = alertDef.getStateDisplayModel(ah.newState);
ah.metrics = alertDef.joinEvalMatches(ah.data, ', ');
return ah;
......
......@@ -4,9 +4,33 @@
<div class="gf-form">
<span class="gf-form-label width-8">Show</span>
<div class="gf-form-select-wrapper max-width-15">
<select class="gf-form-input" ng-model="ctrl.panel.show" ng-options="f.value as f.text for f in ctrl.showOptions" ng-change="ctrl.onRender()"></select>
<select class="gf-form-input" ng-model="ctrl.panel.show" ng-options="f.value as f.text for f in ctrl.showOptions" ng-change="ctrl.onRender()"></select>
</div>
</div>
<div class="gf-form">
<span class="gf-form-label width-8">Max items</span>
<input type="text" class="gf-form-input max-width-15" ng-model="ctrl.panel.limit" />
</div>
<div class="gf-form">
<span class="gf-form-label width-8">With state</span>
<div class="gf-form-select-wrapper max-width-15">
<select class="gf-form-input" ng-model="ctrl.panel.stateFilter" ng-options="f as f for f in ctrl.alertStates" ng-change="ctrl.onRender()"></select>
</div>
</div>
</div>
<div class="section gf-form-group" ng-if="ctrl.panel.show == 'changes'">
<h5 class="section-heading">Search options</h5>
<div class="gf-form">
<span class="gf-form-label width-8">Timerange from</span>
<input type="text" placeholder="6h" class="gf-form-input max-width-4" ng-model="ctrl.panel.since" />
</div>
<div class="gf-form">
<gf-form-switch class="gf-form" label="Setting" label-class="width-8" checked="ctrl.panel.setting" on-change="ctrl.render()"></gf-form-switch>
</div>
</div>
<div class="section gf-form-group" ng-if="ctrl.panel.show == 'current'">
<h5 class="section-heading">Current state</h5>
</div>
</div>
<div class="panel-alert-list">
<section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'current'">
<ol class="card-list" >
<ol class="card-list">
<li class="card-item-wrapper" ng-repeat="alert in ctrl.currentAlerts">
<div class="card-item card-item--alert">
<div class="card-item-header">
<div class="card-item-type">
<a class="card-item-cog" href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert" bs-tooltip="'Edit alert rule'">
<i class="icon-gf icon-gf-settings"></i>
</a>
</div>
</div>
<div class="card-item-body">
<div class="card-item-details">
<div class="card-item-name">
<div class="card-item-notice">
<a href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert">
{{alert.name}}
</a>
......@@ -34,22 +26,22 @@
</ol>
</section>
<section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'changes'">
<ol class="card-list" >
<ol class="card-list">
<li class="card-item-wrapper" ng-repeat="al in ctrl.alertHistory">
<div class="card-item card-item--alert">
<div class="card-item-header">
<div class="card-item-sub-name">{{al.time}}</div>
</div>
<div class="card-item-body">
<div class="card-item-details">
<div class="card-item-notice">{{al.title}}</div>
<div class="card-item-sub-name">
<span class="alert-list-item-state {{al.stateModel.stateClass}}">
<i class="{{al.stateModel.iconClass}}"></i>
{{al.stateModel.text}}
</span> {{al.metrics}}
</div>
<div class="card-item-sub-name">
{{al.time}}
</div>
</div>
</div>
</div>
......
......@@ -4,6 +4,7 @@ import _ from 'lodash';
import moment from 'moment';
import alertDef from '../../../features/alerting/alert_def';
import config from 'app/core/config';
//import * as dateMath from 'app/core/utils/datemath';
import {PanelCtrl} from 'app/plugins/sdk';
class AlertListPanel extends PanelCtrl {
......@@ -11,14 +12,18 @@ class AlertListPanel extends PanelCtrl {
showOptions = [
{text: 'Current state', value: 'current'},
{text: 'State changes', value: 'changes'},
{text: 'Recent statechanges', value: 'changes'}
];
alertStates = [ 'all', 'ok', 'alerting', 'paused', 'no_data', 'execution_error' ];
currentAlerts: any = [];
alertHistory: any = [];
// Set and populate defaults
panelDefaults = {
show: 'current'
show: 'current',
limit: 10,
stateFilter: 'all'
};
/** @ngInject */
......@@ -37,15 +42,34 @@ class AlertListPanel extends PanelCtrl {
}
if (this.panel.show === 'changes') {
this.getAlertHistory();
this.getStateChanges();
}
}
getAlertHistory() {
this.backendSrv.get(`/api/alert-history?dashboardId=32&panelId=1`)
getStateChanges() {
var params: any = {
limit: this.panel.limit,
type: 'alert',
};
if (this.panel.stateFilter !== "all") {
params.newState = this.panel.stateFilter;
}
/*
var since = this.panel.since;
if (since !== undefined && since !== "" && since !== null) {
var t = this.dashboard.time;
var now = (new Date()).getTime();
params.to = t.to;
//this.range = this.timeSrv.timeRange();
params.from = dateMath.parseDateMath("1m", t.from, false);
}
*/
this.backendSrv.get(`/api/annotations`, params)
.then(res => {
this.alertHistory = _.map(res, al => {
al.time = moment(al.timestamp).format('MMM D, YYYY HH:mm:ss');
al.time = moment(al.time).format('MMM D, YYYY HH:mm:ss');
al.stateModel = alertDef.getStateDisplayModel(al.newState);
al.metrics = alertDef.joinEvalMatches(al.data, ', ');
return al;
......
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