micro-wrapper-sql/wrapper.go
Vasiliy Tolstov b023ed8cec implement collect
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-15 15:49:54 +03:00

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))
}
}
}