mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
650a87dc05
commit
11a4ff0f8a
@ -215,8 +215,13 @@ func DeleteAlertNotification(c *middleware.Context) Response {
|
||||
}
|
||||
|
||||
func GetAlertHistory(c *middleware.Context) Response {
|
||||
alertId, err := getAlertIdForRequest(c)
|
||||
if err != nil {
|
||||
return ApiError(400, "Invalid request", err)
|
||||
}
|
||||
|
||||
query := &annotations.ItemQuery{
|
||||
AlertId: c.ParamsInt64("alertId"),
|
||||
AlertId: alertId,
|
||||
Type: annotations.AlertType,
|
||||
OrgId: c.OrgId,
|
||||
Limit: c.QueryInt64("limit"),
|
||||
@ -244,3 +249,34 @@ func GetAlertHistory(c *middleware.Context) Response {
|
||||
|
||||
return Json(200, result)
|
||||
}
|
||||
|
||||
func getAlertIdForRequest(c *middleware.Context) (int64, error) {
|
||||
alertId := c.QueryInt64("alertId")
|
||||
panelId := c.QueryInt64("panelId")
|
||||
dashboardId := c.QueryInt64("dashboardId")
|
||||
|
||||
if alertId == 0 && dashboardId == 0 && panelId == 0 {
|
||||
return 0, fmt.Errorf("Missing alertId or dashboardId and panelId")
|
||||
}
|
||||
|
||||
if alertId == 0 {
|
||||
//fetch alertId
|
||||
query := models.GetAlertsQuery{
|
||||
OrgId: c.OrgId,
|
||||
DashboardId: dashboardId,
|
||||
PanelId: panelId,
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(query.Result) != 1 {
|
||||
return 0, fmt.Errorf("PanelId is not unique on dashboard")
|
||||
}
|
||||
|
||||
alertId = query.Result[0].Id
|
||||
}
|
||||
|
||||
return alertId, nil
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/", wrap(GetAlerts))
|
||||
})
|
||||
|
||||
r.Get("/alert-history/:alertId", ValidateOrgAlert, wrap(GetAlertHistory))
|
||||
r.Get("/alert-history", wrap(GetAlertHistory))
|
||||
|
||||
r.Get("/alert-notifications", wrap(GetAlertNotifications))
|
||||
|
||||
|
@ -55,7 +55,7 @@ type EvalMatch struct {
|
||||
|
||||
type AlertHistory struct {
|
||||
AlertId int64 `json:"alertId"`
|
||||
NewState string `json:"netState"`
|
||||
NewState string `json:"newState"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
@ -65,6 +66,7 @@ func (handler *DefaultResultHandler) Handle(ctx *EvalContext) {
|
||||
NewState: string(ctx.Rule.State),
|
||||
PrevState: string(oldState),
|
||||
Timestamp: time.Now(),
|
||||
Data: simplejson.NewFromAny(ctx.EvalMatches),
|
||||
}
|
||||
|
||||
annotationRepo := annotations.GetRepository()
|
||||
|
@ -5,6 +5,7 @@ import {ThresholdMapper} from './threshold_mapper';
|
||||
import {QueryPart} from 'app/core/components/query_part/query_part';
|
||||
import alertDef from './alert_def';
|
||||
import config from 'app/core/config';
|
||||
import moment from 'moment';
|
||||
|
||||
export class AlertTabCtrl {
|
||||
panel: any;
|
||||
@ -22,6 +23,7 @@ export class AlertTabCtrl {
|
||||
alertNotifications;
|
||||
error: string;
|
||||
appSubUrl: string;
|
||||
alertHistory: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope,
|
||||
@ -60,6 +62,7 @@ export class AlertTabCtrl {
|
||||
// build notification model
|
||||
this.notifications = [];
|
||||
this.alertNotifications = [];
|
||||
this.alertHistory = [];
|
||||
|
||||
return this.backendSrv.get('/api/alert-notifications').then(res => {
|
||||
this.notifications = res;
|
||||
@ -71,6 +74,19 @@ export class AlertTabCtrl {
|
||||
this.alertNotifications.push(model);
|
||||
}
|
||||
});
|
||||
}).then(() => {
|
||||
this.backendSrv.get(`/api/alert-history?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}`).then(res => {
|
||||
this.alertHistory = _.map(res, (ah) => {
|
||||
ah.time = moment(ah.timestamp).format('MMM D, YYYY HH:mm:ss');
|
||||
ah.stateModel = alertDef.getStateDisplayModel(ah.newState);
|
||||
|
||||
ah.metrics = _.map(ah.data, (ev) => {
|
||||
return ev.Metric + "=" + ev.Value;
|
||||
}).join(', ');
|
||||
|
||||
return ah;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,28 @@
|
||||
<textarea class="gf-form-input width-20" rows="10" ng-model="ctrl.alert.message" placeholder="Notification message details..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" style="width: 60%; margin-left: 8rem;" ng-if="ctrl.subTabIndex === 2">
|
||||
<h5 class="section-heading">Alert history</h5>
|
||||
<section class="card-section card-list-layout-list">
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="ah in ctrl.alertHistory">
|
||||
<div class="card-item card-item--alert">
|
||||
<div class="card-item-body">
|
||||
<div class="card-item-details">
|
||||
<div class="card-item-sub-name">
|
||||
<span class="alert-list-item-state {{ah.stateModel.stateClass}}">
|
||||
<i class="{{ah.stateModel.iconClass}}"></i>
|
||||
{{ah.text}}
|
||||
</span> at {{ah.time}} {{ah.metrics}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
}
|
||||
|
||||
.edit-sidemenu-aside {
|
||||
width: 14rem;
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
.edit-sidemenu {
|
||||
|
Loading…
Reference in New Issue
Block a user