/
githubmirror
/
grafana
Обзор
Документация
Войти
/
githubmirror
/
grafana
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
pkg/services/pluginsintegration/coreplugin/coreplugins.go
211 строк
6 KB
Ryan Morris
InfluxDB: Remove from core plugins (#129602)
04 авг 2026, 19:37
Не верифицирован
04 авг 2026, 19:37
9b382c7
Код
Авторство
О чём код?
package coreplugin import ( "context" "errors" "fmt" "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" sdklog "github.com/grafana/grafana-plugin-sdk-go/backend/log" sdktracing "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/provider" "github.com/grafana/grafana/pkg/plugins/log" "github.com/grafana/grafana/pkg/tsdb/azuremonitor" "github.com/grafana/grafana/pkg/tsdb/cloudwatch" testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource" "github.com/grafana/grafana/pkg/tsdb/grafanads" "github.com/grafana/grafana/pkg/tsdb/graphite" ) const ( CloudWatch = "cloudwatch" AzureMonitor = "grafana-azure-monitor-datasource" Graphite = "graphite" TestData = "grafana-testdata-datasource" TestDataAlias = "testdata" Grafana = "grafana" ) func init() { // Non-optimal global solution to replace plugin SDK default loggers for core plugins. sdklog.DefaultLogger = &logWrapper{logger: log.New("plugin.coreplugin")} backend.Logger = sdklog.DefaultLogger backend.NewLoggerWith = func(args ...any) sdklog.Logger { for i, arg := range args { // Obtain logger name from args. if s, ok := arg.(string); ok && s == "logger" { l := &logWrapper{logger: log.New(args[i+1].(string))} // new args slice without logger name and logger name value if len(args) > 2 { newArgs := make([]any, 0, len(args)-2) newArgs = append(newArgs, args[:i]...) newArgs = append(newArgs, args[i+2:]...) return l.With(newArgs...) } return l } } return sdklog.DefaultLogger } } type Registry struct { store map[string]backendplugin.PluginFactoryFunc } func NewRegistry(store map[string]backendplugin.PluginFactoryFunc) *Registry { return &Registry{ store: store, } } func ProvideCoreProvider(coreRegistry *Registry) plugins.BackendFactoryProvider { return provider.New(coreRegistry.BackendFactoryProvider(), provider.DefaultProvider) } func ProvideCoreRegistry(tracer trace.Tracer, am *azuremonitor.Service, cw *cloudwatch.Service, grap *graphite.Service, td *testdatasource.Service, graf *grafanads.Service) *Registry { // Non-optimal global solution to replace plugin SDK default tracer for core plugins. sdktracing.InitDefaultTracer(tracer) return NewRegistry(map[string]backendplugin.PluginFactoryFunc{ CloudWatch: asBackendPlugin(cw), AzureMonitor: asBackendPlugin(am), Graphite: asBackendPlugin(grap), TestData: asBackendPlugin(td), Grafana: asBackendPlugin(graf), }) } func (cr *Registry) Get(pluginID string) backendplugin.PluginFactoryFunc { return cr.store[pluginID] } func (cr *Registry) BackendFactoryProvider() func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { return func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { if !p.IsCorePlugin() { return nil } return cr.Get(p.ID) } } func asBackendPlugin(svc any) backendplugin.PluginFactoryFunc { opts := backend.ServeOpts{} if queryHandler, ok := svc.(backend.QueryDataHandler); ok { opts.QueryDataHandler = queryHandler } if handler, ok := svc.(backend.QueryChunkedDataHandler); ok { opts.QueryChunkedDataHandler = handler } if resourceHandler, ok := svc.(backend.CallResourceHandler); ok { opts.CallResourceHandler = resourceHandler } if streamHandler, ok := svc.(backend.StreamHandler); ok { opts.StreamHandler = streamHandler } if healthHandler, ok := svc.(backend.CheckHealthHandler); ok { opts.CheckHealthHandler = healthHandler } if storageHandler, ok := svc.(backend.AdmissionHandler); ok { opts.AdmissionHandler = storageHandler } if opts.QueryDataHandler != nil || opts.QueryChunkedDataHandler != nil || opts.CheckHealthHandler != nil || opts.StreamHandler != nil || opts.CallResourceHandler != nil { return coreplugin.New(opts) } return nil } type logWrapper struct { logger log.Logger } func (l *logWrapper) Debug(msg string, args ...any) { l.logger.Debug(msg, args...) } func (l *logWrapper) Info(msg string, args ...any) { l.logger.Info(msg, args...) } func (l *logWrapper) Warn(msg string, args ...any) { l.logger.Warn(msg, args...) } func (l *logWrapper) Error(msg string, args ...any) { l.logger.Error(msg, args...) } func (l *logWrapper) Level() sdklog.Level { return sdklog.NoLevel } func (l *logWrapper) With(args ...any) sdklog.Logger { return &logWrapper{ logger: l.logger.New(args...), } } func (l *logWrapper) FromContext(ctx context.Context) sdklog.Logger { return &logWrapper{ logger: l.logger.FromContext(ctx), } } var ErrCorePluginNotFound = errors.New("core plugin not found") // NewPlugin factory for creating and initializing a single core plugin. // Note: cfg only needed for mssql connection pooling defaults. func NewPlugin(pluginID string, httpClientProvider *httpclient.Provider, tracer trace.Tracer) (*plugins.Plugin, error) { jsonData := plugins.JSONData{ ID: pluginID, AliasIDs: []string{}, } var svc any switch pluginID { case TestData, TestDataAlias: jsonData.ID = TestData jsonData.AliasIDs = append(jsonData.AliasIDs, TestDataAlias) svc = testdatasource.ProvideService() case CloudWatch: svc = cloudwatch.ProvideService() case AzureMonitor: svc = azuremonitor.ProvideService(httpClientProvider) case Graphite: svc = graphite.ProvideService(httpClientProvider, tracer) default: return nil, ErrCorePluginNotFound } p := plugins.Plugin{ JSONData: jsonData, Class: plugins.ClassCore, } p.SetLogger(log.New(fmt.Sprintf("plugin.%s", p.ID))) backendFactory := asBackendPlugin(svc) if backendFactory == nil { return nil, ErrCorePluginNotFound } bp, err := backendFactory(p.ID, p.Logger(), tracer, nil) if err != nil { return nil, err } p.RegisterClient(bp) return &p, nil }