To expose and monitor database query execution times with expvar
in Go, you can follow these steps:
import (
"expvar"
"database/sql"
"time"
)
type DatabaseStats struct {
TotalQueries *expvar.Int
TotalTime *expvar.Int
AverageTime *expvar.Float
MinTime *expvar.Duration
MaxTime *expvar.Duration
LastQueryTime *expvar.Duration
}
func main() {
dbStats := &DatabaseStats{
TotalQueries: expvar.NewInt("total_queries"),
TotalTime: expvar.NewInt("total_time"),
AverageTime: expvar.NewFloat("average_time"),
MinTime: expvar.NewDuration("min_time"),
MaxTime: expvar.NewDuration("max_time"),
LastQueryTime: expvar.NewDuration("last_query_time"),
}
// ...
}
func executeQuery(db *sql.DB, dbStats *DatabaseStats) {
startTime := time.Now()
// Your database query execution code here
elapsedTime := time.Since(startTime)
dbStats.LastQueryTime.Set(elapsedTime)
dbStats.TotalTime.Add(int64(elapsedTime))
dbStats.TotalQueries.Add(1)
currentTotalTime := dbStats.TotalTime.Value()
currentTotalQueries := dbStats.TotalQueries.Value()
dbStats.AverageTime.Set(float64(currentTotalTime) / float64(currentTotalQueries))
minQueryTime := time.Duration(dbStats.MinTime.Value())
maxQueryTime := time.Duration(dbStats.MaxTime.Value())
if elapsedTime < minQueryTime || minQueryTime == 0 {
dbStats.MinTime.Set(int64(elapsedTime))
}
if elapsedTime > maxQueryTime {
dbStats.MaxTime.Set(int64(elapsedTime))
}
}
func exposeStats() {
expvar.Publish("db_stats", expvar.Func(func() interface{} {
return dbStats
}))
http.ListenAndServe(":8080", nil)
}
Make sure to call exposeStats()
in your main function to start serving the expvar endpoint.
This setup will expose the various database query execution time metrics through the /debug/vars
endpoint, which you can view in your browser or fetch programmatically.