160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
|
package wrapper
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"database/sql"
|
||
|
"time"
|
||
|
|
||
|
"github.com/unistack-org/micro/v3/logger"
|
||
|
"github.com/unistack-org/micro/v3/meter"
|
||
|
"github.com/unistack-org/micro/v3/tracer"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
DefaultStatsInterval = 5 * time.Second
|
||
|
// default metric prefix
|
||
|
DefaultMetricPrefix = "micro_sql_"
|
||
|
// default label prefix
|
||
|
DefaultLabelPrefix = "micro_"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
DatabaseHostLabel = "database_host"
|
||
|
DatabaseNameLabel = "database_name"
|
||
|
ServiceNameLabel = "service_name"
|
||
|
ServiceVersionLabel = "service_version"
|
||
|
ServiceIDLabel = "service_id"
|
||
|
|
||
|
MaxOpenConnectionsLabel = "max_open_connections"
|
||
|
OpenConnectionsLabel = "open_connections"
|
||
|
InuseConnectionsLabel = "inuse_connections"
|
||
|
IdleConnectionsLabel = "idle_connections"
|
||
|
WaitConnectionsLabel = "wait_connections"
|
||
|
BlockedSecondsLabel = "blocked_seconds"
|
||
|
MaxIdleClosedLabel = "max_idle_closed"
|
||
|
MaxLifetimeClosedLabel = "max_lifetime_closed"
|
||
|
|
||
|
//srequest_total // counter
|
||
|
//slatency_microseconds // summary
|
||
|
//srequest_duration_seconds // histogramm
|
||
|
|
||
|
)
|
||
|
|
||
|
type Options struct {
|
||
|
Logger logger.Logger
|
||
|
Meter meter.Meter
|
||
|
Tracer tracer.Tracer
|
||
|
DatabaseHost string
|
||
|
DatabaseName string
|
||
|
ServiceName string
|
||
|
ServiceVersion string
|
||
|
ServiceID string
|
||
|
}
|
||
|
|
||
|
type Option func(*Options)
|
||
|
|
||
|
func DatabaseHost(host string) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.DatabaseHost = host
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func DatabaseName(name string) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.DatabaseName = name
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ServiceName(name string) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.ServiceName = name
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ServiceVersion(version string) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.ServiceVersion = version
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ServiceID(id string) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.ServiceID = id
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Meter(m meter.Meter) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.Meter = m
|
||
|
}
|
||
|
}
|
||
|
func Logger(l logger.Logger) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.Logger = l
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Tracer(t tracer.Tracer) Option {
|
||
|
return func(opts *Options) {
|
||
|
opts.Tracer = t
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type queryKey struct{}
|
||
|
|
||
|
func QueryName(ctx context.Context, name string) context.Context {
|
||
|
if ctx == nil {
|
||
|
ctx = context.Background()
|
||
|
}
|
||
|
|
||
|
return context.WithValue(ctx, queryKey{}, name)
|
||
|
}
|
||
|
|
||
|
func getName(ctx context.Context) string {
|
||
|
name := "Unknown"
|
||
|
|
||
|
val, ok := ctx.Value(queryKey{}).(string)
|
||
|
if ok && len(val) > 0 {
|
||
|
name = val
|
||
|
}
|
||
|
|
||
|
return name
|
||
|
}
|
||
|
|
||
|
type Wrapper struct {
|
||
|
db *sql.DB
|
||
|
opts Options
|
||
|
}
|
||
|
|
||
|
func (w *Wrapper) collect() {
|
||
|
labels := []string{
|
||
|
DatabaseHostLabel, w.opts.DatabaseHost,
|
||
|
DatabaseNameLabel, w.opts.DatabaseName,
|
||
|
ServiceNameLabel, w.opts.ServiceName,
|
||
|
ServiceVersionLabel, w.opts.ServiceVersion,
|
||
|
ServiceIDLabel, w.opts.ServiceID,
|
||
|
}
|
||
|
|
||
|
ticker := time.NewTicker(DefaultStatsInterval)
|
||
|
defer ticker.Stop()
|
||
|
|
||
|
for {
|
||
|
select {
|
||
|
case <-ticker.C:
|
||
|
if w.db == nil {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
stats := w.db.Stats()
|
||
|
w.opts.Meter.FloatCounter(MaxOpenConnectionsLabel, meter.Labels(labels...)).Set(float64(stats.MaxOpenConnections))
|
||
|
w.opts.Meter.FloatCounter(OpenConnectionsLabel, meter.Labels(labels...)).Set(float64(stats.OpenConnections))
|
||
|
w.opts.Meter.FloatCounter(InuseConnectionsLabel, meter.Labels(labels...)).Set(float64(stats.InUse))
|
||
|
w.opts.Meter.FloatCounter(IdleConnectionsLabel, meter.Labels(labels...)).Set(float64(stats.Idle))
|
||
|
w.opts.Meter.FloatCounter(WaitConnectionsLabel, meter.Labels(labels...)).Set(float64(stats.WaitCount))
|
||
|
w.opts.Meter.FloatCounter(BlockedSecondsLabel, meter.Labels(labels...)).Set(stats.WaitDuration.Seconds())
|
||
|
w.opts.Meter.FloatCounter(MaxIdleClosedLabel, meter.Labels(labels...)).Set(float64(stats.MaxIdleClosed))
|
||
|
w.opts.Meter.FloatCounter(MaxLifetimeClosedLabel, meter.Labels(labels...)).Set(float64(stats.MaxLifetimeClosed))
|
||
|
}
|
||
|
}
|
||
|
}
|