Skip to content

Commit

Permalink
add metrics to monitor processes by user and host (#333)
Browse files Browse the repository at this point in the history
* add processes by user and host to info_schema_processlist.go

Signed-off-by: Peter Löffler <peter.loeffler@runtastic.com>
  • Loading branch information
peterloeffler authored and SuperQ committed Sep 25, 2018
1 parent ae7180b commit 410ace7
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The minimum supported MySQL version is now 5.5.

* [CHANGE] Update defaults for MySQL 5.5 #318
* [BUGFIX] Sanitize metric names in global variables #307
* [FEATURE] Add by_user and by_host metrics to info_schema.processlist collector (PR #333) #334

## 0.11.0 / 2018-06-29

Expand Down
60 changes: 50 additions & 10 deletions collector/info_schema_processlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,17 @@ import (
)

const infoSchemaProcesslistQuery = `
SELECT COALESCE(command,''),COALESCE(state,''),count(*),sum(time)
SELECT
user,
SUBSTRING_INDEX(host, ':', 1) AS host,
COALESCE(command,'') AS command,
COALESCE(state,'') AS state,
count(*) AS processes,
sum(time) AS seconds
FROM information_schema.processlist
WHERE ID != connection_id()
AND TIME >= %d
GROUP BY command,state
GROUP BY user,SUBSTRING_INDEX(host, ':', 1),command,state
ORDER BY null
`

Expand All @@ -26,6 +32,14 @@ var (
"collect.info_schema.processlist.min_time",
"Minimum time a thread must be in each state to be counted",
).Default("0").Int()
processesByUserFlag = kingpin.Flag(
"collect.info_schema.processlist.processes_by_user",
"Enable collecting the number of processes by user",
).Default("true").Bool()
processesByHostFlag = kingpin.Flag(
"collect.info_schema.processlist.processes_by_host",
"Enable collecting the number of processes by host",
).Default("true").Bool()
)

// Metric descriptors.
Expand All @@ -38,6 +52,14 @@ var (
prometheus.BuildFQName(namespace, informationSchema, "threads_seconds"),
"The number of seconds threads (connections) have used split by current state.",
[]string{"state"}, nil)
processesByUserDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, informationSchema, "processes_by_user"),
"The number of processes by user.",
[]string{"src_user"}, nil)
processesByHostDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, informationSchema, "processes_by_host"),
"The number of processes by host.",
[]string{"src_host"}, nil)
)

// whitelist for connection/process states in SHOW PROCESSLIST
Expand Down Expand Up @@ -147,30 +169,48 @@ func (ScrapeProcesslist) Scrape(db *sql.DB, ch chan<- prometheus.Metric) error {
defer processlistRows.Close()

var (
command string
state string
count uint32
time uint32
user string
host string
command string
state string
processes uint32
time uint32
)
stateCounts := make(map[string]uint32, len(threadStateCounterMap))
stateTime := make(map[string]uint32, len(threadStateCounterMap))
hostCount := make(map[string]uint32)
userCount := make(map[string]uint32)
for k, v := range threadStateCounterMap {
stateCounts[k] = v
stateTime[k] = v
}

for processlistRows.Next() {
err = processlistRows.Scan(&command, &state, &count, &time)
err = processlistRows.Scan(&user, &host, &command, &state, &processes, &time)
if err != nil {
return err
}
realState := deriveThreadState(command, state)
stateCounts[realState] += count
stateCounts[realState] += processes
stateTime[realState] += time
hostCount[host] = hostCount[host] + processes
userCount[user] = userCount[user] + processes
}

for state, count := range stateCounts {
ch <- prometheus.MustNewConstMetric(processlistCountDesc, prometheus.GaugeValue, float64(count), state)
if *processesByHostFlag == true {
for host, processes := range hostCount {
ch <- prometheus.MustNewConstMetric(processesByHostDesc, prometheus.GaugeValue, float64(processes), host)
}
}

if *processesByUserFlag == true {
for user, processes := range userCount {
ch <- prometheus.MustNewConstMetric(processesByUserDesc, prometheus.GaugeValue, float64(processes), user)
}
}

for state, processes := range stateCounts {
ch <- prometheus.MustNewConstMetric(processlistCountDesc, prometheus.GaugeValue, float64(processes), state)
}
for state, time := range stateTime {
ch <- prometheus.MustNewConstMetric(processlistTimeDesc, prometheus.GaugeValue, float64(time), state)
Expand Down

0 comments on commit 410ace7

Please sign in to comment.