From a4154b376fae636af76ca997b78659ab5c5417b1 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Thu, 12 Aug 2021 13:02:36 -0400 Subject: [PATCH] Annotations: Fix alerting annotation coloring (#37412) (#37851) Co-authored-by: Ryan McKinley (cherry picked from commit aef67994a18cf8f036ae5e0310d066dea1857132) Co-authored-by: Kyle Brandt --- pkg/services/ngalert/state/manager.go | 8 +++++--- .../annotations/standardAnnotationSupport.ts | 18 ++++++++++++++---- .../query/state/DashboardQueryRunner/utils.ts | 10 ++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pkg/services/ngalert/state/manager.go b/pkg/services/ngalert/state/manager.go index 52e4afd4669..1d77c273947 100644 --- a/pkg/services/ngalert/state/manager.go +++ b/pkg/services/ngalert/state/manager.go @@ -181,7 +181,7 @@ func (st *Manager) setNextState(alertRule *ngModels.AlertRule, result eval.Resul st.set(currentState) if oldState != currentState.State { - go st.createAlertAnnotation(currentState.State, alertRule, result) + go st.createAlertAnnotation(currentState.State, alertRule, result, oldState) } return currentState } @@ -229,7 +229,7 @@ func translateInstanceState(state ngModels.InstanceStateType) eval.State { } } -func (st *Manager) createAlertAnnotation(new eval.State, alertRule *ngModels.AlertRule, result eval.Result) { +func (st *Manager) createAlertAnnotation(new eval.State, alertRule *ngModels.AlertRule, result eval.Result, oldState eval.State) { st.log.Debug("alert state changed creating annotation", "alertRuleUID", alertRule.UID, "newState", new.String()) dashUid, ok := alertRule.Annotations["__dashboardUid__"] if !ok { @@ -255,12 +255,14 @@ func (st *Manager) createAlertAnnotation(new eval.State, alertRule *ngModels.Ale return } - annotationText := fmt.Sprintf("%s %s", result.Instance.String(), new.String()) + annotationText := fmt.Sprintf("%s {%s} - %s", alertRule.Title, result.Instance.String(), new.String()) item := &annotations.Item{ OrgId: alertRule.OrgID, DashboardId: query.Result.Id, PanelId: panelId, + PrevState: oldState.String(), + NewState: new.String(), Text: annotationText, Epoch: result.EvaluatedAt.UnixNano() / int64(time.Millisecond), } diff --git a/public/app/features/annotations/standardAnnotationSupport.ts b/public/app/features/annotations/standardAnnotationSupport.ts index beacb8f9fb7..e5d87f9e5fd 100644 --- a/public/app/features/annotations/standardAnnotationSupport.ts +++ b/public/app/features/annotations/standardAnnotationSupport.ts @@ -90,6 +90,7 @@ export interface AnnotationFieldInfo { help?: string; } +// These fields get added to the standard UI export const annotationEventNames: AnnotationFieldInfo[] = [ { key: 'time', @@ -109,9 +110,18 @@ export const annotationEventNames: AnnotationFieldInfo[] = [ { key: 'id', }, - // { key: 'userId' }, - // { key: 'login' }, - // { key: 'email' }, +]; + +// Given legacy infrastructure, alert events are passed though the same annotation +// pipeline, but include fields that should not be exposed generally +const alertEventAndAnnotationFields: AnnotationFieldInfo[] = [ + ...annotationEventNames, + { key: 'userId' }, + { key: 'login' }, + { key: 'email' }, + { key: 'prevState' }, + { key: 'newState' }, + { key: 'data' as any }, ]; export function getAnnotationsFromData( @@ -140,7 +150,7 @@ export function getAnnotationsFromData( const fields: AnnotationEventFieldSetter[] = []; - for (const evts of annotationEventNames) { + for (const evts of alertEventAndAnnotationFields) { const opt = options[evts.key] || {}; //AnnotationEventFieldMapping if (opt.source === AnnotationEventFieldSource.Skip) { diff --git a/public/app/features/query/state/DashboardQueryRunner/utils.ts b/public/app/features/query/state/DashboardQueryRunner/utils.ts index f95d1dcf261..aa9996b72bb 100644 --- a/public/app/features/query/state/DashboardQueryRunner/utils.ts +++ b/public/app/features/query/state/DashboardQueryRunner/utils.ts @@ -59,9 +59,9 @@ export function translateQueryResult(annotation: AnnotationQuery, results: Annot item.type = annotation.name; item.isRegion = Boolean(item.timeEnd && item.time !== item.timeEnd); - switch (item.newState) { + switch (item.newState?.toLowerCase()) { case 'pending': - item.color = 'gray'; + item.color = 'yellow'; break; case 'alerting': item.color = 'red'; @@ -69,9 +69,15 @@ export function translateQueryResult(annotation: AnnotationQuery, results: Annot case 'ok': item.color = 'green'; break; + case 'normal': // ngalert ("normal" instead of "ok") + item.color = 'green'; + break; case 'no_data': item.color = 'gray'; break; + case 'nodata': // ngalert + item.color = 'gray'; + break; } }