-
Notifications
You must be signed in to change notification settings - Fork 190
/
gatherer.go
79 lines (72 loc) · 2.1 KB
/
gatherer.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
package apmprometheus
import (
"context"
"strconv"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"go.elastic.co/apm"
)
// Wrap returns an apm.MetricsGatherer wrapping g.
func Wrap(g prometheus.Gatherer) apm.MetricsGatherer {
return gatherer{g}
}
type gatherer struct {
p prometheus.Gatherer
}
// GatherMetrics gathers metrics from the prometheus.Gatherer p.g,
// and adds them to out.
func (g gatherer) GatherMetrics(ctx context.Context, out *apm.Metrics) error {
metricFamilies, err := g.p.Gather()
if err != nil {
return errors.WithStack(err)
}
for _, mf := range metricFamilies {
name := mf.GetName()
switch mf.GetType() {
case dto.MetricType_COUNTER:
for _, m := range mf.GetMetric() {
v := m.GetCounter().GetValue()
out.Add(name, makeLabels(m.GetLabel()), v)
}
case dto.MetricType_GAUGE:
metrics := mf.GetMetric()
if name == "go_info" && len(metrics) == 1 && metrics[0].GetGauge().GetValue() == 1 {
// Ignore the "go_info" metric from the
// built-in GoCollector, as we provide
// the same information in the payload.
continue
}
for _, m := range metrics {
v := m.GetGauge().GetValue()
out.Add(name, makeLabels(m.GetLabel()), v)
}
case dto.MetricType_UNTYPED:
for _, m := range mf.GetMetric() {
v := m.GetUntyped().GetValue()
out.Add(name, makeLabels(m.GetLabel()), v)
}
case dto.MetricType_SUMMARY:
for _, m := range mf.GetMetric() {
s := m.GetSummary()
labels := makeLabels(m.GetLabel())
out.Add(name+".count", labels, float64(s.GetSampleCount()))
out.Add(name+".total", labels, float64(s.GetSampleSum()))
for _, q := range s.GetQuantile() {
p := int(q.GetQuantile() * 100)
out.Add(name+".percentile."+strconv.Itoa(p), labels, q.GetValue())
}
}
default:
// TODO(axw) MetricType_HISTOGRAM
}
}
return nil
}
func makeLabels(lps []*dto.LabelPair) []apm.MetricLabel {
labels := make([]apm.MetricLabel, len(lps))
for i, lp := range lps {
labels[i] = apm.MetricLabel{Name: lp.GetName(), Value: lp.GetValue()}
}
return labels
}