-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
debug.go
124 lines (110 loc) · 3.7 KB
/
debug.go
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
115
116
117
118
119
120
121
122
123
124
package promrelabel
import (
"fmt"
"io"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
)
// WriteMetricRelabelDebug writes /metric-relabel-debug page to w with the corresponding args.
func WriteMetricRelabelDebug(w io.Writer, targetID, metric, relabelConfigs, format string, err error) {
writeRelabelDebug(w, false, targetID, metric, relabelConfigs, format, err)
}
// WriteTargetRelabelDebug writes /target-relabel-debug page to w with the corresponding args.
func WriteTargetRelabelDebug(w io.Writer, targetID, metric, relabelConfigs, format string, err error) {
writeRelabelDebug(w, true, targetID, metric, relabelConfigs, format, err)
}
func writeRelabelDebug(w io.Writer, isTargetRelabel bool, targetID, metric, relabelConfigs, format string, err error) {
if metric == "" {
metric = "{}"
}
targetURL := ""
if err != nil {
WriteRelabelDebugSteps(w, targetURL, targetID, format, nil, metric, relabelConfigs, err)
return
}
labels, err := promutils.NewLabelsFromString(metric)
if err != nil {
err = fmt.Errorf("cannot parse metric: %w", err)
WriteRelabelDebugSteps(w, targetURL, targetID, format, nil, metric, relabelConfigs, err)
return
}
pcs, err := ParseRelabelConfigsData([]byte(relabelConfigs))
if err != nil {
err = fmt.Errorf("cannot parse relabel configs: %w", err)
WriteRelabelDebugSteps(w, targetURL, targetID, format, nil, metric, relabelConfigs, err)
return
}
dss, targetURL := newDebugRelabelSteps(pcs, labels, isTargetRelabel)
WriteRelabelDebugSteps(w, targetURL, targetID, format, dss, metric, relabelConfigs, nil)
}
func newDebugRelabelSteps(pcs *ParsedConfigs, labels *promutils.Labels, isTargetRelabel bool) ([]DebugStep, string) {
// The target relabeling below must be in sync with the code at scrapeWorkConfig.getScrapeWork if isTargetRelabel=true
// and with the code at scrapeWork.addRowToTimeseries when isTargetRelabeling=false
targetURL := ""
// Prevent from modifying the original labels
labels = labels.Clone()
// Apply relabeling
labelsResult, dss := pcs.ApplyDebug(labels.GetLabels())
labels.Labels = labelsResult
outStr := LabelsToString(labels.GetLabels())
if isTargetRelabel {
// Add missing instance label
if labels.Get("instance") == "" {
address := labels.Get("__address__")
if address != "" {
inStr := outStr
labels.Add("instance", address)
outStr = LabelsToString(labels.GetLabels())
dss = append(dss, DebugStep{
Rule: "add missing instance label from __address__ label",
In: inStr,
Out: outStr,
})
}
}
// Generate targetURL
targetURL, _ = GetScrapeURL(labels, nil)
// Remove labels with __ prefix
inStr := outStr
labels.RemoveLabelsWithDoubleUnderscorePrefix()
outStr = LabelsToString(labels.GetLabels())
if inStr != outStr {
dss = append(dss, DebugStep{
Rule: "remove labels with __ prefix",
In: inStr,
Out: outStr,
})
}
} else {
// Remove labels with __ prefix except of __name__
inStr := outStr
labels.Labels = FinalizeLabels(labels.Labels[:0], labels.Labels)
outStr = LabelsToString(labels.GetLabels())
if inStr != outStr {
dss = append(dss, DebugStep{
Rule: "remove labels with __ prefix except of __name__",
In: inStr,
Out: outStr,
})
}
}
// There is no need in labels' sorting, since LabelsToString() automatically sorts labels.
return dss, targetURL
}
func getChangedLabelNames(in, out *promutils.Labels) map[string]struct{} {
inMap := in.ToMap()
outMap := out.ToMap()
changed := make(map[string]struct{})
for k, v := range outMap {
inV, ok := inMap[k]
if !ok || inV != v {
changed[k] = struct{}{}
}
}
for k, v := range inMap {
outV, ok := outMap[k]
if !ok || outV != v {
changed[k] = struct{}{}
}
}
return changed
}