-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetric.go
114 lines (103 loc) · 2.62 KB
/
metric.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
package prommerge
import (
"bufio"
"fmt"
log "github.com/sirupsen/logrus"
"log/slog"
"os"
"strconv"
"strings"
)
type PromMetric struct {
Name string
LabelList []string
Output string
Value float64
Help string
Type string
sort string
}
func (pd *PromData) ParseMetricData(in string, extraLabels []string) []*PromMetric {
var metrics []*PromMetric
helpMap := make(map[string]string)
typeMap := make(map[string]string)
scanner := bufio.NewScanner(strings.NewReader(in))
for scanner.Scan() {
line := scanner.Text()
if len(line) > 6 && line[0:6] == "# HELP" {
if pd.OmitMeta {
continue
}
//log.Debugf("Metadata help %v", line)
matches := helpRe.FindStringSubmatch(line)
if matches == nil || len(matches) < 2 {
log.Warnf("No matches found for the help input %v", line)
}
helpMap[matches[1]] = matches[0]
continue
}
if len(line) > 6 && line[0:6] == "# TYPE" {
if pd.OmitMeta {
continue
}
//log.Debugf("Metadata type %v", line)
matches := typeRe.FindStringSubmatch(line)
if matches == nil || len(matches) < 2 {
log.Warnf("No matches found for the type input %v", line)
}
typeMap[matches[1]] = matches[0]
continue
}
p, err := pd.MetricParser(line, extraLabels)
if err != nil {
slog.Error(err.Error())
return nil
}
p.Help = helpMap[p.Name]
p.Type = typeMap[p.Name]
metrics = append(metrics, p)
//log.Debugf("Metric: %+v", p)
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading input:", err)
}
return metrics
}
func (pd *PromData) MetricParser(input string, extraLabels []string) (*PromMetric, error) {
p := new(PromMetric)
matches := metricRe.FindStringSubmatch(input)
if matches == nil {
return nil, fmt.Errorf("no matches found for the input %v", input)
}
//log.Debugf("Metric Name: %v", matches[1])
p.Name = matches[1]
//log.Debugf("Labels: %v", matches[2])
labelPairs := strings.Split(matches[2], ",")
for _, labelPair := range extraLabels {
kv := strings.Split(labelPair, "=")
if len(kv) == 2 {
p.LabelList = append(p.LabelList, kv[0], strings.ReplaceAll(kv[1], `"`, ""))
}
}
// Parse labels
for i, _ := range labelPairs {
m := labelRe.FindStringSubmatch(labelPairs[i])
if m == nil {
log.Debugf("Metric %v has no labels", p.Name)
continue
}
if len(m) > 2 {
p.LabelList = append(p.LabelList, m[1], m[2])
}
}
value, err := strconv.ParseFloat(matches[3], 64)
if err != nil {
return nil, fmt.Errorf("error parsing float, %v", err)
}
//log.Debugf("Value: %v", value)
p.Value = value
if pd.Sort {
p.sort = fmt.Sprintf("%v%v", p.Name, p.LabelList)
}
return p, nil
}