{% package main %} {% import ( "time" "sort" "net/http" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/tpl" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier" ) %} {% func Welcome(r *http.Request) %} {%= tpl.Header(r, navItems, "vmalert", getLastConfigError()) %}

API:
{% for _, p := range apiLinks %} {%code p, doc := p[0], p[1] %} {%s p %} - {%s doc %}
{% endfor %} {% if r.Header.Get("X-Forwarded-For") == "" %} System:
{% for _, p := range systemLinks %} {%code p, doc := p[0], p[1] %} {%s p %} - {%s doc %}
{% endfor %} {% endif %}

{%= tpl.Footer(r) %} {% endfunc %} {% func buttonActive(filter, expValue string) %} {% if filter != expValue %} btn-secondary {% else %} btn-primary {% endif %} {% endfunc %} {% func ListGroups(r *http.Request, originGroups []apiGroup) %} {%code prefix := utils.Prefix(r.URL.Path) %} {%= tpl.Header(r, navItems, "Groups", getLastConfigError()) %} {%code filter := r.URL.Query().Get("filter") rOk := make(map[string]int) rNotOk := make(map[string]int) rNoMatch := make(map[string]int) var groups []apiGroup for _, g := range originGroups { var rules []apiRule for _, r := range g.Rules { if r.LastError != "" { rNotOk[g.ID]++ } else { rOk[g.ID]++ } if isNoMatch(r) { rNoMatch[g.ID]++ } if (filter == "unhealthy" && r.LastError == "") || (filter == "noMatch" && !isNoMatch(r)) { continue } rules = append(rules, r) } if len(rules) > 0 { g.Rules = rules groups = append(groups, g) } } %} All Collapse All Expand All Unhealthy NoMatch {% if len(groups) > 0 %} {% for _, g := range groups %}
{%s g.Name %}{% if g.Type != "prometheus" %} ({%s g.Type %}){% endif %} (every {%f.0 g.Interval %}s) # {% if rNotOk[g.ID] > 0 %}{%d rNotOk[g.ID] %} {% endif %} {% if rNoMatch[g.ID] > 0 %}{%d rNoMatch[g.ID] %} {% endif %} {%d rOk[g.ID] %}

{%s g.File %}

{% if len(g.Params) > 0 %}
Extra params {% for _, param := range g.Params %} {%s param %} {% endfor %}
{% endif %} {% if len(g.Headers) > 0 %}
Extra headers {% for _, header := range g.Headers %} {%s header %} {% endfor %}
{% endif %}
{% for _, r := range g.Rules %} {% endfor %}
Rule Samples Updated
{% if r.Type == "alerting" %} {% if r.KeepFiringFor > 0 %} alert: {%s r.Name %} (for: {%v r.Duration %} seconds, keep_firing_for: {%v r.KeepFiringFor %} seconds) {% else %} alert: {%s r.Name %} (for: {%v r.Duration %} seconds) {% endif %} {% else %} record: {%s r.Name %} {% endif %} | {%= seriesFetchedWarn(r) %} Details
{%s r.Query %}
{% if len(r.Labels) > 0 %} Labels:{% endif %} {% for k, v := range r.Labels %} {%s k %}={%s v %} {% endfor %}
{% if r.LastError != "" %}
Error:
{%s r.LastError %}
{% endif %}
{%d r.LastSamples %} {%f.3 time.Since(r.LastEvaluation).Seconds() %}s ago
{% endfor %} {% else %}

No groups...

{% endif %} {%= tpl.Footer(r) %} {% endfunc %} {% func ListAlerts(r *http.Request, groupAlerts []groupAlerts) %} {%code prefix := utils.Prefix(r.URL.Path) %} {%= tpl.Header(r, navItems, "Alerts", getLastConfigError()) %} {% if len(groupAlerts) > 0 %} Collapse All Expand All {% for _, ga := range groupAlerts %} {%code g := ga.Group %}
{%s g.Name %}{% if g.Type != "prometheus" %} ({%s g.Type %}){% endif %} {%d len(ga.Alerts) %}

{%s g.File %}

{%code var keys []string alertsByRule := make(map[string][]*apiAlert) for _, alert := range ga.Alerts { if len(alertsByRule[alert.RuleID]) < 1 { keys = append(keys, alert.RuleID) } alertsByRule[alert.RuleID] = append(alertsByRule[alert.RuleID], alert) } sort.Strings(keys) %}
{% for _, ruleID := range keys %} {%code defaultAR := alertsByRule[ruleID][0] var labelKeys []string for k := range defaultAR.Labels { labelKeys = append(labelKeys, k) } sort.Strings(labelKeys) %}
alert: {%s defaultAR.Name %} ({%d len(alertsByRule[ruleID]) %}) | Source
expr:
{%s defaultAR.Expression %}
{% for _, ar := range alertsByRule[ruleID] %} {% endfor %}
Labels State Active at Value Link
{% for _, k := range labelKeys %} {%s k %}={%s ar.Labels[k] %} {% endfor %} {%= badgeState(ar.State) %} {%s ar.ActiveAt.Format("2006-01-02T15:04:05Z07:00") %} {% if ar.Restored %}{%= badgeRestored() %}{% endif %} {% if ar.Stabilizing %}{%= badgeStabilizing() %}{% endif %} {%s ar.Value %} Details
{% endfor %}

{% endfor %} {% else %}

No active alerts...

{% endif %} {%= tpl.Footer(r) %} {% endfunc %} {% func ListTargets(r *http.Request, targets map[notifier.TargetType][]notifier.Target) %} {%= tpl.Header(r, navItems, "Notifiers", getLastConfigError()) %} {% if len(targets) > 0 %} Collapse All Expand All {%code var keys []string for key := range targets { keys = append(keys, string(key)) } sort.Strings(keys) %} {% for i := range keys %} {%code typeK, ns := keys[i], targets[notifier.TargetType(keys[i])] count := len(ns) %}
{%s typeK %} ({%d count %})
{% for _, n := range ns %} {% endfor %}
Labels Address
{% for _, l := range n.Labels.GetLabels() %} {%s l.Name %}={%s l.Value %} {% endfor %} {%s n.Notifier.Addr() %}
{% endfor %} {% else %}

No targets...

{% endif %} {%= tpl.Footer(r) %} {% endfunc %} {% func Alert(r *http.Request, alert *apiAlert) %} {%code prefix := utils.Prefix(r.URL.Path) %} {%= tpl.Header(r, navItems, "", getLastConfigError()) %} {%code var labelKeys []string for k := range alert.Labels { labelKeys = append(labelKeys, k) } sort.Strings(labelKeys) var annotationKeys []string for k := range alert.Annotations { annotationKeys = append(annotationKeys, k) } sort.Strings(annotationKeys) %}
Alert: {%s alert.Name %}{%s alert.State %}
Active at
{%s alert.ActiveAt.Format("2006-01-02T15:04:05Z07:00") %}
Expr
{%s alert.Expression %}
Labels
{% for _, k := range labelKeys %} {%s k %}={%s alert.Labels[k] %} {% endfor %}
Annotations
{% for _, k := range annotationKeys %} {%s k %}:

{%s alert.Annotations[k] %}

{% endfor %}
Group
Source link
{%= tpl.Footer(r) %} {% endfunc %} {% func RuleDetails(r *http.Request, rule apiRule) %} {%code prefix := utils.Prefix(r.URL.Path) %} {%= tpl.Header(r, navItems, "", getLastConfigError()) %} {%code var labelKeys []string for k := range rule.Labels { labelKeys = append(labelKeys, k) } sort.Strings(labelKeys) var annotationKeys []string for k := range rule.Annotations { annotationKeys = append(annotationKeys, k) } sort.Strings(annotationKeys) var seriesFetchedEnabled bool var seriesFetchedWarning bool for _, u := range rule.Updates { if u.SeriesFetched != nil { seriesFetchedEnabled = true if *u.SeriesFetched == 0 && u.Samples == 0{ seriesFetchedWarning = true } } } %}
Rule: {%s rule.Name %}{%s rule.Health %}
Expr
{%s rule.Query %}
{% if rule.Type == "alerting" %}
For
{%v rule.Duration %} seconds
{% if rule.KeepFiringFor > 0 %}
Keep firing for
{%v rule.KeepFiringFor %} seconds
{% endif %} {% endif %}
Labels
{% for _, k := range labelKeys %} {%s k %}={%s rule.Labels[k] %} {% endfor %}
{% if rule.Type == "alerting" %}
Annotations
{% for _, k := range annotationKeys %} {%s k %}:

{%s rule.Annotations[k] %}

{% endfor %}
Debug
{%v rule.Debug %}
{% endif %}
Group

{% if seriesFetchedWarning %} {% endif %}
Last {%d len(rule.Updates) %}/{%d rule.MaxUpdates %} updates:
{% if seriesFetchedEnabled %}{% endif %} {% for _, u := range rule.Updates %} {% if seriesFetchedEnabled %}{% endif %} {% if u.Err != nil %} {% endif %} {% endfor %} {%= tpl.Footer(r) %} {% endfunc %} {% func badgeState(state string) %} {%code badgeClass := "bg-warning text-dark" if state == "firing" { badgeClass = "bg-danger" } %} {%s state %} {% endfunc %} {% func badgeRestored() %} restored {% endfunc %} {% func badgeStabilizing() %} stabilizing {% endfunc %} {% func seriesFetchedWarn(r apiRule) %} {% if isNoMatch(r) %} {% endif %} {% endfunc %} {%code func isNoMatch (r apiRule) bool { return r.LastSamples == 0 && r.LastSeriesFetched != nil && *r.LastSeriesFetched == 0 } %}
Updated at SamplesSeries fetchedDuration Executed at cURL
{%s u.Time.Format(time.RFC3339) %} {%d u.Samples %}{% if u.SeriesFetched != nil %}{%d *u.SeriesFetched %}{% endif %}{%f.3 u.Duration.Seconds() %}s {%s u.At.Format(time.RFC3339) %}
{%v u.Err %}