GORM Metrics is a plugin for GORM that automatically collects and exposes database operation duration metrics for monitoring and observability. It integrates with Prometheus and is designed for easy use in Go applications using GORM.
- Tracks duration of GORM operations (query, create, update, delete, raw, row)
- Prometheus histogram metrics with rich labels: name, action, model, joins, outcome
- Identifies number of joins in queries
- Simple integration with GORM
Install the package using go get:
go get github.com/tpokki/gorm-metricsImport and register the plugin with your GORM DB instance:
import (
"github.com/tpokki/gorm-metrics"
"gorm.io/gorm"
)
db, err := gorm.Open(...)
if err != nil {
// handle error
}
// Register the metrics plugin
if err := db.Use(gm.Default()); err != nil {
panic(err)
}
// You can give custom name for the query
db.WithContext(gm.WithName("my_create")).Create(&Person{Name: "Bob", Age: 40})
// Or just rely on default labels
db.Create(&Person{Name: "Alice", Age: 40})The plugin exposes a Prometheus histogram metric:
gorm_metrics_duration_seconds: Duration of GORM operations in seconds
Labels:
name: The name of the operation, if defined in operation context (see below). Default value isdefault.action: The type of GORM operation (query,create,update,delete,raw,row)model: The table/model name (e.g.people,favorite_colors)joins: Number of joins in the query (as a string, e.g.0,1)outcome: The result of the operation (success,error)
gorm_metrics_duration_seconds{name="default",action="query",model="people",joins="1",outcome="success"} 0.001
Example:
gorm_metrics_duration_seconds{name="default",action="query",model="people",joins="1",outcome="success"} 0.001
gorm_metrics_duration_seconds{name="my_create",action="create",model="things",joins="0",outcome="success"} 0.002
To expose metrics for Prometheus, use the prometheus/client_golang package and register the metrics endpoint in your HTTP server:
import (
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)See plugin_test.go for example usage and metric assertions. The test covers plugin registration, GORM operations, and metric validation.
The default plugin uses Prometheus default buckets and automatically registers the histogram with the following labels:
name,action,model,joins,outcome
You can customize label extraction by providing your own LabelFn when creating a GormMetrics instance:
plugin := &gm.GormMetrics{
HistogramVec: promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "gorm_custom_metric",
Help: "Custom GORM metric with just name label",
Buckets: prometheus.DefBuckets,
},
[]string{"name"}, // Only the name label
),
LabelFn: func(db *gorm.DB, action gm.Action) []string {
ctxVal, ok := db.Statement.Context.Value(gm.GormMetricsContextKey).(*gm.MetricContextValue)
if ok {
return []string{ctxVal.Name()}
}
return []string{"default"}
},
}
// Usage example:
db.WithContext(gm.WithName("my_create")).Create(&Person{Name: "Bob", Age: 40})See the code for details on advanced configuration and more examples.
MIT