-
Notifications
You must be signed in to change notification settings - Fork 619
/
circonus.go
128 lines (100 loc) · 3.2 KB
/
circonus.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
125
126
127
128
package metrics
import (
"errors"
"fmt"
"log"
"os"
"sync"
"time"
cgm "github.com/circonus-labs/circonus-gometrics"
"github.com/fabiolb/fabio/config"
)
var (
circonus *cgmRegistry
once sync.Once
)
const serviceName = "fabio"
// circonusRegistry returns a provider that reports to Circonus.
func circonusRegistry(prefix string, circ config.Circonus, interval time.Duration) (Registry, error) {
var initError error
once.Do(func() {
if circ.APIKey == "" {
initError = errors.New("metrics: Circonus API token key")
return
}
if circ.APIApp == "" {
circ.APIApp = serviceName
}
host, err := os.Hostname()
if err != nil {
initError = fmt.Errorf("metrics: unable to initialize Circonus %s", err)
return
}
cfg := &cgm.Config{}
cfg.CheckManager.API.TokenKey = circ.APIKey
cfg.CheckManager.API.TokenApp = circ.APIApp
cfg.CheckManager.API.URL = circ.APIURL
cfg.CheckManager.Check.ID = circ.CheckID
cfg.CheckManager.Broker.ID = circ.BrokerID
cfg.Interval = fmt.Sprintf("%.0fs", interval.Seconds())
cfg.CheckManager.Check.InstanceID = host
cfg.CheckManager.Check.DisplayName = fmt.Sprintf("%s /%s", host, serviceName)
cfg.CheckManager.Check.SearchTag = fmt.Sprintf("service:%s", serviceName)
metrics, err := cgm.NewCirconusMetrics(cfg)
if err != nil {
initError = fmt.Errorf("metrics: unable to initialize Circonus %s", err)
return
}
circonus = &cgmRegistry{metrics, prefix}
metrics.Start()
log.Print("[INFO] Sending metrics to Circonus")
})
return circonus, initError
}
type cgmRegistry struct {
metrics *cgm.CirconusMetrics
prefix string
}
// Names is not supported by Circonus.
func (m *cgmRegistry) Names() []string { return nil }
// Unregister is implicitly supported by Circonus,
// stop submitting the metric and it stops being sent to Circonus.
func (m *cgmRegistry) Unregister(name string) {}
// UnregisterAll is implicitly supported by Circonus,
// stop submitting metrics and they will no longer be sent to Circonus.
func (m *cgmRegistry) UnregisterAll() {}
// GetCounter returns a counter for the given metric name.
func (m *cgmRegistry) GetCounter(name string) Counter {
metricName := fmt.Sprintf("%s`%s", m.prefix, name)
return &cgmCounter{m.metrics, metricName}
}
// GetTimer returns a timer for the given metric name.
func (m *cgmRegistry) GetTimer(name string) Timer {
metricName := fmt.Sprintf("%s`%s", m.prefix, name)
return &cgmTimer{m.metrics, metricName}
}
type cgmCounter struct {
metrics *cgm.CirconusMetrics
name string
}
// Inc increases the counter by n.
func (c *cgmCounter) Inc(n int64) {
c.metrics.IncrementByValue(c.name, uint64(n))
}
type cgmTimer struct {
metrics *cgm.CirconusMetrics
name string
}
// Percentile is not supported by Circonus.
func (t *cgmTimer) Percentile(nth float64) float64 { return 0 }
// Rate1 is not supported by Circonus.
func (t *cgmTimer) Rate1() float64 { return 0 }
func (t *cgmTimer) Update(d time.Duration) {
t.metrics.Timing(t.name, float64(d))
}
// UpdateSince adds delta between start and current time as
// a sample to a histogram. The histogram is created if it
// does not already exist.
func (t *cgmTimer) UpdateSince(start time.Time) {
t.metrics.Timing(t.name, float64(time.Since(start)))
}