meter: improve meter usage across micro framework #409

Merged
vtolstov merged 3 commits from feature/issue-220 into v4 2025-10-07 23:54:21 +03:00
Showing only changes of commit 3d4198ac42 - Show all commits

View File

@@ -3,6 +3,7 @@ package sql
import ( import (
"context" "context"
"database/sql" "database/sql"
"sync"
"time" "time"
) )
@@ -11,31 +12,84 @@ type Statser interface {
} }
func NewStatsMeter(ctx context.Context, db Statser, opts ...Option) { func NewStatsMeter(ctx context.Context, db Statser, opts ...Option) {
options := NewOptions(opts...)
go func() {
ticker := time.NewTicker(options.MeterStatsInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if db == nil { if db == nil {
return return
} }
options := NewOptions(opts...)
var (
statsMu sync.Mutex
lastUpdated time.Time
maxOpenConnections, openConnections, inUse, idle, waitCount float64
maxIdleClosed, maxIdleTimeClosed, maxLifetimeClosed float64
waitDuration float64
)
updateFn := func() {
statsMu.Lock()
defer statsMu.Unlock()
if time.Since(lastUpdated) < options.MeterStatsInterval {
return
}
stats := db.Stats() stats := db.Stats()
options.Meter.Counter(MaxOpenConnections).Set(uint64(stats.MaxOpenConnections)) maxOpenConnections = float64(stats.MaxOpenConnections)
options.Meter.Counter(OpenConnections).Set(uint64(stats.OpenConnections)) openConnections = float64(stats.OpenConnections)
options.Meter.Counter(InuseConnections).Set(uint64(stats.InUse)) inUse = float64(stats.InUse)
options.Meter.Counter(IdleConnections).Set(uint64(stats.Idle)) idle = float64(stats.Idle)
options.Meter.Counter(WaitConnections).Set(uint64(stats.WaitCount)) waitCount = float64(stats.WaitCount)
options.Meter.FloatCounter(BlockedSeconds).Set(stats.WaitDuration.Seconds()) maxIdleClosed = float64(stats.MaxIdleClosed)
options.Meter.Counter(MaxIdleClosed).Set(uint64(stats.MaxIdleClosed)) maxIdleTimeClosed = float64(stats.MaxIdleTimeClosed)
options.Meter.Counter(MaxIdletimeClosed).Set(uint64(stats.MaxIdleTimeClosed)) maxLifetimeClosed = float64(stats.MaxLifetimeClosed)
options.Meter.Counter(MaxLifetimeClosed).Set(uint64(stats.MaxLifetimeClosed)) waitDuration = float64(stats.WaitDuration.Seconds())
lastUpdated = time.Now()
} }
}
}() options.Meter.Gauge(MaxOpenConnections, func() float64 {
updateFn()
return maxOpenConnections
})
options.Meter.Gauge(OpenConnections, func() float64 {
updateFn()
return openConnections
})
options.Meter.Gauge(InuseConnections, func() float64 {
updateFn()
return inUse
})
options.Meter.Gauge(IdleConnections, func() float64 {
updateFn()
return idle
})
options.Meter.Gauge(WaitConnections, func() float64 {
updateFn()
return waitCount
})
options.Meter.Gauge(BlockedSeconds, func() float64 {
updateFn()
return waitDuration
})
options.Meter.Gauge(MaxIdleClosed, func() float64 {
updateFn()
return maxIdleClosed
})
options.Meter.Gauge(MaxIdletimeClosed, func() float64 {
updateFn()
return maxIdleTimeClosed
})
options.Meter.Gauge(MaxLifetimeClosed, func() float64 {
updateFn()
return maxLifetimeClosed
})
} }