基于gorm默认的上报
import (
"gorm.io/gorm"
"gorm.io/driver/sqlite"
"gorm.io/plugin/prometheus"
)
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
db.Use(prometheus.New(prometheus.Config{
DBName: "db1", // use `DBName` as metrics label
RefreshInterval: 15, // Refresh metrics interval (default 15 seconds)
PushAddr: "prometheus pusher address", // push metrics if `PushAddr` configured
StartServer: true, // start http server to expose metrics
HTTPServerPort: 8080, // configure http server port, default port 8080 (if you have configured multiple instances, only the first `HTTPServerPort` will be used to start server)
MetricsCollector: []prometheus.MetricsCollector {
&prometheus.MySQL{
VariableNames: []string{"Threads_running"},
},
}, // user defined metrics
}))
以上为gorm默认提供的prometheus监控方式,但需要注意的是,这种方式会全新启动一个端点(http://xxxx:8080/metrics)。如果用户希望将上报的metrics上报到其他端点,可以使用下面方式。
基于gorm日志的上报
gorm的日志中已经带有了sql source,执行耗时,参数,发生时间等数据,如果能够对gorm的日志进行扩展,在记录日志的同时,将数据采集即可不用开启新的端点就能完成采集,简易代码如下:
type StatsLog struct {
tally.Scope
gormLogger *gormzap.Logger
}
func (log *StatsLog) Print(v ...interface{}) {
log.stats(v)
log.gormLogger.Print(v...)
}
func (log *StatsLog) stats(values []interface{}) {
if len(values) > 1 {
var level = values[0]
source := getSource(values)
if level == "sql" && log.Scope != nil {
duration := getDuration(values)
sql := values[3].(string)
tags := map[string]string{
"sql": sql,
"source": source,
}
log.Scope.Tagged(tags).Histogram("metrics", HistogramBuckets).RecordDuration(duration)
}
}
}
最后,向gorm注册log实现时,使用我们自定义的logger即可