meter: improve meter usage across micro framework #409
@@ -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) {
|
||||||
|
if db == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
options := NewOptions(opts...)
|
options := NewOptions(opts...)
|
||||||
|
|
||||||
go func() {
|
var (
|
||||||
ticker := time.NewTicker(options.MeterStatsInterval)
|
statsMu sync.Mutex
|
||||||
defer ticker.Stop()
|
lastUpdated time.Time
|
||||||
|
maxOpenConnections, openConnections, inUse, idle, waitCount float64
|
||||||
|
maxIdleClosed, maxIdleTimeClosed, maxLifetimeClosed float64
|
||||||
|
waitDuration float64
|
||||||
|
)
|
||||||
|
|
||||||
for {
|
updateFn := func() {
|
||||||
select {
|
statsMu.Lock()
|
||||||
case <-ctx.Done():
|
defer statsMu.Unlock()
|
||||||
return
|
|
||||||
case <-ticker.C:
|
if time.Since(lastUpdated) < options.MeterStatsInterval {
|
||||||
if db == nil {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
stats := db.Stats()
|
|
||||||
options.Meter.Counter(MaxOpenConnections).Set(uint64(stats.MaxOpenConnections))
|
|
||||||
options.Meter.Counter(OpenConnections).Set(uint64(stats.OpenConnections))
|
|
||||||
options.Meter.Counter(InuseConnections).Set(uint64(stats.InUse))
|
|
||||||
options.Meter.Counter(IdleConnections).Set(uint64(stats.Idle))
|
|
||||||
options.Meter.Counter(WaitConnections).Set(uint64(stats.WaitCount))
|
|
||||||
options.Meter.FloatCounter(BlockedSeconds).Set(stats.WaitDuration.Seconds())
|
|
||||||
options.Meter.Counter(MaxIdleClosed).Set(uint64(stats.MaxIdleClosed))
|
|
||||||
options.Meter.Counter(MaxIdletimeClosed).Set(uint64(stats.MaxIdleTimeClosed))
|
|
||||||
options.Meter.Counter(MaxLifetimeClosed).Set(uint64(stats.MaxLifetimeClosed))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
stats := db.Stats()
|
||||||
|
maxOpenConnections = float64(stats.MaxOpenConnections)
|
||||||
|
openConnections = float64(stats.OpenConnections)
|
||||||
|
inUse = float64(stats.InUse)
|
||||||
|
idle = float64(stats.Idle)
|
||||||
|
waitCount = float64(stats.WaitCount)
|
||||||
|
maxIdleClosed = float64(stats.MaxIdleClosed)
|
||||||
|
maxIdleTimeClosed = float64(stats.MaxIdleTimeClosed)
|
||||||
|
maxLifetimeClosed = float64(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
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user