/
graphite_exporter.go
74 lines (65 loc) · 2.11 KB
/
graphite_exporter.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
// Copyright 2018 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package metric
import (
"context"
"fmt"
"os"
"time"
"github.com/ruiaylin/pgparser/utils/log"
"github.com/cockroachdb/errors"
"github.com/prometheus/client_golang/prometheus/graphite"
)
var errNoEndpoint = errors.New("external.graphite.endpoint is not set")
// GraphiteExporter scrapes PrometheusExporter for metrics and pushes
// them to a Graphite or Carbon server.
type GraphiteExporter struct {
pm *PrometheusExporter
}
// MakeGraphiteExporter returns an initialized graphite exporter.
func MakeGraphiteExporter(pm *PrometheusExporter) GraphiteExporter {
return GraphiteExporter{pm: pm}
}
type loggerFunc func(...interface{})
// Println implements graphite.Logger.
func (lf loggerFunc) Println(v ...interface{}) {
lf(v...)
}
// Push metrics scraped from registry to Graphite or Carbon server.
// It converts the same metrics that are pulled by Prometheus into Graphite-format.
func (ge *GraphiteExporter) Push(ctx context.Context, endpoint string) error {
if endpoint == "" {
return errNoEndpoint
}
h, err := os.Hostname()
if err != nil {
return err
}
// Make the bridge.
var b *graphite.Bridge
if b, err = graphite.NewBridge(&graphite.Config{
URL: endpoint,
Gatherer: ge.pm,
Prefix: fmt.Sprintf("%s.cockroach", h),
Timeout: 10 * time.Second,
ErrorHandling: graphite.AbortOnError,
Logger: loggerFunc(func(args ...interface{}) {
log.InfofDepth(ctx, 1, "", args...)
}),
}); err != nil {
return err
}
// Regardless of whether Push() errors, clear metrics. Only latest metrics
// are pushed. If there is an error, this will cause a gap in receiver. The
// receiver associates timestamp with when metric arrived, so storing missed
// metrics has no benefit.
defer ge.pm.clearMetrics()
return b.Push()
}