mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 11:52:09 +08:00

* records grafana database metrics for unified storage * update type to tracing.Tracer * use nil for tracer in tests
117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
package dbimpl
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/dlmiddlecote/sqlstats"
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"xorm.io/xorm"
|
|
|
|
infraDB "github.com/grafana/grafana/pkg/infra/db"
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
|
|
"github.com/grafana/grafana/pkg/storage/unified/sql/db/migrations"
|
|
)
|
|
|
|
const (
|
|
dbTypeMySQL = "mysql"
|
|
dbTypePostgres = "postgres"
|
|
)
|
|
|
|
func ProvideResourceDB(grafanaDB infraDB.DB, cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer tracing.Tracer) (db.DBProvider, error) {
|
|
p, err := newResourceDBProvider(grafanaDB, cfg, features, tracer)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("provide Resource DB: %w", err)
|
|
}
|
|
var once sync.Once
|
|
var resourceDB db.DB
|
|
|
|
return dbProviderFunc(func(ctx context.Context) (db.DB, error) {
|
|
once.Do(func() {
|
|
resourceDB, err = p.init(ctx)
|
|
})
|
|
return resourceDB, err
|
|
}), nil
|
|
}
|
|
|
|
type dbProviderFunc func(context.Context) (db.DB, error)
|
|
|
|
func (f dbProviderFunc) Init(ctx context.Context) (db.DB, error) {
|
|
return f(ctx)
|
|
}
|
|
|
|
type resourceDBProvider struct {
|
|
engine *xorm.Engine
|
|
cfg *setting.Cfg
|
|
log log.Logger
|
|
migrateFunc func(context.Context, *xorm.Engine, *setting.Cfg) error
|
|
registerMetrics bool
|
|
logQueries bool
|
|
}
|
|
|
|
func newResourceDBProvider(grafanaDB infraDB.DB, cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer tracing.Tracer) (p *resourceDBProvider, err error) {
|
|
// TODO: This should be renamed resource_api
|
|
getter := §ionGetter{
|
|
DynamicSection: cfg.SectionWithEnvOverrides("resource_api"),
|
|
}
|
|
|
|
p = &resourceDBProvider{
|
|
cfg: cfg,
|
|
log: log.New("entity-db"),
|
|
logQueries: getter.Key("log_queries").MustBool(false),
|
|
}
|
|
if features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorage) {
|
|
p.migrateFunc = migrations.MigrateResourceStore
|
|
}
|
|
|
|
switch dbType := getter.Key("db_type").MustString(""); dbType {
|
|
case dbTypePostgres:
|
|
p.registerMetrics = true
|
|
p.engine, err = getEnginePostgres(getter, tracer)
|
|
return p, err
|
|
|
|
case dbTypeMySQL:
|
|
p.registerMetrics = true
|
|
p.engine, err = getEngineMySQL(getter, tracer)
|
|
return p, err
|
|
|
|
case "":
|
|
// try to use the grafana db connection
|
|
if grafanaDB == nil {
|
|
return p, fmt.Errorf("no db connection provided")
|
|
}
|
|
p.engine = grafanaDB.GetEngine()
|
|
return p, nil
|
|
|
|
default:
|
|
// TODO: sqlite support
|
|
return p, fmt.Errorf("invalid db type specified: %s", dbType)
|
|
}
|
|
}
|
|
|
|
func (p *resourceDBProvider) init(ctx context.Context) (db.DB, error) {
|
|
if p.registerMetrics {
|
|
err := prometheus.Register(sqlstats.NewStatsCollector("unified_storage", p.engine.DB().DB))
|
|
if err != nil {
|
|
p.log.Warn("Failed to register unified storage sql stats collector", "error", err)
|
|
}
|
|
}
|
|
_ = p.logQueries // TODO: configure SQL logging
|
|
|
|
// TODO: change the migrator to use db.DB instead of xorm
|
|
// Skip migrations if feature flag is not enabled
|
|
if p.migrateFunc != nil {
|
|
err := p.migrateFunc(ctx, p.engine, p.cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("run migrations: %w", err)
|
|
}
|
|
}
|
|
|
|
return NewDB(p.engine.DB().DB, p.engine.Dialect().DriverName()), nil
|
|
}
|