mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 05:04:05 -08:00
Add external labels to template expansion
This affects the expansion of templates in alert labels and annotations and console templates. Signed-off-by: Sylvain Rabot <sylvain@abstraction.fr>
This commit is contained in:
parent
1d4c9efe63
commit
335a34486e
|
@ -748,6 +748,12 @@ func reloadConfig(filename string, logger log.Logger, rls ...func(*config.Config
|
|||
return errors.Errorf("one or more errors occurred while applying the new configuration (--config.file=%q)", filename)
|
||||
}
|
||||
promql.SetDefaultEvaluationInterval(time.Duration(conf.GlobalConfig.EvaluationInterval))
|
||||
|
||||
// Register conf as current config.
|
||||
config.CurrentConfigMutex.Lock()
|
||||
config.CurrentConfig = conf
|
||||
config.CurrentConfigMutex.Unlock()
|
||||
|
||||
level.Info(logger).Log("msg", "Completed loading of configuration file", "filename", filename)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -68,6 +69,10 @@ func LoadFile(filename string) (*Config, error) {
|
|||
|
||||
// The defaults applied before parsing the respective config sections.
|
||||
var (
|
||||
// CurrentConfig is a pointer to the current configuration.
|
||||
CurrentConfig *Config
|
||||
CurrentConfigMutex sync.RWMutex
|
||||
|
||||
// DefaultConfig is the default top-level configuration.
|
||||
DefaultConfig = Config{
|
||||
GlobalConfig: DefaultGlobalConfig,
|
||||
|
|
|
@ -43,7 +43,7 @@ The `annotations` clause specifies a set of informational labels that can be use
|
|||
#### Templating
|
||||
|
||||
Label and annotation values can be templated using [console templates](https://prometheus.io/docs/visualization/consoles).
|
||||
The `$labels` variable holds the label key/value pairs of an alert instance
|
||||
The `$labels` & `$externalLabels` variables hold the label key/value pairs of an alert instance
|
||||
and `$value` holds the evaluated value of an alert instance.
|
||||
|
||||
# To insert a firing element's label values:
|
||||
|
|
|
@ -155,7 +155,7 @@ func testTemplateParsing(rl *Rule) (errs []error) {
|
|||
}
|
||||
|
||||
// Trying to parse templates.
|
||||
tmplData := template.AlertTemplateData(make(map[string]string), 0)
|
||||
tmplData := template.AlertTemplateData(make(map[string]string), make(map[string]string), 0)
|
||||
defs := "{{$labels := .Labels}}{{$value := .Value}}"
|
||||
parseTest := func(text string) error {
|
||||
tmpl := template.NewTemplateExpander(
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
|
||||
"github.com/prometheus/prometheus/pkg/labels"
|
||||
"github.com/prometheus/prometheus/pkg/rulefmt"
|
||||
|
@ -79,8 +80,9 @@ func (s AlertState) String() string {
|
|||
type Alert struct {
|
||||
State AlertState
|
||||
|
||||
Labels labels.Labels
|
||||
Annotations labels.Labels
|
||||
Labels labels.Labels
|
||||
ExternalLabels labels.Labels
|
||||
Annotations labels.Labels
|
||||
|
||||
// The value at the last evaluation of the alerting expression.
|
||||
Value float64
|
||||
|
@ -300,15 +302,27 @@ func (r *AlertingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc,
|
|||
var vec promql.Vector
|
||||
for _, smpl := range res {
|
||||
// Provide the alert information to the template.
|
||||
l := make(map[string]string, len(smpl.Metric))
|
||||
l := make(map[string]string)
|
||||
for _, lbl := range smpl.Metric {
|
||||
l[lbl.Name] = lbl.Value
|
||||
}
|
||||
|
||||
tmplData := template.AlertTemplateData(l, smpl.V)
|
||||
// Add external labels.
|
||||
el := make(map[string]string)
|
||||
if config.CurrentConfig != nil {
|
||||
config.CurrentConfigMutex.RLock()
|
||||
for eln, elv := range (*config.CurrentConfig).GlobalConfig.ExternalLabels {
|
||||
el[string(eln)] = string(elv)
|
||||
}
|
||||
config.CurrentConfigMutex.RUnlock()
|
||||
}
|
||||
|
||||
tmplData := template.AlertTemplateData(l, el, smpl.V)
|
||||
// Inject some convenience variables that are easier to remember for users
|
||||
// who are not used to Go's templating system.
|
||||
defs := "{{$labels := .Labels}}{{$value := .Value}}"
|
||||
defs := "{{$labels := .Labels}}"
|
||||
defs += "{{$externalLabels := .ExternalLabels}}"
|
||||
defs += "{{$value := .Value}}"
|
||||
|
||||
expand := func(text string) string {
|
||||
tmpl := template.NewTemplateExpander(
|
||||
|
|
|
@ -28,9 +28,10 @@ import (
|
|||
text_template "text/template"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
"github.com/prometheus/prometheus/util/strutil"
|
||||
)
|
||||
|
@ -133,6 +134,19 @@ func NewTemplateExpander(
|
|||
"label": func(label string, s *sample) string {
|
||||
return s.Labels[label]
|
||||
},
|
||||
"externalLabel": func(label string) string {
|
||||
if config.CurrentConfig == nil {
|
||||
return ""
|
||||
}
|
||||
config.CurrentConfigMutex.RLock()
|
||||
defer config.CurrentConfigMutex.RUnlock()
|
||||
for eln, elv := range (*config.CurrentConfig).GlobalConfig.ExternalLabels {
|
||||
if label == string(eln) {
|
||||
return string(elv)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"value": func(s *sample) float64 {
|
||||
return s.Value
|
||||
},
|
||||
|
@ -261,13 +275,15 @@ func NewTemplateExpander(
|
|||
}
|
||||
|
||||
// AlertTemplateData returns the interface to be used in expanding the template.
|
||||
func AlertTemplateData(labels map[string]string, value float64) interface{} {
|
||||
func AlertTemplateData(labels map[string]string, externalLabels map[string]string, value float64) interface{} {
|
||||
return struct {
|
||||
Labels map[string]string
|
||||
Value float64
|
||||
Labels map[string]string
|
||||
ExternalLabels map[string]string
|
||||
Value float64
|
||||
}{
|
||||
Labels: labels,
|
||||
Value: value,
|
||||
Labels: labels,
|
||||
ExternalLabels: externalLabels,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
34
web/web.go
34
web/web.go
|
@ -541,19 +541,39 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
|||
for k, v := range rawParams {
|
||||
params[k] = v[0]
|
||||
}
|
||||
|
||||
// External labels
|
||||
el := make(map[string]string)
|
||||
if config.CurrentConfig != nil {
|
||||
config.CurrentConfigMutex.RLock()
|
||||
for eln, elv := range (*config.CurrentConfig).GlobalConfig.ExternalLabels {
|
||||
el[string(eln)] = string(elv)
|
||||
}
|
||||
config.CurrentConfigMutex.RUnlock()
|
||||
}
|
||||
|
||||
// Inject some convenience variables that are easier to remember for users
|
||||
// who are not used to Go's templating system.
|
||||
defs := "{{$rawParams := .RawParams }}"
|
||||
defs += "{{$params := .Params}}"
|
||||
defs += "{{$path := .Path}}"
|
||||
defs += "{{$externalLabels := .ExternalLabels}}"
|
||||
|
||||
data := struct {
|
||||
RawParams url.Values
|
||||
Params map[string]string
|
||||
Path string
|
||||
RawParams url.Values
|
||||
Params map[string]string
|
||||
Path string
|
||||
ExternalLabels map[string]string
|
||||
}{
|
||||
RawParams: rawParams,
|
||||
Params: params,
|
||||
Path: strings.TrimLeft(name, "/"),
|
||||
RawParams: rawParams,
|
||||
Params: params,
|
||||
Path: strings.TrimLeft(name, "/"),
|
||||
ExternalLabels: el,
|
||||
}
|
||||
|
||||
tmpl := template.NewTemplateExpander(
|
||||
h.context,
|
||||
string(text),
|
||||
defs+string(text),
|
||||
"__console_"+name,
|
||||
data,
|
||||
h.now(),
|
||||
|
|
Loading…
Reference in a new issue