From 958eea2f78683eca317e8c5b2eacda0038aeb1c9 Mon Sep 17 00:00:00 2001 From: Will Browne Date: Tue, 24 Jan 2023 16:18:34 +0100 Subject: [PATCH] Plugins: Add backend target to instrumentation (#61980) * add target * fix test --- .../backendplugin/coreplugin/core_plugin.go | 4 +++ .../backendplugin/grpcplugin/grpc_plugin.go | 4 +++ pkg/plugins/backendplugin/ifaces.go | 10 +++++++ .../instrumentation/instrumentation.go | 30 +++++++++++-------- pkg/plugins/manager/client/client.go | 24 +++++++++++---- pkg/plugins/plugins.go | 10 +++++++ .../backendplugin/backendplugin_test.go | 4 +++ 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/pkg/plugins/backendplugin/coreplugin/core_plugin.go b/pkg/plugins/backendplugin/coreplugin/core_plugin.go index c59bdf92549..c237f36e26c 100644 --- a/pkg/plugins/backendplugin/coreplugin/core_plugin.go +++ b/pkg/plugins/backendplugin/coreplugin/core_plugin.go @@ -64,6 +64,10 @@ func (cp *corePlugin) IsDecommissioned() bool { return false } +func (cp *corePlugin) Target() backendplugin.Target { + return backendplugin.TargetInMemory +} + func (cp *corePlugin) CollectMetrics(_ context.Context, _ *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) { return nil, backendplugin.ErrMethodNotImplemented } diff --git a/pkg/plugins/backendplugin/grpcplugin/grpc_plugin.go b/pkg/plugins/backendplugin/grpcplugin/grpc_plugin.go index f489be62795..880293ef138 100644 --- a/pkg/plugins/backendplugin/grpcplugin/grpc_plugin.go +++ b/pkg/plugins/backendplugin/grpcplugin/grpc_plugin.go @@ -120,6 +120,10 @@ func (p *grpcPlugin) IsDecommissioned() bool { return p.decommissioned } +func (p *grpcPlugin) Target() backendplugin.Target { + return backendplugin.TargetLocal +} + func (p *grpcPlugin) getPluginClient() (pluginClient, bool) { p.mutex.RLock() if p.client == nil || p.client.Exited() || p.pluginClient == nil { diff --git a/pkg/plugins/backendplugin/ifaces.go b/pkg/plugins/backendplugin/ifaces.go index 7ee21d9dcc5..bfade386006 100644 --- a/pkg/plugins/backendplugin/ifaces.go +++ b/pkg/plugins/backendplugin/ifaces.go @@ -17,9 +17,19 @@ type Plugin interface { Exited() bool Decommission() error IsDecommissioned() bool + Target() Target backend.CollectMetricsHandler backend.CheckHealthHandler backend.QueryDataHandler backend.CallResourceHandler backend.StreamHandler } + +type Target string + +const ( + TargetNone Target = "none" + TargetUnknown Target = "unknown" + TargetInMemory Target = "in_memory" + TargetLocal Target = "local" +) diff --git a/pkg/plugins/backendplugin/instrumentation/instrumentation.go b/pkg/plugins/backendplugin/instrumentation/instrumentation.go index 423d8884dc8..843b85de2a5 100644 --- a/pkg/plugins/backendplugin/instrumentation/instrumentation.go +++ b/pkg/plugins/backendplugin/instrumentation/instrumentation.go @@ -6,11 +6,12 @@ import ( "time" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/infra/tracing" - "github.com/grafana/grafana/pkg/plugins/config" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/plugins/backendplugin" ) var ( @@ -18,20 +19,20 @@ var ( Namespace: "grafana", Name: "plugin_request_total", Help: "The total amount of plugin requests", - }, []string{"plugin_id", "endpoint", "status"}) + }, []string{"plugin_id", "endpoint", "status", "target"}) pluginRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ Namespace: "grafana", Name: "plugin_request_duration_milliseconds", Help: "Plugin request duration", Buckets: []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 25, 50, 100}, - }, []string{"plugin_id", "endpoint"}) + }, []string{"plugin_id", "endpoint", "target"}) ) var logger log.Logger = log.New("plugin.instrumentation") // instrumentPluginRequest instruments success rate and latency of `fn` -func instrumentPluginRequest(ctx context.Context, cfg *config.Cfg, pluginCtx *backend.PluginContext, endpoint string, fn func() error) error { +func instrumentPluginRequest(ctx context.Context, cfg Cfg, pluginCtx *backend.PluginContext, endpoint string, fn func() error) error { status := "ok" start := time.Now() @@ -44,8 +45,8 @@ func instrumentPluginRequest(ctx context.Context, cfg *config.Cfg, pluginCtx *ba } elapsed := time.Since(start) - pluginRequestDuration.WithLabelValues(pluginCtx.PluginID, endpoint).Observe(float64(elapsed / time.Millisecond)) - pluginRequestCounter.WithLabelValues(pluginCtx.PluginID, endpoint, status).Inc() + pluginRequestDuration.WithLabelValues(pluginCtx.PluginID, endpoint, string(cfg.Target)).Observe(float64(elapsed / time.Millisecond)) + pluginRequestCounter.WithLabelValues(pluginCtx.PluginID, endpoint, status, string(cfg.Target)).Inc() if cfg.LogDatasourceRequests { logParams := []interface{}{ @@ -77,22 +78,27 @@ func instrumentPluginRequest(ctx context.Context, cfg *config.Cfg, pluginCtx *ba return err } +type Cfg struct { + LogDatasourceRequests bool + Target backendplugin.Target +} + // InstrumentCollectMetrics instruments collectMetrics. -func InstrumentCollectMetrics(ctx context.Context, req *backend.PluginContext, cfg *config.Cfg, fn func() error) error { +func InstrumentCollectMetrics(ctx context.Context, req *backend.PluginContext, cfg Cfg, fn func() error) error { return instrumentPluginRequest(ctx, cfg, req, "collectMetrics", fn) } // InstrumentCheckHealthRequest instruments checkHealth. -func InstrumentCheckHealthRequest(ctx context.Context, req *backend.PluginContext, cfg *config.Cfg, fn func() error) error { +func InstrumentCheckHealthRequest(ctx context.Context, req *backend.PluginContext, cfg Cfg, fn func() error) error { return instrumentPluginRequest(ctx, cfg, req, "checkHealth", fn) } // InstrumentCallResourceRequest instruments callResource. -func InstrumentCallResourceRequest(ctx context.Context, req *backend.PluginContext, cfg *config.Cfg, fn func() error) error { +func InstrumentCallResourceRequest(ctx context.Context, req *backend.PluginContext, cfg Cfg, fn func() error) error { return instrumentPluginRequest(ctx, cfg, req, "callResource", fn) } // InstrumentQueryDataRequest instruments success rate and latency of query data requests. -func InstrumentQueryDataRequest(ctx context.Context, req *backend.PluginContext, cfg *config.Cfg, fn func() error) error { +func InstrumentQueryDataRequest(ctx context.Context, req *backend.PluginContext, cfg Cfg, fn func() error) error { return instrumentPluginRequest(ctx, cfg, req, "queryData", fn) } diff --git a/pkg/plugins/manager/client/client.go b/pkg/plugins/manager/client/client.go index b9262ac41d7..4663cddef02 100644 --- a/pkg/plugins/manager/client/client.go +++ b/pkg/plugins/manager/client/client.go @@ -35,14 +35,17 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) return nil, fmt.Errorf("req cannot be nil") } - plugin, exists := s.plugin(ctx, req.PluginContext.PluginID) + p, exists := s.plugin(ctx, req.PluginContext.PluginID) if !exists { return nil, plugins.ErrPluginNotRegistered.Errorf("%w", backendplugin.ErrPluginNotRegistered) } var resp *backend.QueryDataResponse - err := instrumentation.InstrumentQueryDataRequest(ctx, &req.PluginContext, s.cfg, func() (innerErr error) { - resp, innerErr = plugin.QueryData(ctx, req) + err := instrumentation.InstrumentQueryDataRequest(ctx, &req.PluginContext, instrumentation.Cfg{ + LogDatasourceRequests: s.cfg.LogDatasourceRequests, + Target: p.Target(), + }, func() (innerErr error) { + resp, innerErr = p.QueryData(ctx, req) return }) @@ -83,7 +86,10 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq if !exists { return backendplugin.ErrPluginNotRegistered } - err := instrumentation.InstrumentCallResourceRequest(ctx, &req.PluginContext, s.cfg, func() error { + err := instrumentation.InstrumentCallResourceRequest(ctx, &req.PluginContext, instrumentation.Cfg{ + LogDatasourceRequests: s.cfg.LogDatasourceRequests, + Target: p.Target(), + }, func() error { removeConnectionHeaders(req.Headers) removeHopByHopHeaders(req.Headers) @@ -120,7 +126,10 @@ func (s *Service) CollectMetrics(ctx context.Context, req *backend.CollectMetric } var resp *backend.CollectMetricsResult - err := instrumentation.InstrumentCollectMetrics(ctx, &req.PluginContext, s.cfg, func() (innerErr error) { + err := instrumentation.InstrumentCollectMetrics(ctx, &req.PluginContext, instrumentation.Cfg{ + LogDatasourceRequests: s.cfg.LogDatasourceRequests, + Target: p.Target(), + }, func() (innerErr error) { resp, innerErr = p.CollectMetrics(ctx, req) return }) @@ -142,7 +151,10 @@ func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthReque } var resp *backend.CheckHealthResult - err := instrumentation.InstrumentCheckHealthRequest(ctx, &req.PluginContext, s.cfg, func() (innerErr error) { + err := instrumentation.InstrumentCheckHealthRequest(ctx, &req.PluginContext, instrumentation.Cfg{ + LogDatasourceRequests: s.cfg.LogDatasourceRequests, + Target: p.Target(), + }, func() (innerErr error) { resp, innerErr = p.CheckHealth(ctx, req) return }) diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 81bfbf11d6c..b9d1a210583 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -267,6 +267,16 @@ func (p *Plugin) Exited() bool { return false } +func (p *Plugin) Target() backendplugin.Target { + if !p.Backend { + return backendplugin.TargetNone + } + if p.client == nil { + return backendplugin.TargetUnknown + } + return p.client.Target() +} + func (p *Plugin) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { pluginClient, ok := p.Client() if !ok { diff --git a/pkg/tests/api/plugins/backendplugin/backendplugin_test.go b/pkg/tests/api/plugins/backendplugin/backendplugin_test.go index d0d97c8cf99..9b6f58b60a4 100644 --- a/pkg/tests/api/plugins/backendplugin/backendplugin_test.go +++ b/pkg/tests/api/plugins/backendplugin/backendplugin_test.go @@ -634,6 +634,10 @@ func (tp *testPlugin) IsDecommissioned() bool { return false } +func (tp *testPlugin) Target() backendplugin.Target { + return backendplugin.TargetNone +} + func (tp *testPlugin) CollectMetrics(_ context.Context, _ *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) { return nil, backendplugin.ErrMethodNotImplemented }