-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathexport.go
133 lines (116 loc) · 3.67 KB
/
export.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
129
130
131
132
133
package goHystrix
import (
"fmt"
"github.com/dahernan/goHystrix/statsd"
"log"
"time"
)
var (
metricsExporter MetricExport
)
func init() {
metricsExporter = NewNilExport()
}
func Exporter() MetricExport {
return metricsExporter
}
func SetExporter(export MetricExport) {
metricsExporter = export
}
type MetricExport interface {
Success(group string, name string, duration time.Duration)
Fail(group string, name string)
Fallback(group string, name string)
FallbackError(group string, name string)
Timeout(group string, name string)
Panic(group string, name string)
State(circuits *CircuitHolder)
}
type StatsdExport struct {
statsdClient statsd.Statter
prefix string
}
type NilExport struct {
}
func UseStatsd(address string, prefix string, dur time.Duration) {
statsdClient, err := statsd.Dial("udp", address)
if err != nil {
log.Println("Error setting Statds for publishing the metrics: ", err)
log.Println("Using NilExport for publishing the metrics")
SetExporter(NilExport{})
return
}
export := NewStatsdExport(statsdClient, prefix)
SetExporter(export)
statsdExport := export.(StatsdExport)
// poll the state of the circuits
go statsdExport.run(Circuits(), dur)
}
func NewNilExport() MetricExport { return NilExport{} }
func (NilExport) Success(group string, name string, duration time.Duration) {}
func (NilExport) Fail(group string, name string) {}
func (NilExport) Fallback(group string, name string) {}
func (NilExport) FallbackError(group string, name string) {}
func (NilExport) Timeout(group string, name string) {}
func (NilExport) Panic(group string, name string) {}
func (NilExport) State(circuits *CircuitHolder) {}
func NewStatsdExport(statsdClient statsd.Statter, prefix string) MetricExport {
return StatsdExport{statsdClient, prefix}
}
func (s StatsdExport) Success(group string, name string, duration time.Duration) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.success", s.prefix, group, name), 1)
//ms := int64(duration / time.Millisecond)
s.statsdClient.Timing(1.0, fmt.Sprintf("%s.%s.%s.duration", s.prefix, group, name), duration)
}()
}
func (s StatsdExport) Fail(group string, name string) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.fail", s.prefix, group, name), 1)
}()
}
func (s StatsdExport) Fallback(group string, name string) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.fallback", s.prefix, group, name), 1)
}()
}
func (s StatsdExport) FallbackError(group string, name string) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.fallbackError", s.prefix, group, name), 1)
}()
}
func (s StatsdExport) Timeout(group string, name string) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.timeout", s.prefix, group, name), 1)
}()
}
func (s StatsdExport) Panic(group string, name string) {
go func() {
s.statsdClient.Counter(1.0, fmt.Sprintf("%s.%s.%s.panic", s.prefix, group, name), 1)
}()
}
func (s StatsdExport) State(holder *CircuitHolder) {
// TODO: have a save way to iterate over the circuits without
// knowing how is implemented
holder.mutex.RLock()
defer holder.mutex.RUnlock()
for group, names := range holder.circuits {
for name, circuit := range names {
var state string
open, _ := circuit.IsOpen()
state = "0"
if open {
state = "1"
}
s.statsdClient.Gauge(1.0, fmt.Sprintf("%s.%s.%s.open", s.prefix, group, name), state)
}
}
}
func (s StatsdExport) run(holder *CircuitHolder, dur time.Duration) {
for {
select {
case <-time.After(dur):
s.State(holder)
}
}
}