-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathredis.go
110 lines (101 loc) · 3.61 KB
/
redis.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
package main
import (
"net"
"regexp"
"strings"
)
const REDIS = "redis"
func init() {
parser.Add(REDIS, "127.0.0.1:6379", "Collect redis metrics")
}
type Redis struct {
Address string
Raw []byte
}
func (self *Redis) Prefix() string {
return "redis"
}
func (self *Redis) Collect(c *MetricsCollection) (e error) {
logger.Printf("collecting redis")
b, e := self.ReadInfo()
if e != nil {
logger.Printf("ERROR reading info: %q", e.Error())
return
}
str := string(b)
values := map[string]string{}
dbRegexp := regexp.MustCompile("^db(\\d+):keys=(\\d+),expires=(\\d+)")
pid := values["process_id"]
tcp_port := values["tcp_port"]
for _, line := range strings.Split(str, "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "#") || len(line) < 2 {
continue
}
res := dbRegexp.FindStringSubmatch(line)
if len(res) == 4 {
dbTags := map[string]string{
"db": res[1],
"pid": pid,
"port": tcp_port,
}
c.AddWithTags("db.Keys", parseInt64(res[2]), dbTags)
c.AddWithTags("db.Expires", parseInt64(res[3]), dbTags)
continue
}
chunks := strings.Split(line, ":")
if len(chunks) > 1 {
values[chunks[0]] = strings.Join(chunks[1:], ":")
}
}
tags := map[string]string{
"pid": pid,
"port": tcp_port,
}
c.AddWithTags("UptimeInSeconds", parseInt64(values["uptime_in_seconds"]), tags)
c.AddWithTags("memory.UsedMemory", parseInt64(values["used_memory"]), tags)
c.AddWithTags("memory.UsedMemoryRSS", parseInt64(values["used_memory_rss"]), tags)
c.AddWithTags("memory.UsedMemoryPeak", parseInt64(values["used_memory_peak"]), tags)
c.AddWithTags("memory.UsedMemoryLua", parseInt64(values["used_memory_lua"]), tags)
c.AddWithTags("clients.ConnectedClients", parseInt64(values["connected_clients"]), tags)
c.AddWithTags("clients.ClientLongestOutputList", parseInt64(values["client_longest_output_list"]), tags)
c.AddWithTags("clients.ClientBiggestInputBuf", parseInt64(values["client_biggest_input_buf"]), tags)
c.AddWithTags("clients.BlockedClients", parseInt64(values["blocked_clients"]), tags)
c.AddWithTags("stats.TotalConnectionsReceived", parseInt64(values["total_connections_received"]), tags)
c.AddWithTags("stats.TotalCommandsProcessed", parseInt64(values["total_commands_processed"]), tags)
c.AddWithTags("stats.InstantaneousOpsPerSec", parseInt64(values["instantaneous_ops_per_sec"]), tags)
c.AddWithTags("stats.RejectedConnections", parseInt64(values["rejected_connections"]), tags)
c.AddWithTags("stats.ExpiredKeys", parseInt64(values["expired_keys"]), tags)
c.AddWithTags("stats.EvictedKeys", parseInt64(values["evicted_keys"]), tags)
c.AddWithTags("stats.KeyspaceHits", parseInt64(values["keyspace_hits"]), tags)
c.AddWithTags("stats.KeyspaceMisses", parseInt64(values["keyspace_misses"]), tags)
c.AddWithTags("stats.PubsubChannels", parseInt64(values["pubsub_channels"]), tags)
c.AddWithTags("stats.PubsubPatterns", parseInt64(values["pubsub_patterns"]), tags)
c.AddWithTags("stats.LatestForkUsec", parseInt64(values["latest_fork_usec"]), tags)
c.AddWithTags("replication.ConnectedSlaves", parseInt64(values["connected_slaves"]), tags)
return
}
func (self *Redis) ReadInfo() (b []byte, e error) {
if len(self.Raw) == 0 {
var con net.Conn
logger.Printf("connecting %s", self.Address)
con, e = net.Dial("tcp", self.Address)
if e != nil {
logger.Printf("ERROR connecting %s: %q", self.Address, e.Error())
return
}
defer con.Close()
con.Write([]byte("INFO\r\n"))
b = make([]byte, 4096)
var i int
i, e = con.Read(b)
dbg.Printf("read %d bytes", i)
if e != nil {
logger.Printf("ERROR reading: %q", e.Error())
return
}
self.Raw = b
}
b = self.Raw
return
}