feat(agent) multi-driver db monitoring, hot-plug config, release pipeline
This commit is contained in:
92
internal/collectors/mysql/mysql.go
Normal file
92
internal/collectors/mysql/mysql.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
|
||||
"bugs.watch/agent/internal/aggregate"
|
||||
)
|
||||
|
||||
// Collector queries MySQL global status each sample interval.
|
||||
// All queries run under a 3-second timeout; any failure is silently skipped.
|
||||
type Collector struct {
|
||||
db *sql.DB
|
||||
prevSlowQueries uint64
|
||||
hasPrev bool
|
||||
}
|
||||
|
||||
func New(dsn string) (*Collector, error) {
|
||||
db, err := sql.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db.SetMaxOpenConns(2)
|
||||
db.SetMaxIdleConns(1)
|
||||
db.SetConnMaxLifetime(5 * time.Minute)
|
||||
return &Collector{db: db}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Name() string { return "mysql" }
|
||||
|
||||
func (c *Collector) Close() { c.db.Close() }
|
||||
|
||||
func (c *Collector) Collect(window *aggregate.Window) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
rows, err := c.db.QueryContext(ctx,
|
||||
"SHOW GLOBAL STATUS WHERE Variable_name IN ('Threads_connected','Threads_running','Slow_queries')",
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
vars := make(map[string]uint64, 3)
|
||||
for rows.Next() {
|
||||
var name, raw string
|
||||
if err := rows.Scan(&name, &raw); err != nil {
|
||||
continue
|
||||
}
|
||||
if v, err := strconv.ParseUint(raw, 10, 64); err == nil {
|
||||
vars[name] = v
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var maxConn uint64
|
||||
if err := c.db.QueryRowContext(ctx, "SELECT @@max_connections").Scan(&maxConn); err != nil || maxConn == 0 {
|
||||
maxConn = 1
|
||||
}
|
||||
|
||||
connPct := float64(vars["Threads_connected"]) / float64(maxConn) * 100
|
||||
window.AddDBConnPct(connPct)
|
||||
window.AddDBThreadsRunning(float64(vars["Threads_running"]))
|
||||
|
||||
slow := vars["Slow_queries"]
|
||||
if c.hasPrev {
|
||||
var delta uint64
|
||||
if slow >= c.prevSlowQueries {
|
||||
delta = slow - c.prevSlowQueries
|
||||
}
|
||||
window.AddDBSlowQueriesDelta(delta)
|
||||
}
|
||||
c.prevSlowQueries = slow
|
||||
c.hasPrev = true
|
||||
|
||||
var sizeBytes uint64
|
||||
err = c.db.QueryRowContext(ctx,
|
||||
"SELECT COALESCE(SUM(data_length + index_length), 0)"+
|
||||
" FROM information_schema.tables"+
|
||||
" WHERE table_schema NOT IN ('information_schema','performance_schema','mysql','sys')",
|
||||
).Scan(&sizeBytes)
|
||||
if err == nil {
|
||||
window.SetDBSizeBytes(sizeBytes)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user