Prometheus源码-Relabel

基于3.5

relabel address流程

  1. Prometheus读取Job中的targets,把target赋值给__address__标签,此标签代表采集地址
  2. __address__赋值给__param_target标签,因为Promehrues访问采集地址需要传参,__param_target代表target参数
  3. __param_target标签赋值给instance标签
  4. __param_target替换为真实的采集地址

核心解析

Label Re

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// PopulateDiscoveredLabels sets base labels on lb from target and group labels and scrape configuration, before relabeling.
// PopulateDiscoveredLabels 在重新标记之前,从目标和组标签以及抓取配置在 lb 上设置基础标签
func PopulateDiscoveredLabels(lb *labels.Builder, cfg *config.ScrapeConfig, tLabels, tgLabels model.LabelSet) {
lb.Reset(labels.EmptyLabels())

for ln, lv := range tLabels {
lb.Set(string(ln), string(lv))
}
for ln, lv := range tgLabels {
if _, ok := tLabels[ln]; !ok {
lb.Set(string(ln), string(lv))
}
}

// Copy labels into the labelset for the target if they are not set already.
// 如果尚未设置,则将标签复制到目标的标签集中
scrapeLabels := []labels.Label{
{Name: model.JobLabel, Value: cfg.JobName},
{Name: model.ScrapeIntervalLabel, Value: cfg.ScrapeInterval.String()},
{Name: model.ScrapeTimeoutLabel, Value: cfg.ScrapeTimeout.String()},
{Name: model.MetricsPathLabel, Value: cfg.MetricsPath},
{Name: model.SchemeLabel, Value: cfg.Scheme},
}

for _, l := range scrapeLabels {
if lb.Get(l.Name) == "" {
lb.Set(l.Name, l.Value)
}
}
// Encode scrape query parameters as labels.
// 将抓取查询参数编码为标签
for k, v := range cfg.Params {
if name := model.ParamLabelPrefix + k; len(v) > 0 && lb.Get(name) == "" {
lb.Set(name, v[0])
}
}
}

// PopulateLabels builds labels from target and group labels and scrape configuration,
// performs defined relabeling, checks validity, and adds Prometheus standard labels such as 'instance'.
// A return of empty labels and nil error means the target was dropped by relabeling.
// PopulateLabels 从目标和组标签以及抓取配置构建标签,
// 执行定义的重新标记,检查有效性,并添加 Prometheus 标准标签如 'instance'。
// 返回空标签和 nil 错误意味着目标被重新标记丢弃。
func PopulateLabels(lb *labels.Builder, cfg *config.ScrapeConfig, tLabels, tgLabels model.LabelSet) (res labels.Labels, err error) {
PopulateDiscoveredLabels(lb, cfg, tLabels, tgLabels)
keep := relabel.ProcessBuilder(lb, cfg.RelabelConfigs...)

// Check if the target was dropped.
// 检查目标是否被丢弃
if !keep {
return labels.EmptyLabels(), nil
}
if v := lb.Get(model.AddressLabel); v == "" {
return labels.EmptyLabels(), errors.New("no address")
}

addr := lb.Get(model.AddressLabel)

if err := config.CheckTargetAddress(model.LabelValue(addr)); err != nil {
return labels.EmptyLabels(), err
}

interval := lb.Get(model.ScrapeIntervalLabel)
intervalDuration, err := model.ParseDuration(interval)
if err != nil {
return labels.EmptyLabels(), fmt.Errorf("error parsing scrape interval: %w", err)
}
if time.Duration(intervalDuration) == 0 {
return labels.EmptyLabels(), errors.New("scrape interval cannot be 0")
}

timeout := lb.Get(model.ScrapeTimeoutLabel)
timeoutDuration, err := model.ParseDuration(timeout)
if err != nil {
return labels.EmptyLabels(), fmt.Errorf("error parsing scrape timeout: %w", err)
}
if time.Duration(timeoutDuration) == 0 {
return labels.EmptyLabels(), errors.New("scrape timeout cannot be 0")
}

if timeoutDuration > intervalDuration {
return labels.EmptyLabels(), fmt.Errorf("scrape timeout cannot be greater than scrape interval (%q > %q)", timeout, interval)
}

// Meta labels are deleted after relabelling. Other internal labels propagate to
// the target which decides whether they will be part of their label set.
// 元标签在重新标记后被删除。其他内部标签传播到目标,由目标决定它们是否成为其标签集的一部分
lb.Range(func(l labels.Label) {
if strings.HasPrefix(l.Name, model.MetaLabelPrefix) {
lb.Del(l.Name)
}
})

// Default the instance label to the target address.
// 默认 instance 标签为目标地址
if v := lb.Get(model.InstanceLabel); v == "" {
lb.Set(model.InstanceLabel, addr)
}

res = lb.Labels()
err = res.Validate(func(l labels.Label) error {
// Check label values are valid, drop the target if not.
// 检查标签值是否有效,如果不有效则丢弃目标
if !model.LabelValue(l.Value).IsValid() {
return fmt.Errorf("invalid label value for %q: %q", l.Name, l.Value)
}
return nil
})
if err != nil {
return labels.EmptyLabels(), err
}
return res, nil
}