mirror of https://github.com/prometheus/prometheus
filtering alerts by state and display count of alerts in each state (#5758)
* local storage selectedTab on targets tab was renamed Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com> * added filters when displaying alerts Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com> * function was simplified Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com> * fixed rebase Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com> * minor rename Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com> * Active -> Pending Signed-off-by: Michał Szczygieł <1153719+mszczygiel@users.noreply.github.com>pull/6129/head^2
parent
6d931a2195
commit
040425b0eb
|
@ -26,6 +26,41 @@ function init() {
|
||||||
targetEl.removeClass('is-checked');
|
targetEl.removeClass('is-checked');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function displayAlerts(alertState, shouldDisplay) {
|
||||||
|
$("#alertsTable > tbody > tr." + alertState).each(function(_, container) {
|
||||||
|
$(container).toggle(shouldDisplay);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(localStorage.hideInactiveAlerts === "true") {
|
||||||
|
$("#inactiveAlerts").parent().removeClass("active");
|
||||||
|
displayAlerts("alert-success", false);
|
||||||
|
}
|
||||||
|
if(localStorage.hidePendingAlerts === "true") {
|
||||||
|
$("#pendingAlerts").parent().removeClass("active");
|
||||||
|
displayAlerts("alert-warning", false);
|
||||||
|
}
|
||||||
|
if(localStorage.hideFiringAlerts === "true") {
|
||||||
|
$("#firingAlerts").parent().removeClass("active");
|
||||||
|
displayAlerts("alert-danger", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#alertFilters :input").change(function() {
|
||||||
|
const target = $(this).attr("id");
|
||||||
|
var shouldHide = $(this).parent().hasClass("active");
|
||||||
|
if (target === "inactiveAlerts") {
|
||||||
|
localStorage.setItem("hideInactiveAlerts", shouldHide);
|
||||||
|
displayAlerts("alert-success", !shouldHide);
|
||||||
|
} else if (target === "pendingAlerts") {
|
||||||
|
localStorage.setItem("hidePendingAlerts", shouldHide);
|
||||||
|
displayAlerts("alert-warning", !shouldHide);
|
||||||
|
} else if (target === "firingAlerts") {
|
||||||
|
localStorage.setItem("hideFiringAlerts", shouldHide);
|
||||||
|
displayAlerts("alert-danger", !shouldHide);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(init);
|
$(init);
|
||||||
|
|
|
@ -22,10 +22,10 @@ function showUnhealthy(_, container) {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if ($("#unhealthy-targets").length) {
|
if ($("#unhealthy-targets").length) {
|
||||||
if (!localStorage.selectedTab || localStorage.selectedTab == "all-targets") {
|
if (!localStorage.selectedTargetsTab || localStorage.selectedTargetsTab == "all-targets") {
|
||||||
$("#all-targets").parent().addClass("active");
|
$("#all-targets").parent().addClass("active");
|
||||||
$(".table-container").each(showAll);
|
$(".table-container").each(showAll);
|
||||||
} else if (localStorage.selectedTab == "unhealthy-targets") {
|
} else if (localStorage.selectedTargetsTab == "unhealthy-targets") {
|
||||||
$("#unhealthy-targets").parent().addClass("active");
|
$("#unhealthy-targets").parent().addClass("active");
|
||||||
$(".table-container").each(showUnhealthy);
|
$(".table-container").each(showUnhealthy);
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,10 @@ function init() {
|
||||||
|
|
||||||
if (target === "all-targets") {
|
if (target === "all-targets") {
|
||||||
$(".table-container").each(showAll);
|
$(".table-container").each(showAll);
|
||||||
localStorage.setItem("selectedTab", "all-targets");
|
localStorage.setItem("selectedTargetsTab", "all-targets");
|
||||||
} else if (target === "unhealthy-targets") {
|
} else if (target === "unhealthy-targets") {
|
||||||
$(".table-container").each(showUnhealthy);
|
$(".table-container").each(showUnhealthy);
|
||||||
localStorage.setItem("selectedTab", "unhealthy-targets");
|
localStorage.setItem("selectedTargetsTab", "unhealthy-targets");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,23 @@
|
||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<h1>Alerts</h1>
|
<h1>Alerts</h1>
|
||||||
|
<div id="alertFilters" class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||||
|
<label class="btn btn-primary active">
|
||||||
|
<input type="checkbox" name="alertFilters" id="inactiveAlerts" autocomplete="off"> Inactive ({{ .Counts.Inactive }})
|
||||||
|
</label>
|
||||||
|
<label class="btn btn-primary active">
|
||||||
|
<input type="checkbox" name="alertFilters" id="pendingAlerts" autocomplete="off"> Pending ({{ .Counts.Pending }})
|
||||||
|
</label>
|
||||||
|
<label class="btn btn-primary active">
|
||||||
|
<input type="checkbox" name="alertFilters" id="firingAlerts" autocomplete="off"> Firing ({{ .Counts.Firing }})
|
||||||
|
</label>
|
||||||
|
</br>
|
||||||
|
</div>
|
||||||
<div class="show-annotations">
|
<div class="show-annotations">
|
||||||
<i class="glyphicon glyphicon-unchecked"></i>
|
<i class="glyphicon glyphicon-unchecked"></i>
|
||||||
<button type="button" class="show-annotations" title="show annotations">Show annotations</button>
|
<button type="button" class="show-annotations" title="show annotations">Show annotations</button>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-bordered table-collapsed">
|
<table id="alertsTable" class="table table-bordered table-collapsed">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{$alertStateToRowClass := .AlertStateToRowClass}}
|
{{$alertStateToRowClass := .AlertStateToRowClass}}
|
||||||
{{range .Groups}}
|
{{range .Groups}}
|
||||||
|
|
26
web/web.go
26
web/web.go
|
@ -579,10 +579,29 @@ func (h *Handler) alerts(w http.ResponseWriter, r *http.Request) {
|
||||||
rules.StatePending: "warning",
|
rules.StatePending: "warning",
|
||||||
rules.StateFiring: "danger",
|
rules.StateFiring: "danger",
|
||||||
},
|
},
|
||||||
|
Counts: alertCounts(groups),
|
||||||
}
|
}
|
||||||
h.executeTemplate(w, "alerts.html", alertStatus)
|
h.executeTemplate(w, "alerts.html", alertStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func alertCounts(groups []*rules.Group) AlertByStateCount {
|
||||||
|
result := AlertByStateCount{}
|
||||||
|
|
||||||
|
for _, group := range groups {
|
||||||
|
for _, alert := range group.AlertingRules() {
|
||||||
|
switch alert.State() {
|
||||||
|
case rules.StateInactive:
|
||||||
|
result.Inactive++
|
||||||
|
case rules.StatePending:
|
||||||
|
result.Pending++
|
||||||
|
case rules.StateFiring:
|
||||||
|
result.Firing++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
name := route.Param(ctx, "filepath")
|
name := route.Param(ctx, "filepath")
|
||||||
|
@ -997,4 +1016,11 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter
|
||||||
type AlertStatus struct {
|
type AlertStatus struct {
|
||||||
Groups []*rules.Group
|
Groups []*rules.Group
|
||||||
AlertStateToRowClass map[rules.AlertState]string
|
AlertStateToRowClass map[rules.AlertState]string
|
||||||
|
Counts AlertByStateCount
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertByStateCount struct {
|
||||||
|
Inactive int32
|
||||||
|
Pending int32
|
||||||
|
Firing int32
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue