forked from prometheus/mysqld_exporter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslave_hosts.go
138 lines (119 loc) · 3.81 KB
/
slave_hosts.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
// Copyright 2018 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Scrape heartbeat data.
package collector
import (
"context"
"database/sql"
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/satori/go.uuid"
)
const (
// slavehosts is the Metric subsystem we use.
slavehosts = "slave_hosts"
// heartbeatQuery is the query used to fetch the stored and current
// timestamps. %s will be replaced by the database and table name.
// The second column allows gets the server timestamp at the exact same
// time the query is run.
slaveHostsQuery = "SHOW SLAVE HOSTS"
)
// Metric descriptors.
var (
SlaveHostsInfo = prometheus.NewDesc(
prometheus.BuildFQName(namespace, heartbeat, "mysql_slave_hosts_info"),
"Information about running slaves",
[]string{"server_id", "slave_host", "port", "master_id", "slave_uuid"}, nil,
)
)
// ScrapeSlaveHosts scrapes metrics about the replicating slaves.
type ScrapeSlaveHosts struct{}
// Name of the Scraper. Should be unique.
func (ScrapeSlaveHosts) Name() string {
return slavehosts
}
// Help describes the role of the Scraper.
func (ScrapeSlaveHosts) Help() string {
return "Scrape information from 'SHOW SLAVE HOSTS'"
}
// Version of MySQL from which scraper is available.
func (ScrapeSlaveHosts) Version() float64 {
return 5.1
}
// Scrape collects data from database connection and sends it over channel as prometheus metric.
func (ScrapeSlaveHosts) Scrape(ctx context.Context, db *sql.DB, ch chan<- prometheus.Metric, logger log.Logger) error {
slaveHostsRows, err := db.QueryContext(ctx, slaveHostsQuery)
if err != nil {
return err
}
defer slaveHostsRows.Close()
// fields of row
var serverId string
var host string
var port string
var rrrOrMasterId string
var slaveUuidOrMasterId string
// Depends on the version of MySQL being scraped
var masterId string
var slaveUuid string
columnNames, err := slaveHostsRows.Columns()
if err != nil {
return err
}
for slaveHostsRows.Next() {
// Newer versions of mysql have the following
// Server_id, Host, Port, Master_id, Slave_UUID
// Older versions of mysql have the following
// Server_id, Host, Port, Rpl_recovery_rank, Master_id
// MySQL 5.5 and MariaDB 10.5 have the following
// Server_id, Host, Port, Master_id
if len(columnNames) == 5 {
err = slaveHostsRows.Scan(&serverId, &host, &port, &rrrOrMasterId, &slaveUuidOrMasterId)
} else {
err = slaveHostsRows.Scan(&serverId, &host, &port, &rrrOrMasterId)
}
if err != nil {
return err
}
// if a Slave_UUID or Rpl_recovery_rank field is present
if len(columnNames) == 5 {
// Check to see if slaveUuidOrMasterId resembles a UUID or not
// to find out if we are using an old version of MySQL
if _, err = uuid.FromString(slaveUuidOrMasterId); err != nil {
// We are running an older version of MySQL with no slave UUID
slaveUuid = ""
masterId = slaveUuidOrMasterId
} else {
// We are running a more recent version of MySQL
slaveUuid = slaveUuidOrMasterId
masterId = rrrOrMasterId
}
} else {
slaveUuid = ""
masterId = rrrOrMasterId
}
ch <- prometheus.MustNewConstMetric(
SlaveHostsInfo,
prometheus.GaugeValue,
1,
serverId,
host,
port,
masterId,
slaveUuid,
)
}
return nil
}
// check interface
var _ Scraper = ScrapeSlaveHosts{}