forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mysql.go
149 lines (123 loc) · 2.45 KB
/
mysql.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
package mysql
import (
"database/sql"
"strconv"
"strings"
_ "github.com/go-sql-driver/mysql"
"github.com/influxdb/telegraf/plugins"
)
type Mysql struct {
Servers []string
}
var sampleConfig = `
# specify servers via a url matching:
# [username[:password]@][protocol[(address)]]/[?tls=[true|false|skip-verify]]
# e.g. root:root@http://10.0.0.18/?tls=false
#
# If no servers are specified, then localhost is used as the host.
servers = ["localhost"]`
func (m *Mysql) SampleConfig() string {
return sampleConfig
}
func (m *Mysql) Description() string {
return "Read metrics from one or many mysql servers"
}
var localhost = ""
func (m *Mysql) Gather(acc plugins.Accumulator) error {
if len(m.Servers) == 0 {
// if we can't get stats in this case, thats fine, don't report
// an error.
m.gatherServer(localhost, acc)
return nil
}
for _, serv := range m.Servers {
err := m.gatherServer(serv, acc)
if err != nil {
return err
}
}
return nil
}
type mapping struct {
onServer string
inExport string
}
var mappings = []*mapping{
{
onServer: "Bytes_",
inExport: "bytes_",
},
{
onServer: "Com_",
inExport: "commands_",
},
{
onServer: "Handler_",
inExport: "handler_",
},
{
onServer: "Innodb_",
inExport: "innodb_",
},
{
onServer: "Tokudb_",
inExport: "tokudb_",
},
{
onServer: "Threads_",
inExport: "threads_",
},
}
func (m *Mysql) gatherServer(serv string, acc plugins.Accumulator) error {
if serv == "localhost" {
serv = ""
}
db, err := sql.Open("mysql", serv)
if err != nil {
return err
}
defer db.Close()
rows, err := db.Query(`SHOW /*!50002 GLOBAL */ STATUS`)
if err != nil {
return err
}
for rows.Next() {
var name string
var val interface{}
err = rows.Scan(&name, &val)
if err != nil {
return err
}
var found bool
for _, mapped := range mappings {
if strings.HasPrefix(name, mapped.onServer) {
i, _ := strconv.Atoi(string(val.([]byte)))
acc.Add(mapped.inExport+name[len(mapped.onServer):], i, nil)
found = true
}
}
if found {
continue
}
switch name {
case "Queries":
i, err := strconv.ParseInt(string(val.([]byte)), 10, 64)
if err != nil {
return err
}
acc.Add("queries", i, nil)
case "Slow_queries":
i, err := strconv.ParseInt(string(val.([]byte)), 10, 64)
if err != nil {
return err
}
acc.Add("slow_queries", i, nil)
}
}
return nil
}
func init() {
plugins.Add("mysql", func() plugins.Plugin {
return &Mysql{}
})
}