diff --git a/retrieval/target.go b/retrieval/target.go index c51f5048cf..ac52eb4129 100644 --- a/retrieval/target.go +++ b/retrieval/target.go @@ -73,11 +73,11 @@ type TargetHealth int func (t TargetHealth) String() string { switch t { case HealthUnknown: - return "UNKNOWN" + return "unknown" case HealthGood: - return "HEALTHY" + return "healthy" case HealthBad: - return "UNHEALTHY" + return "unhealthy" } panic("unknown state") } diff --git a/rules/alerting.go b/rules/alerting.go index 54514db9bb..49655740df 100644 --- a/rules/alerting.go +++ b/rules/alerting.go @@ -209,23 +209,38 @@ func (rule *AlertingRule) eval(timestamp clientmodel.Timestamp, engine *promql.E } func (rule *AlertingRule) String() string { - return fmt.Sprintf("ALERT %s IF %s FOR %s WITH %s", rule.name, rule.vector, strutil.DurationToString(rule.holdDuration), rule.labels) + s := fmt.Sprintf("ALERT %s", rule.name) + s += fmt.Sprintf("\n\tIF %s", rule.vector) + if rule.holdDuration > 0 { + s += fmt.Sprintf("\n\tFOR %s", strutil.DurationToString(rule.holdDuration)) + } + if len(rule.labels) > 0 { + s += fmt.Sprintf("\n\tWITH %s", rule.labels) + } + s += fmt.Sprintf("\n\tSUMMARY %q", rule.summary) + s += fmt.Sprintf("\n\tDESCRIPTION %q", rule.description) + return s } -// HTMLSnippet returns an HTML snippet representing this alerting rule. +// HTMLSnippet returns an HTML snippet representing this alerting rule. The +// resulting snippet is expected to be presented in a
element, so that +// line breaks and other returned whitespace is respected. func (rule *AlertingRule) HTMLSnippet(pathPrefix string) template.HTML { alertMetric := clientmodel.Metric{ clientmodel.MetricNameLabel: alertMetricName, alertNameLabel: clientmodel.LabelValue(rule.name), } - return template.HTML(fmt.Sprintf( - `ALERT %s IF %s FOR %s WITH %s`, - pathPrefix+strutil.GraphLinkForExpression(alertMetric.String()), - rule.name, - pathPrefix+strutil.GraphLinkForExpression(rule.vector.String()), - rule.vector, - strutil.DurationToString(rule.holdDuration), - rule.labels)) + s := fmt.Sprintf("ALERT %s", pathPrefix+strutil.GraphLinkForExpression(alertMetric.String()), rule.name) + s += fmt.Sprintf("\n IF %s", pathPrefix+strutil.GraphLinkForExpression(rule.vector.String()), rule.vector) + if rule.holdDuration > 0 { + s += fmt.Sprintf("\n FOR %s", strutil.DurationToString(rule.holdDuration)) + } + if len(rule.labels) > 0 { + s += fmt.Sprintf("\n WITH %s", rule.labels) + } + s += fmt.Sprintf("\n SUMMARY %q", rule.summary) + s += fmt.Sprintf("\n DESCRIPTION %q", rule.description) + return template.HTML(s) } // State returns the "maximum" state: firing > pending > inactive. diff --git a/template/template.go b/template/template.go index e7060cc4e9..7b7cdd2670 100644 --- a/template/template.go +++ b/template/template.go @@ -238,6 +238,13 @@ func NewTemplateExpander(text string, name string, data interface{}, timestamp c } return fmt.Sprintf("%.4g%ss", v, prefix) }, + "humanizeTimestamp": func(v float64) string { + if math.IsNaN(v) || math.IsInf(v, 0) { + return fmt.Sprintf("%.4g", v) + } + t := clientmodel.TimestampFromUnixNano(int64(v * 1000000000)).Time() + return fmt.Sprint(t) + }, "pathPrefix": func() string { return pathPrefix }, @@ -245,6 +252,14 @@ func NewTemplateExpander(text string, name string, data interface{}, timestamp c } } +// Funcs adds the functions in fm to the templateExpander's function map. +// Existing functions will be overwritten in case of conflict. +func (te templateExpander) Funcs(fm text_template.FuncMap) { + for k, v := range fm { + te.funcMap[k] = v + } +} + // Expand a template. func (te templateExpander) Expand() (result string, resultErr error) { // It'd better to have no alert description than to kill the whole process diff --git a/template/template_test.go b/template/template_test.go index b7e1b54c05..b3a92bc531 100644 --- a/template/template_test.go +++ b/template/template_test.go @@ -135,9 +135,14 @@ func TestTemplateExpansion(t *testing.T) { }, { // Humanize* Inf and NaN. - text: "{{ range . }}{{ humanize . }}:{{ humanize1024 . }}:{{ humanizeDuration . }}:{{ end }}", + text: "{{ range . }}{{ humanize . }}:{{ humanize1024 . }}:{{ humanizeDuration . }}:{{humanizeTimestamp .}}:{{ end }}", input: []float64{math.Inf(1), math.Inf(-1), math.NaN()}, - output: "+Inf:+Inf:+Inf:-Inf:-Inf:-Inf:NaN:NaN:NaN:", + output: "+Inf:+Inf:+Inf:+Inf:-Inf:-Inf:-Inf:-Inf:NaN:NaN:NaN:NaN:", + }, + { + // HumanizeTimestamp - clientmodel.SampleValue input. + text: "{{ 1435065584.128 | humanizeTimestamp }}", + output: "2015-06-23 15:19:44.128 +0200 CEST", }, { // Title. diff --git a/web/blob/static/css/alerts.css b/web/blob/static/css/alerts.css index f7061c4d8a..798fc36912 100644 --- a/web/blob/static/css/alerts.css +++ b/web/blob/static/css/alerts.css @@ -5,19 +5,3 @@ .alert_details { display: none; } - -.silence_children_link { - margin-left: 5px; -} - -.alert_rule { - padding: 5px; - color: #333; - background-color: #ddd; - font-family: monospace; - font-weight: normal; -} - -.alert_description { - padding: 8px 0 8px 0; -} diff --git a/web/blob/static/css/prometheus.css b/web/blob/static/css/prometheus.css index 623fd743cd..c44c65ec17 100644 --- a/web/blob/static/css/prometheus.css +++ b/web/blob/static/css/prometheus.css @@ -10,8 +10,9 @@ th.job_header { padding-bottom: 10px; } -.target_status_alert { +.state_indicator { padding: 0 4px 0 4px; + text-transform: uppercase; } .literal_output td { diff --git a/web/blob/templates/alerts.html b/web/blob/templates/alerts.html index fc374e00d5..bc9015ddec 100644 --- a/web/blob/templates/alerts.html +++ b/web/blob/templates/alerts.html @@ -16,9 +16,9 @@- - {{.HTMLSnippet pathPrefix}} - Silence All Children… ++{{if $activeAlerts}}+ Silence all instances of this alert…{{.HTMLSnippet pathPrefix}}
@@ -30,12 +30,16 @@
diff --git a/web/blob/templates/status.html b/web/blob/templates/status.html index becba8f6cf..69678a32d4 100644 --- a/web/blob/templates/status.html +++ b/web/blob/templates/status.html @@ -55,7 +55,7 @@ {{end}}Silence {{range $activeAlerts}} -- {{.Labels}} -{{.State}} -{{.ActiveSince}} ++ {{end}}+ {{range $label, $value := .Labels}} + {{$label}}="{{$value}}" + {{end}} + +{{.State}} +{{.ActiveSince.Time}} {{.Value}} -Silence… + Silence… - + {{.Status.Health}}