Quellcode durchsuchen

feat(alerting): add basic UI for history in alert tab

ref #5850
bergquist vor 9 Jahren
Ursprung
Commit
11a4ff0f8a

+ 37 - 1
pkg/api/alerting.go

@@ -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
+}

+ 1 - 1
pkg/api/api.go

@@ -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))
 

+ 1 - 1
pkg/api/dtos/alerting.go

@@ -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"`

+ 2 - 0
pkg/services/alerting/result_handler.go

@@ -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()

+ 16 - 0
public/app/features/alerting/alert_tab_ctrl.ts

@@ -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;
+        });
+      });
     });
   }
 

+ 22 - 0
public/app/features/alerting/partials/alert_tab.html

@@ -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>
 

+ 1 - 1
public/sass/components/edit_sidemenu.scss

@@ -5,7 +5,7 @@
 }
 
 .edit-sidemenu-aside {
-  width: 14rem;
+  width: 16rem;
 }
 
 .edit-sidemenu {