feat(agent) multi-driver db monitoring, hot-plug config, release pipeline
This commit is contained in:
94
internal/collectors/mongodb/mongodb.go
Normal file
94
internal/collectors/mongodb/mongodb.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package mongodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
||||
"bugs.watch/agent/internal/aggregate"
|
||||
)
|
||||
|
||||
// Collector queries MongoDB serverStatus and listDatabases each sample interval.
|
||||
// All queries run under a 3-second timeout; any failure is silently skipped.
|
||||
// Metrics mapping:
|
||||
// db_conn_pct → current / (current + available) * 100
|
||||
// db_threads_running → connections.current
|
||||
// db_size_bytes → totalSize from listDatabases
|
||||
type Collector struct {
|
||||
client *mongo.Client
|
||||
}
|
||||
|
||||
func New(uri string) (*Collector, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri).
|
||||
SetConnectTimeout(3*time.Second).
|
||||
SetServerSelectionTimeout(3*time.Second))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Collector{client: client}, nil
|
||||
}
|
||||
|
||||
func (c *Collector) Name() string { return "mongodb" }
|
||||
|
||||
func (c *Collector) Close() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
c.client.Disconnect(ctx)
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(window *aggregate.Window) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
admin := c.client.Database("admin")
|
||||
|
||||
var status bson.M
|
||||
if err := admin.RunCommand(ctx, bson.D{
|
||||
{Key: "serverStatus", Value: 1},
|
||||
{Key: "repl", Value: 0},
|
||||
{Key: "metrics", Value: 0},
|
||||
{Key: "locks", Value: 0},
|
||||
}).Decode(&status); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if conns, ok := status["connections"].(bson.M); ok {
|
||||
current := toFloat64(conns["current"])
|
||||
available := toFloat64(conns["available"])
|
||||
total := current + available
|
||||
if total > 0 {
|
||||
window.AddDBConnPct(current / total * 100)
|
||||
}
|
||||
if current > 0 {
|
||||
window.AddDBThreadsRunning(current)
|
||||
}
|
||||
}
|
||||
|
||||
var listResult bson.M
|
||||
if err := admin.RunCommand(ctx, bson.D{
|
||||
{Key: "listDatabases", Value: 1},
|
||||
{Key: "nameOnly", Value: false},
|
||||
}).Decode(&listResult); err == nil {
|
||||
if totalSize := toFloat64(listResult["totalSize"]); totalSize > 0 {
|
||||
window.SetDBSizeBytes(uint64(totalSize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toFloat64(v interface{}) float64 {
|
||||
switch x := v.(type) {
|
||||
case int32:
|
||||
return float64(x)
|
||||
case int64:
|
||||
return float64(x)
|
||||
case float64:
|
||||
return x
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user