forked from marpaia/graphite-golang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraphite.go
168 lines (145 loc) · 4.65 KB
/
graphite.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package graphite
import (
"bytes"
"fmt"
"log"
"net"
"time"
)
// Graphite is a struct that defines the relevant properties of a graphite
// connection
type Graphite struct {
Address string
Timeout time.Duration
Prefix string
conn net.Conn
nop bool
}
// defaultTimeout is the default number of seconds that we're willing to wait
// before forcing the connection establishment to fail
const defaultTimeout = 5
// IsNop is a getter for *graphite.Graphite.nop
func (graphite *Graphite) IsNop() bool {
if graphite.nop {
return true
}
return false
}
// Given a Graphite struct, Connect populates the Graphite.conn field with an
// appropriate TCP connection
func (graphite *Graphite) Connect() error {
if !graphite.IsNop() {
if graphite.conn != nil {
graphite.conn.Close()
}
if graphite.Timeout == 0 {
graphite.Timeout = defaultTimeout * time.Second
}
conn, err := net.DialTimeout("tcp", graphite.Address, graphite.Timeout)
if err != nil {
return err
}
graphite.conn = conn
}
return nil
}
// Given a Graphite struct, Disconnect closes the Graphite.conn field
func (graphite *Graphite) Disconnect() error {
err := graphite.conn.Close()
graphite.conn = nil
return err
}
// Given a Metric struct, the SendMetric method sends the supplied metric to the
// Graphite connection that the method is called upon
func (graphite *Graphite) SendMetric(metric Metric) error {
metrics := make([]Metric, 1)
metrics[0] = metric
return graphite.sendMetrics(metrics)
}
// Given a slice of Metrics, the SendMetrics method sends the metrics, as a
// batch, to the Graphite connection that the method is called upon
func (graphite *Graphite) SendMetrics(metrics []Metric) error {
return graphite.sendMetrics(metrics)
}
// sendMetrics is an internal function that is used to write to the TCP
// connection in order to communicate metrics to the remote Graphite host
func (graphite *Graphite) sendMetrics(metrics []Metric) error {
zeroed_metric := Metric{} // ignore unintialized metrics
if !graphite.IsNop() {
buf := bytes.NewBufferString("")
for _, metric := range metrics {
if metric == zeroed_metric {
continue // ignore unintialized metrics
}
if metric.Timestamp == 0 {
metric.Timestamp = time.Now().Unix()
}
metric_name := ""
if graphite.Prefix != "" {
metric_name = fmt.Sprintf("%s.%s", graphite.Prefix, metric.Name)
} else {
metric_name = metric.Name
}
buf.WriteString(fmt.Sprintf("%s %s %d\n", metric_name, metric.Value, metric.Timestamp))
}
_, err := graphite.conn.Write(buf.Bytes())
//fmt.Print("Sent msg:", buf.String(), "'")
if err != nil {
return err
}
} else {
for _, metric := range metrics {
log.Printf("Graphite: %s\n", metric)
}
}
return nil
}
// The SimpleSend method can be used to just pass a metric name and value and
// have it be sent to the Graphite host with the current timestamp
func (graphite *Graphite) SimpleSend(stat string, value string) error {
metrics := make([]Metric, 1)
metrics[0] = NewMetric(stat, value, time.Now().Unix())
err := graphite.sendMetrics(metrics)
if err != nil {
return err
}
return nil
}
// NewGraphiteHost is a factory method that's used to create a new Graphite
// connection given a hostname and a port number
func NewGraphite(host string, port int) (*Graphite, error) {
address := fmt.Sprintf("%s:%d", host, port)
Graphite := &Graphite{Address: address}
err := Graphite.Connect()
if err != nil {
return nil, err
}
return Graphite, nil
}
// NewGraphiteHost is a factory method that's used to create a new Graphite
// connection given an address string understood by net.Dial
func NewGraphiteFromAddress(address string) (*Graphite, error) {
Graphite := &Graphite{Address: address}
err := Graphite.Connect()
if err != nil {
return nil, err
}
return Graphite, nil
}
// NewGraphiteNop is a factory method that returns a Graphite struct but will
// not actually try to send any packets to a remote host and, instead, will just
// log. This is useful if you want to use Graphite in a project but don't want
// to make Graphite a requirement for the project.
func NewGraphiteNop(host string, port int) *Graphite {
address := fmt.Sprintf("%s:%d", host, port)
graphiteNop := &Graphite{Address: address, nop: true}
return graphiteNop
}
// NewGraphiteNop is a factory method that returns a Graphite struct but will
// not actually try to send any packets to a remote host and, instead, will just
// log. This is useful if you want to use Graphite in a project but don't want
// to make Graphite a requirement for the project.
func NewGraphiteNopFromAdress(address string) *Graphite {
graphiteNop := &Graphite{Address: address, nop: true}
return graphiteNop
}