From 5c711bfb791035140ca844db89e82d1dceb38bbc Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 15 Jan 2020 13:10:48 +0100 Subject: [PATCH] Backend Plugins: Collect and expose metrics and plugin process health check (#21481) Adds support for collecting metrics from backend plugins and exposing them thru Grafana's Prometheus metrics endpoint. Enables to check health of backend plugin by using the route `/api/plugins//health`. Uses sdk v0.6.0. Closes #20984 --- go.mod | 3 +- go.sum | 6 +- pkg/infra/metrics/metrics.go | 13 + pkg/plugins/backendplugin/backend_plugin.go | 206 +++++ pkg/plugins/backendplugin/client.go | 17 +- .../backendplugin/collector/collector.go | 89 ++ pkg/plugins/backendplugin/manager.go | 60 +- pkg/plugins/plugins.go | 7 + .../grafana-plugin-sdk-go/backend/core.go | 47 - .../backend/core_grpc.go | 32 +- .../backend/core_sdk_adapter.go | 61 -- .../backend/diagnostics.go | 53 ++ .../backend/diagnostics_grpc.go | 51 + .../common.go => backend/handshake.go} | 2 +- .../backend/sdk_adapter.go | 91 ++ .../grafana-plugin-sdk-go/backend/serve.go | 61 +- .../backend/transform.go | 6 +- .../backend/transform_grpc.go | 4 +- .../backend/transform_sdk_adapter.go | 33 - .../genproto/pluginv2/backend.pb.go | 868 +++++++++--------- .../go-grpc-prometheus/.gitignore | 201 ++++ .../go-grpc-prometheus/CHANGELOG.md | 24 + .../grpc-ecosystem/go-grpc-prometheus/LICENSE | 201 ++++ .../go-grpc-prometheus/README.md | 247 +++++ .../go-grpc-prometheus/client.go | 39 + .../go-grpc-prometheus/client_metrics.go | 170 ++++ .../go-grpc-prometheus/client_reporter.go | 46 + .../go-grpc-prometheus/makefile | 16 + .../go-grpc-prometheus/metric_options.go | 41 + .../go-grpc-prometheus/server.go | 48 + .../go-grpc-prometheus/server_metrics.go | 185 ++++ .../go-grpc-prometheus/server_reporter.go | 46 + .../grpc-ecosystem/go-grpc-prometheus/util.go | 50 + vendor/modules.txt | 5 +- 34 files changed, 2406 insertions(+), 623 deletions(-) create mode 100644 pkg/plugins/backendplugin/collector/collector.go delete mode 100644 vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go create mode 100644 vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go create mode 100644 vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go rename vendor/github.com/grafana/grafana-plugin-sdk-go/{common/common.go => backend/handshake.go} (95%) create mode 100644 vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go delete mode 100644 vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go create mode 100644 vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go diff --git a/go.mod b/go.mod index 80d413dd66a..007132bddf3 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/gorilla/websocket v1.4.1 github.com/gosimple/slug v1.4.2 github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 - github.com/grafana/grafana-plugin-sdk-go v0.5.0 + github.com/grafana/grafana-plugin-sdk-go v0.6.0 github.com/hashicorp/go-hclog v0.8.0 github.com/hashicorp/go-plugin v1.0.1 github.com/hashicorp/go-version v1.1.0 @@ -74,6 +74,7 @@ require ( golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/tools v0.0.0-20191213221258-04c2e8eff935 // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 + google.golang.org/grpc v1.23.1 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/ini.v1 v1.46.0 diff --git a/go.sum b/go.sum index 4efa0137927..e3db1db93d1 100644 --- a/go.sum +++ b/go.sum @@ -123,8 +123,10 @@ github.com/gosimple/slug v1.4.2 h1:jDmprx3q/9Lfk4FkGZtvzDQ9Cj9eAmsjzeQGp24PeiQ= github.com/gosimple/slug v1.4.2/go.mod h1:ER78kgg1Mv0NQGlXiDe57DpCyfbNywXXZ9mIorhxAf0= github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SPdxCL9BChFTlyi0Khv64vdCW4TMna8+sxL7+Chx+Ag= github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4/go.mod h1:nc0XxBzjeGcrMltCDw269LoWF9S8ibhgxolCdA1R8To= -github.com/grafana/grafana-plugin-sdk-go v0.5.0 h1:qe60CcvhWn0H+CNoXgD6527GXcIJ78dU+pv1PmJypM8= -github.com/grafana/grafana-plugin-sdk-go v0.5.0/go.mod h1:78zFGQy3wwAtNE5imCeXklnD1xJ1VtIhF4JmxUIrwrw= +github.com/grafana/grafana-plugin-sdk-go v0.6.0 h1:rMMp84CdEKxI4i6SEpIUgsHgcKa1JdXDjLrDDw6QhXI= +github.com/grafana/grafana-plugin-sdk-go v0.6.0/go.mod h1:0eV4vNOYNZKOBbl23MieYiLa2y8M8S3D6ytLdggctqo= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0 h1:z3ollgGRg8RjfJH6UVBaG54R70GFd++QOkvnJH3VSBY= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= diff --git a/pkg/infra/metrics/metrics.go b/pkg/infra/metrics/metrics.go index 248b3e480e8..b41542053f4 100644 --- a/pkg/infra/metrics/metrics.go +++ b/pkg/infra/metrics/metrics.go @@ -148,6 +148,8 @@ var ( // grafanaBuildVersion is a metric with a constant '1' value labeled by version, revision, branch, and goversion from which Grafana was built grafanaBuildVersion *prometheus.GaugeVec + + grafanPluginBuildInfoDesc *prometheus.GaugeVec ) func init() { @@ -422,6 +424,12 @@ func init() { Help: "A metric with a constant '1' value labeled by version, revision, branch, and goversion from which Grafana was built", Namespace: exporterName, }, []string{"version", "revision", "branch", "goversion", "edition"}) + + grafanPluginBuildInfoDesc = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "plugin_build_info", + Help: "A metric with a constant '1' value labeled by pluginId, pluginType and version from which Grafana plugin was built", + Namespace: exporterName, + }, []string{"plugin_id", "plugin_type", "version"}) } // SetBuildInformation sets the build information for this binary @@ -434,6 +442,10 @@ func SetBuildInformation(version, revision, branch string) { grafanaBuildVersion.WithLabelValues(version, revision, branch, runtime.Version(), edition).Set(1) } +func SetPluginBuildInformation(pluginID, pluginType, version string) { + grafanPluginBuildInfoDesc.WithLabelValues(pluginID, pluginType, version).Set(1) +} + func initMetricVars() { prometheus.MustRegister( MInstanceStart, @@ -480,6 +492,7 @@ func initMetricVars() { StatsTotalActiveEditors, StatsTotalActiveAdmins, grafanaBuildVersion, + grafanPluginBuildInfoDesc, ) } diff --git a/pkg/plugins/backendplugin/backend_plugin.go b/pkg/plugins/backendplugin/backend_plugin.go index 089682f8cb5..26822d66d9b 100644 --- a/pkg/plugins/backendplugin/backend_plugin.go +++ b/pkg/plugins/backendplugin/backend_plugin.go @@ -1,14 +1,25 @@ package backendplugin import ( + "bytes" "context" "errors" + "fmt" + + "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/expfmt" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource" rendererV1 "github.com/grafana/grafana-plugin-model/go/renderer" backend "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/plugins/backendplugin/collector" + "github.com/grafana/grafana/pkg/util/errutil" plugin "github.com/hashicorp/go-plugin" + dto "github.com/prometheus/client_model/go" ) // BackendPlugin a registered backend plugin. @@ -20,6 +31,7 @@ type BackendPlugin struct { client *plugin.Client logger log.Logger startFns PluginStartFuncs + diagnostics backend.DiagnosticsPlugin } func (p *BackendPlugin) start(ctx context.Context) error { @@ -33,6 +45,11 @@ func (p *BackendPlugin) start(ctx context.Context) error { var client *Client if p.client.NegotiatedVersion() > 1 { + rawDiagnostics, err := rpcClient.Dispense("diagnostics") + if err != nil { + return err + } + rawBackend, err := rpcClient.Dispense("backend") if err != nil { return err @@ -43,6 +60,12 @@ func (p *BackendPlugin) start(ctx context.Context) error { return err } + if rawDiagnostics != nil { + if plugin, ok := rawDiagnostics.(backend.DiagnosticsPlugin); ok { + p.diagnostics = plugin + } + } + client = &Client{} if rawBackend != nil { if plugin, ok := rawBackend.(backend.BackendPlugin); ok { @@ -96,3 +119,186 @@ func (p *BackendPlugin) stop() error { } return nil } + +// supportsDiagnostics return whether backend plugin supports diagnostics like metrics and health check. +func (p *BackendPlugin) supportsDiagnostics() bool { + return p.diagnostics != nil +} + +// CollectMetrics implements the collector.Collector interface. +func (p *BackendPlugin) CollectMetrics(ctx context.Context, ch chan<- prometheus.Metric) error { + if p.diagnostics == nil { + return nil + } + + if p.client == nil || p.client.Exited() { + return nil + } + + res, err := p.diagnostics.CollectMetrics(ctx, &pluginv2.CollectMetrics_Request{}) + if err != nil { + if st, ok := status.FromError(err); ok { + if st.Code() == codes.Unimplemented { + return nil + } + } + + return err + } + + if res == nil || res.Metrics == nil || res.Metrics.Prometheus == nil { + return nil + } + + reader := bytes.NewReader(res.Metrics.Prometheus) + var parser expfmt.TextParser + families, err := parser.TextToMetricFamilies(reader) + if err != nil { + return errutil.Wrap("failed to parse collected metrics", err) + } + + for _, mf := range families { + if mf.Help == nil { + help := fmt.Sprintf("Metric read from %s plugin", p.id) + mf.Help = &help + } + } + + for _, mf := range families { + convertMetricFamily(p.id, mf, ch, p.logger) + } + + return nil +} + +func (p *BackendPlugin) checkHealth(ctx context.Context) (*pluginv2.CheckHealth_Response, error) { + if p.diagnostics == nil || p.client == nil || p.client.Exited() { + return &pluginv2.CheckHealth_Response{ + Status: pluginv2.CheckHealth_Response_UNKNOWN, + }, nil + } + + res, err := p.diagnostics.CheckHealth(ctx, &pluginv2.CheckHealth_Request{}) + if err != nil { + if st, ok := status.FromError(err); ok { + if st.Code() == codes.Unimplemented { + return &pluginv2.CheckHealth_Response{ + Status: pluginv2.CheckHealth_Response_UNKNOWN, + Info: "Health check not implemented", + }, nil + } + } + return nil, err + } + + return res, nil +} + +// convertMetricFamily converts metric family to prometheus.Metric. +// Copied from https://github.com/prometheus/node_exporter/blob/3ddc82c2d8d11eec53ed5faa8db969a1bb81f8bb/collector/textfile.go#L66-L165 +func convertMetricFamily(pluginID string, metricFamily *dto.MetricFamily, ch chan<- prometheus.Metric, logger log.Logger) { + var valType prometheus.ValueType + var val float64 + + allLabelNames := map[string]struct{}{} + for _, metric := range metricFamily.Metric { + labels := metric.GetLabel() + for _, label := range labels { + if _, ok := allLabelNames[label.GetName()]; !ok { + allLabelNames[label.GetName()] = struct{}{} + } + } + } + + for _, metric := range metricFamily.Metric { + if metric.TimestampMs != nil { + logger.Warn("Ignoring unsupported custom timestamp on metric", "metric", metric) + } + + labels := metric.GetLabel() + var names []string + var values []string + for _, label := range labels { + names = append(names, label.GetName()) + values = append(values, label.GetValue()) + } + names = append(names, "plugin_id") + values = append(values, pluginID) + + for k := range allLabelNames { + present := false + for _, name := range names { + if k == name { + present = true + break + } + } + if !present { + names = append(names, k) + values = append(values, "") + } + } + + metricName := prometheus.BuildFQName(collector.Namespace, "", *metricFamily.Name) + + metricType := metricFamily.GetType() + switch metricType { + case dto.MetricType_COUNTER: + valType = prometheus.CounterValue + val = metric.Counter.GetValue() + + case dto.MetricType_GAUGE: + valType = prometheus.GaugeValue + val = metric.Gauge.GetValue() + + case dto.MetricType_UNTYPED: + valType = prometheus.UntypedValue + val = metric.Untyped.GetValue() + + case dto.MetricType_SUMMARY: + quantiles := map[float64]float64{} + for _, q := range metric.Summary.Quantile { + quantiles[q.GetQuantile()] = q.GetValue() + } + ch <- prometheus.MustNewConstSummary( + prometheus.NewDesc( + metricName, + metricFamily.GetHelp(), + names, nil, + ), + metric.Summary.GetSampleCount(), + metric.Summary.GetSampleSum(), + quantiles, values..., + ) + case dto.MetricType_HISTOGRAM: + buckets := map[float64]uint64{} + for _, b := range metric.Histogram.Bucket { + buckets[b.GetUpperBound()] = b.GetCumulativeCount() + } + ch <- prometheus.MustNewConstHistogram( + prometheus.NewDesc( + metricName, + metricFamily.GetHelp(), + names, nil, + ), + metric.Histogram.GetSampleCount(), + metric.Histogram.GetSampleSum(), + buckets, values..., + ) + default: + logger.Error("unknown metric type", "type", metricType) + continue + } + + if metricType == dto.MetricType_GAUGE || metricType == dto.MetricType_COUNTER || metricType == dto.MetricType_UNTYPED { + ch <- prometheus.MustNewConstMetric( + prometheus.NewDesc( + metricName, + metricFamily.GetHelp(), + names, nil, + ), + valType, val, values..., + ) + } + } +} diff --git a/pkg/plugins/backendplugin/client.go b/pkg/plugins/backendplugin/client.go index 6d0c39e4238..efabe7b7452 100644 --- a/pkg/plugins/backendplugin/client.go +++ b/pkg/plugins/backendplugin/client.go @@ -8,7 +8,6 @@ import ( datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource" rendererV1 "github.com/grafana/grafana-plugin-model/go/renderer" backend "github.com/grafana/grafana-plugin-sdk-go/backend" - sdk "github.com/grafana/grafana-plugin-sdk-go/common" "github.com/hashicorp/go-plugin" ) @@ -27,8 +26,8 @@ var handshake = plugin.HandshakeConfig{ ProtocolVersion: DefaultProtocolVersion, // The magic cookie values should NEVER be changed. - MagicCookieKey: sdk.MagicCookieKey, - MagicCookieValue: sdk.MagicCookieValue, + MagicCookieKey: backend.MagicCookieKey, + MagicCookieValue: backend.MagicCookieValue, } func newClientConfig(executablePath string, logger log.Logger, versionedPlugins map[int]plugin.PluginSet) *plugin.ClientConfig { @@ -73,9 +72,10 @@ func NewBackendPluginDescriptor(pluginID, executablePath string, startFns Plugin DefaultProtocolVersion: { pluginID: &datasourceV1.DatasourcePluginImpl{}, }, - sdk.ProtocolVersion: { - "backend": &backend.CoreGRPCPlugin{}, - "transform": &backend.TransformGRPCPlugin{}, + backend.ProtocolVersion: { + "diagnostics": &backend.DiagnosticsGRPCPlugin{}, + "backend": &backend.CoreGRPCPlugin{}, + "transform": &backend.TransformGRPCPlugin{}, }, }, startFns: startFns, @@ -106,6 +106,7 @@ type LegacyClient struct { // Client client for communicating with a plugin using the current plugin protocol. type Client struct { - BackendPlugin backend.BackendPlugin - TransformPlugin backend.TransformPlugin + DiagnosticsPlugin backend.DiagnosticsPlugin + BackendPlugin backend.BackendPlugin + TransformPlugin backend.TransformPlugin } diff --git a/pkg/plugins/backendplugin/collector/collector.go b/pkg/plugins/backendplugin/collector/collector.go new file mode 100644 index 00000000000..dd9cfceaccb --- /dev/null +++ b/pkg/plugins/backendplugin/collector/collector.go @@ -0,0 +1,89 @@ +package collector + +import ( + "context" + "sync" + "time" + + "github.com/grafana/grafana/pkg/infra/log" + "github.com/prometheus/client_golang/prometheus" +) + +// Namespace collector metric namespace +const Namespace = "grafana_plugin" + +var ( + scrapeDurationDesc = prometheus.NewDesc( + prometheus.BuildFQName(Namespace, "scrape", "duration_seconds"), + "grafana_plugin: Duration of a plugin collector scrape.", + []string{"plugin_id"}, + nil, + ) + scrapeSuccessDesc = prometheus.NewDesc( + prometheus.BuildFQName(Namespace, "scrape", "success"), + "grafana_plugin: Whether a plugin collector succeeded.", + []string{"plugin_id"}, + nil, + ) +) + +// Collector is the interface a plugin collector has to implement. +type Collector interface { + // Get new metrics and expose them via prometheus registry. + CollectMetrics(ctx context.Context, ch chan<- prometheus.Metric) error +} + +// PluginCollector implements the prometheus.Collector interface. +type PluginCollector struct { + collectors map[string]Collector + logger log.Logger +} + +// NewPluginCollector creates a new PluginCollector.. +func NewPluginCollector() PluginCollector { + return PluginCollector{ + collectors: make(map[string]Collector), + logger: log.New("plugins.backend.collector"), + } +} + +func (pc PluginCollector) Register(pluginID string, c Collector) { + pc.collectors[pluginID] = c +} + +// Describe implements the prometheus.Collector interface. +func (pc PluginCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- scrapeDurationDesc + ch <- scrapeSuccessDesc +} + +// Collect implements the prometheus.Collector interface. +func (pc PluginCollector) Collect(ch chan<- prometheus.Metric) { + ctx := context.Background() + wg := sync.WaitGroup{} + wg.Add(len(pc.collectors)) + for name, c := range pc.collectors { + go func(name string, c Collector) { + execute(ctx, name, c, ch, pc.logger) + wg.Done() + }(name, c) + } + wg.Wait() +} + +func execute(ctx context.Context, pluginID string, c Collector, ch chan<- prometheus.Metric, logger log.Logger) { + begin := time.Now() + err := c.CollectMetrics(ctx, ch) + duration := time.Since(begin) + var success float64 + + if err != nil { + logger.Error("collector failed", "pluginId", pluginID, "took", duration, "error", err) + success = 0 + } else { + logger.Debug("collector succeeded", "pluginId", pluginID, "took", duration) + success = 1 + } + ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), pluginID) + ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, pluginID) +} diff --git a/pkg/plugins/backendplugin/manager.go b/pkg/plugins/backendplugin/manager.go index 55b0ea4f79d..4f94aaf9850 100644 --- a/pkg/plugins/backendplugin/manager.go +++ b/pkg/plugins/backendplugin/manager.go @@ -6,7 +6,14 @@ import ( "sync" "time" + "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/plugins/backendplugin/collector" "github.com/grafana/grafana/pkg/registry" plugin "github.com/hashicorp/go-plugin" "golang.org/x/xerrors" @@ -29,14 +36,21 @@ type Manager interface { } type manager struct { - pluginsMu sync.RWMutex - plugins map[string]*BackendPlugin - logger log.Logger + RouteRegister routing.RouteRegister `inject:""` + pluginsMu sync.RWMutex + plugins map[string]*BackendPlugin + pluginCollector collector.PluginCollector + logger log.Logger } func (m *manager) Init() error { m.plugins = make(map[string]*BackendPlugin) m.logger = log.New("plugins.backend") + m.pluginCollector = collector.NewPluginCollector() + prometheus.MustRegister(m.pluginCollector) + + m.RouteRegister.Get("/api/plugins/:pluginId/health", m.checkHealth) + return nil } @@ -85,6 +99,12 @@ func (m *manager) start(ctx context.Context) { if err := startPluginAndRestartKilledProcesses(ctx, p); err != nil { p.logger.Error("Failed to start plugin", "error", err) + continue + } + + if p.supportsDiagnostics() { + p.logger.Debug("Registering metrics collector") + m.pluginCollector.Register(p.id, p) } } } @@ -120,6 +140,40 @@ func (m *manager) stop() { } } +// checkHealth http handler for checking plugin health. +func (m *manager) checkHealth(c *models.ReqContext) { + pluginID := c.Params("pluginId") + m.pluginsMu.RLock() + p, registered := m.plugins[pluginID] + m.pluginsMu.RUnlock() + + if !registered || !p.supportsDiagnostics() { + c.JsonApiErr(404, "Plugin not found", nil) + return + } + + res, err := p.checkHealth(c.Req.Context()) + if err != nil { + p.logger.Error("Failed to check plugin health", "error", err) + c.JSON(503, map[string]interface{}{ + "status": pluginv2.CheckHealth_Response_ERROR.String(), + }) + return + } + + payload := map[string]interface{}{ + "status": res.Status.String(), + "info": res.Info, + } + + if res.Status != pluginv2.CheckHealth_Response_OK { + c.JSON(503, payload) + return + } + + c.JSON(200, payload) +} + func startPluginAndRestartKilledProcesses(ctx context.Context, p *BackendPlugin) error { if err := p.start(ctx); err != nil { return err diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 408ea696c4d..f325db4cf04 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -14,6 +14,7 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/setting" @@ -110,6 +111,12 @@ func (pm *PluginManager) Init() error { app.initApp() } + for _, p := range Plugins { + if !p.IsCorePlugin { + metrics.SetPluginBuildInformation(p.Id, p.Type, p.Info.Version) + } + } + return nil } diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go index 12ea8247843..901749c1d8a 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go @@ -191,42 +191,6 @@ func (rr *ResourceResponse) toProtobuf() *pluginv2.ResourceResponse { } } -// HealthStatus is the status of the plugin. -type HealthStatus int - -const ( - // HealthStatusUnknown means the status of the plugin is unknown. - HealthStatusUnknown HealthStatus = iota - // HealthStatusOk means the status of the plugin is good. - HealthStatusOk - // HealthStatusError means the plugin is in an error state. - HealthStatusError -) - -// func (ps HealthStatus) toProtobuf() pluginv2.CheckHealth_Response_HealthStatus { -// switch ps { -// case HealthStatusUnknown: -// return pluginv2.CheckHealth_Response_UNKNOWN -// case HealthStatusOk: -// return pluginv2.CheckHealth_Response_OK -// case HealthStatusError: -// return pluginv2.CheckHealth_Response_ERROR -// } -// panic("unsupported protobuf health status type in sdk") -// } - -type CheckHealthResult struct { - Status HealthStatus - Info string -} - -// func (res *CheckHealthResult) toProtobuf() *pluginv2.CheckHealth_Response { -// return &pluginv2.CheckHealth_Response{ -// Status: res.Status.toProtobuf(), -// Info: res.Info, -// } -// } - // DataQueryHandler handles data source queries. type DataQueryHandler interface { DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error) @@ -237,26 +201,15 @@ type ResourceHandler interface { Resource(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error) } -type CheckHealthHandler interface { - CheckHealth(ctx context.Context) (*CheckHealthResult, error) -} - -type DiagnosticsHandler interface { - CheckHealthHandler -} - // PluginHandlers is the collection of handlers that corresponds to the // grpc "service BackendPlugin". type PluginHandlers interface { - DiagnosticsHandler DataQueryHandler ResourceHandler } // BackendPlugin is the Grafana backend plugin interface. type BackendPlugin interface { - CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) - CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) } diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go index e7b7b48dc6a..674dfdb8033 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go @@ -8,16 +8,16 @@ import ( "google.golang.org/grpc" ) -// CoreGRPCPlugin implements the GRPPlugin interface from github.com/hashicorp/go-plugin. +// CoreGRPCPlugin implements the GRPCPlugin interface from github.com/hashicorp/go-plugin. type CoreGRPCPlugin struct { plugin.NetRPCUnsupportedPlugin plugin.GRPCPlugin - adapter *sdkAdapter + server pluginv2.CoreServer } func (p *CoreGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { pluginv2.RegisterCoreServer(s, &coreGRPCServer{ - adapter: p.adapter, + server: p.server, }) return nil } @@ -27,37 +27,21 @@ func (p *CoreGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBrok } type coreGRPCServer struct { - adapter *sdkAdapter + server pluginv2.CoreServer } -func (s *coreGRPCServer) CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { - return s.adapter.CollectMetrics(ctx, req) +func (s *coreGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { + return s.server.DataQuery(ctx, req) } -func (s *coreGRPCServer) CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { - return s.adapter.CheckHealth(ctx, req) -} - -func (m *coreGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { - return m.adapter.DataQuery(ctx, req) -} - -func (m *coreGRPCServer) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) { - return m.adapter.Resource(ctx, req) +func (s *coreGRPCServer) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) { + return s.server.Resource(ctx, req) } type coreGRPCClient struct { client pluginv2.CoreClient } -func (s *coreGRPCClient) CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { - return s.client.CollectMetrics(ctx, req) -} - -func (s *coreGRPCClient) CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { - return s.client.CheckHealth(ctx, req) -} - func (m *coreGRPCClient) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { return m.client.DataQuery(ctx, req) } diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go deleted file mode 100644 index f9da9b94149..00000000000 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go +++ /dev/null @@ -1,61 +0,0 @@ -package backend - -import ( - "bytes" - "context" - - "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/common/expfmt" -) - -// sdkAdapter adapter between protobuf and SDK interfaces. -type sdkAdapter struct { - handlers PluginHandlers -} - -func (a *sdkAdapter) CollectMetrics(ctx context.Context, protoReq *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { - metrics, err := prometheus.DefaultGatherer.Gather() - if err != nil { - return nil, err - } - - var buf bytes.Buffer - for _, m := range metrics { - _, err := expfmt.MetricFamilyToText(&buf, m) - if err != nil { - continue - } - } - - resp := &pluginv2.CollectMetrics_Response{ - Metrics: &pluginv2.CollectMetrics_Payload{ - Prometheus: buf.Bytes(), - }, - } - - return resp, nil -} - -func (a *sdkAdapter) CheckHealth(ctx context.Context, protoReq *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { - return &pluginv2.CheckHealth_Response{ - Status: pluginv2.CheckHealth_Response_OK, - }, nil -} - -func (a *sdkAdapter) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { - resp, err := a.handlers.DataQuery(ctx, dataQueryRequestFromProto(req)) - if err != nil { - return nil, err - } - - return resp.toProtobuf() -} - -func (a *sdkAdapter) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) { - res, err := a.handlers.Resource(ctx, resourceRequestFromProtobuf(req)) - if err != nil { - return nil, err - } - return res.toProtobuf(), nil -} diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go new file mode 100644 index 00000000000..56507ca49f9 --- /dev/null +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go @@ -0,0 +1,53 @@ +package backend + +import ( + "context" + + "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" +) + +// DiagnosticsPlugin is the Grafana diagnostics plugin interface. +type DiagnosticsPlugin interface { + CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) + CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) +} + +type CheckHealthHandler interface { + CheckHealth(ctx context.Context) (*CheckHealthResult, error) +} + +// HealthStatus is the status of the plugin. +type HealthStatus int + +const ( + // HealthStatusUnknown means the status of the plugin is unknown. + HealthStatusUnknown HealthStatus = iota + // HealthStatusOk means the status of the plugin is good. + HealthStatusOk + // HealthStatusError means the plugin is in an error state. + HealthStatusError +) + +func (ps HealthStatus) toProtobuf() pluginv2.CheckHealth_Response_HealthStatus { + switch ps { + case HealthStatusUnknown: + return pluginv2.CheckHealth_Response_UNKNOWN + case HealthStatusOk: + return pluginv2.CheckHealth_Response_OK + case HealthStatusError: + return pluginv2.CheckHealth_Response_ERROR + } + panic("unsupported protobuf health status type in sdk") +} + +type CheckHealthResult struct { + Status HealthStatus + Info string +} + +func (res *CheckHealthResult) toProtobuf() *pluginv2.CheckHealth_Response { + return &pluginv2.CheckHealth_Response{ + Status: res.Status.toProtobuf(), + Info: res.Info, + } +} diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go new file mode 100644 index 00000000000..d045f577e68 --- /dev/null +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go @@ -0,0 +1,51 @@ +package backend + +import ( + "context" + + "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" + plugin "github.com/hashicorp/go-plugin" + "google.golang.org/grpc" +) + +// DiagnosticsGRPCPlugin implements the GRPCPlugin interface from github.com/hashicorp/go-plugin. +type DiagnosticsGRPCPlugin struct { + plugin.NetRPCUnsupportedPlugin + plugin.GRPCPlugin + server pluginv2.DiagnosticsServer +} + +func (p *DiagnosticsGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { + pluginv2.RegisterDiagnosticsServer(s, &diagnosticsGRPCServer{ + server: p.server, + }) + return nil +} + +func (p *DiagnosticsGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { + return &diagnosticsGRPCClient{client: pluginv2.NewDiagnosticsClient(c)}, nil +} + +type diagnosticsGRPCServer struct { + server pluginv2.DiagnosticsServer +} + +func (s *diagnosticsGRPCServer) CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { + return s.server.CollectMetrics(ctx, req) +} + +func (s *diagnosticsGRPCServer) CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { + return s.server.CheckHealth(ctx, req) +} + +type diagnosticsGRPCClient struct { + client pluginv2.DiagnosticsClient +} + +func (s *diagnosticsGRPCClient) CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { + return s.client.CollectMetrics(ctx, req) +} + +func (s *diagnosticsGRPCClient) CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { + return s.client.CheckHealth(ctx, req) +} diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/common/common.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/handshake.go similarity index 95% rename from vendor/github.com/grafana/grafana-plugin-sdk-go/common/common.go rename to vendor/github.com/grafana/grafana-plugin-sdk-go/backend/handshake.go index 68e98f703d5..1803a5bd73d 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/common/common.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/handshake.go @@ -1,4 +1,4 @@ -package common +package backend import plugin "github.com/hashicorp/go-plugin" diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go new file mode 100644 index 00000000000..7b55b93b1e0 --- /dev/null +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go @@ -0,0 +1,91 @@ +package backend + +import ( + "bytes" + "context" + + "github.com/grafana/grafana-plugin-sdk-go/dataframe" + "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/expfmt" +) + +// sdkAdapter adapter between protobuf and SDK interfaces. +type sdkAdapter struct { + checkHealthHandler CheckHealthHandler + dataQueryHandler DataQueryHandler + resourceHandler ResourceHandler + transformDataHandler TransformDataHandler +} + +func (a *sdkAdapter) CollectMetrics(ctx context.Context, protoReq *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) { + mfs, err := prometheus.DefaultGatherer.Gather() + if err != nil { + return nil, err + } + + var buf bytes.Buffer + for _, mf := range mfs { + _, err := expfmt.MetricFamilyToText(&buf, mf) + if err != nil { + return nil, err + } + } + + return &pluginv2.CollectMetrics_Response{ + Metrics: &pluginv2.CollectMetrics_Payload{ + Prometheus: buf.Bytes(), + }, + }, nil +} + +func (a *sdkAdapter) CheckHealth(ctx context.Context, protoReq *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) { + if a.checkHealthHandler != nil { + res, err := a.checkHealthHandler.CheckHealth(ctx) + if err != nil { + return nil, err + } + return res.toProtobuf(), nil + } + + return &pluginv2.CheckHealth_Response{ + Status: pluginv2.CheckHealth_Response_OK, + }, nil +} + +func (a *sdkAdapter) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { + resp, err := a.dataQueryHandler.DataQuery(ctx, dataQueryRequestFromProto(req)) + if err != nil { + return nil, err + } + + return resp.toProtobuf() +} + +func (a *sdkAdapter) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) { + res, err := a.resourceHandler.Resource(ctx, resourceRequestFromProtobuf(req)) + if err != nil { + return nil, err + } + return res.toProtobuf(), nil +} + +func (a *sdkAdapter) TransformData(ctx context.Context, req *pluginv2.DataQueryRequest, callBack TransformCallBack) (*pluginv2.DataQueryResponse, error) { + resp, err := a.transformDataHandler.TransformData(ctx, dataQueryRequestFromProto(req), &transformCallBackWrapper{callBack}) + if err != nil { + return nil, err + } + + encodedFrames := make([][]byte, len(resp.Frames)) + for i, frame := range resp.Frames { + encodedFrames[i], err = dataframe.MarshalArrow(frame) + if err != nil { + return nil, err + } + } + + return &pluginv2.DataQueryResponse{ + Frames: encodedFrames, + Metadata: resp.Metadata, + }, nil +} diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go index ed981d71c52..f5060759184 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go @@ -1,37 +1,68 @@ package backend import ( - "github.com/grafana/grafana-plugin-sdk-go/common" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" plugin "github.com/hashicorp/go-plugin" + "google.golang.org/grpc" ) -// Serve starts serving the datasource plugin over gRPC. -func Serve(backendHandlers PluginHandlers, transformHandlers TransformHandlers) error { +type ServeOpts struct { + CheckHealthHandler CheckHealthHandler + DataQueryHandler DataQueryHandler + ResourceHandler ResourceHandler + TransformDataHandler TransformDataHandler + + // GRPCServer factory method for creating GRPC server. + // If nil, the default one will be used. + GRPCServer func(options []grpc.ServerOption) *grpc.Server +} + +// Serve starts serving the plugin over gRPC. +func Serve(opts ServeOpts) error { versionedPlugins := make(map[int]plugin.PluginSet) - pSet := make(plugin.PluginSet) - if backendHandlers != nil { + + sdkAdapter := &sdkAdapter{ + checkHealthHandler: opts.CheckHealthHandler, + dataQueryHandler: opts.DataQueryHandler, + resourceHandler: opts.ResourceHandler, + transformDataHandler: opts.TransformDataHandler, + } + + pSet["diagnostics"] = &DiagnosticsGRPCPlugin{ + server: sdkAdapter, + } + + if opts.DataQueryHandler != nil || opts.ResourceHandler != nil { pSet["backend"] = &CoreGRPCPlugin{ - adapter: &sdkAdapter{ - handlers: backendHandlers, - }, + server: sdkAdapter, } } - if transformHandlers != nil { + if opts.TransformDataHandler != nil { pSet["transform"] = &TransformGRPCPlugin{ - adapter: &transformSDKAdapter{ - handlers: transformHandlers, - }, + adapter: sdkAdapter, } } - versionedPlugins[common.ProtocolVersion] = pSet + versionedPlugins[ProtocolVersion] = pSet + + if opts.GRPCServer == nil { + // opts.GRPCServer = plugin.DefaultGRPCServer + // hack for now to add grpc prometheuc server interceptor + opts.GRPCServer = func(serverOptions []grpc.ServerOption) *grpc.Server { + mergedOptions := serverOptions + mergedOptions = append(mergedOptions, grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor)) + server := grpc.NewServer(mergedOptions...) + grpc_prometheus.Register(server) + return server + } + } plugin.Serve(&plugin.ServeConfig{ - HandshakeConfig: common.Handshake, + HandshakeConfig: Handshake, VersionedPlugins: versionedPlugins, - GRPCServer: plugin.DefaultGRPCServer, + GRPCServer: opts.GRPCServer, }) return nil diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go index 19ecb24fa11..4a2c532793d 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go @@ -7,11 +7,11 @@ import ( ) type TransformHandlers interface { - TransformDataQueryHandler + TransformDataHandler } -type TransformDataQueryHandler interface { - DataQuery(ctx context.Context, req *DataQueryRequest, callBack TransformCallBackHandler) (*DataQueryResponse, error) +type TransformDataHandler interface { + TransformData(ctx context.Context, req *DataQueryRequest, callBack TransformCallBackHandler) (*DataQueryResponse, error) } // Callback diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go index 460a7fccd48..8506eec0d7d 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go @@ -15,7 +15,7 @@ import ( type TransformGRPCPlugin struct { plugin.NetRPCUnsupportedPlugin plugin.GRPCPlugin - adapter *transformSDKAdapter + adapter *sdkAdapter } func (p *TransformGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { @@ -32,7 +32,7 @@ func (p *TransformGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRP type transformGRPCServer struct { broker *plugin.GRPCBroker - adapter *transformSDKAdapter + adapter *sdkAdapter } func (t *transformGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) { diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go deleted file mode 100644 index 28ae6c6b0b1..00000000000 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go +++ /dev/null @@ -1,33 +0,0 @@ -package backend - -import ( - "context" - - "github.com/grafana/grafana-plugin-sdk-go/dataframe" - "github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2" -) - -// transformSDKAdapter adapter between protobuf and SDK interfaces. -type transformSDKAdapter struct { - handlers TransformHandlers -} - -func (a *transformSDKAdapter) TransformData(ctx context.Context, req *pluginv2.DataQueryRequest, callBack TransformCallBack) (*pluginv2.DataQueryResponse, error) { - resp, err := a.handlers.DataQuery(ctx, dataQueryRequestFromProto(req), &transformCallBackWrapper{callBack}) - if err != nil { - return nil, err - } - - encodedFrames := make([][]byte, len(resp.Frames)) - for i, frame := range resp.Frames { - encodedFrames[i], err = dataframe.MarshalArrow(frame) - if err != nil { - return nil, err - } - } - - return &pluginv2.DataQueryResponse{ - Frames: encodedFrames, - Metadata: resp.Metadata, - }, nil -} diff --git a/vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go b/vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go index faa780b48fa..ecc59d503b1 100644 --- a/vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go +++ b/vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go @@ -50,7 +50,7 @@ func (x CheckHealth_Response_HealthStatus) String() string { } func (CheckHealth_Response_HealthStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{2, 1, 0} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8, 1, 0} } type PluginConfig struct { @@ -140,255 +140,6 @@ func (m *PluginConfig) GetDecryptedSecureJsonData() map[string]string { return nil } -type CollectMetrics struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CollectMetrics) Reset() { *m = CollectMetrics{} } -func (m *CollectMetrics) String() string { return proto.CompactTextString(m) } -func (*CollectMetrics) ProtoMessage() {} -func (*CollectMetrics) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{1} -} - -func (m *CollectMetrics) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CollectMetrics.Unmarshal(m, b) -} -func (m *CollectMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CollectMetrics.Marshal(b, m, deterministic) -} -func (m *CollectMetrics) XXX_Merge(src proto.Message) { - xxx_messageInfo_CollectMetrics.Merge(m, src) -} -func (m *CollectMetrics) XXX_Size() int { - return xxx_messageInfo_CollectMetrics.Size(m) -} -func (m *CollectMetrics) XXX_DiscardUnknown() { - xxx_messageInfo_CollectMetrics.DiscardUnknown(m) -} - -var xxx_messageInfo_CollectMetrics proto.InternalMessageInfo - -type CollectMetrics_Request struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CollectMetrics_Request) Reset() { *m = CollectMetrics_Request{} } -func (m *CollectMetrics_Request) String() string { return proto.CompactTextString(m) } -func (*CollectMetrics_Request) ProtoMessage() {} -func (*CollectMetrics_Request) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{1, 0} -} - -func (m *CollectMetrics_Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CollectMetrics_Request.Unmarshal(m, b) -} -func (m *CollectMetrics_Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CollectMetrics_Request.Marshal(b, m, deterministic) -} -func (m *CollectMetrics_Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_CollectMetrics_Request.Merge(m, src) -} -func (m *CollectMetrics_Request) XXX_Size() int { - return xxx_messageInfo_CollectMetrics_Request.Size(m) -} -func (m *CollectMetrics_Request) XXX_DiscardUnknown() { - xxx_messageInfo_CollectMetrics_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_CollectMetrics_Request proto.InternalMessageInfo - -type CollectMetrics_Payload struct { - Prometheus []byte `protobuf:"bytes,1,opt,name=prometheus,proto3" json:"prometheus,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CollectMetrics_Payload) Reset() { *m = CollectMetrics_Payload{} } -func (m *CollectMetrics_Payload) String() string { return proto.CompactTextString(m) } -func (*CollectMetrics_Payload) ProtoMessage() {} -func (*CollectMetrics_Payload) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{1, 1} -} - -func (m *CollectMetrics_Payload) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CollectMetrics_Payload.Unmarshal(m, b) -} -func (m *CollectMetrics_Payload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CollectMetrics_Payload.Marshal(b, m, deterministic) -} -func (m *CollectMetrics_Payload) XXX_Merge(src proto.Message) { - xxx_messageInfo_CollectMetrics_Payload.Merge(m, src) -} -func (m *CollectMetrics_Payload) XXX_Size() int { - return xxx_messageInfo_CollectMetrics_Payload.Size(m) -} -func (m *CollectMetrics_Payload) XXX_DiscardUnknown() { - xxx_messageInfo_CollectMetrics_Payload.DiscardUnknown(m) -} - -var xxx_messageInfo_CollectMetrics_Payload proto.InternalMessageInfo - -func (m *CollectMetrics_Payload) GetPrometheus() []byte { - if m != nil { - return m.Prometheus - } - return nil -} - -type CollectMetrics_Response struct { - Metrics *CollectMetrics_Payload `protobuf:"bytes,1,opt,name=metrics,proto3" json:"metrics,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CollectMetrics_Response) Reset() { *m = CollectMetrics_Response{} } -func (m *CollectMetrics_Response) String() string { return proto.CompactTextString(m) } -func (*CollectMetrics_Response) ProtoMessage() {} -func (*CollectMetrics_Response) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{1, 2} -} - -func (m *CollectMetrics_Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CollectMetrics_Response.Unmarshal(m, b) -} -func (m *CollectMetrics_Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CollectMetrics_Response.Marshal(b, m, deterministic) -} -func (m *CollectMetrics_Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_CollectMetrics_Response.Merge(m, src) -} -func (m *CollectMetrics_Response) XXX_Size() int { - return xxx_messageInfo_CollectMetrics_Response.Size(m) -} -func (m *CollectMetrics_Response) XXX_DiscardUnknown() { - xxx_messageInfo_CollectMetrics_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_CollectMetrics_Response proto.InternalMessageInfo - -func (m *CollectMetrics_Response) GetMetrics() *CollectMetrics_Payload { - if m != nil { - return m.Metrics - } - return nil -} - -type CheckHealth struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CheckHealth) Reset() { *m = CheckHealth{} } -func (m *CheckHealth) String() string { return proto.CompactTextString(m) } -func (*CheckHealth) ProtoMessage() {} -func (*CheckHealth) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{2} -} - -func (m *CheckHealth) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CheckHealth.Unmarshal(m, b) -} -func (m *CheckHealth) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CheckHealth.Marshal(b, m, deterministic) -} -func (m *CheckHealth) XXX_Merge(src proto.Message) { - xxx_messageInfo_CheckHealth.Merge(m, src) -} -func (m *CheckHealth) XXX_Size() int { - return xxx_messageInfo_CheckHealth.Size(m) -} -func (m *CheckHealth) XXX_DiscardUnknown() { - xxx_messageInfo_CheckHealth.DiscardUnknown(m) -} - -var xxx_messageInfo_CheckHealth proto.InternalMessageInfo - -type CheckHealth_Request struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CheckHealth_Request) Reset() { *m = CheckHealth_Request{} } -func (m *CheckHealth_Request) String() string { return proto.CompactTextString(m) } -func (*CheckHealth_Request) ProtoMessage() {} -func (*CheckHealth_Request) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{2, 0} -} - -func (m *CheckHealth_Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CheckHealth_Request.Unmarshal(m, b) -} -func (m *CheckHealth_Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CheckHealth_Request.Marshal(b, m, deterministic) -} -func (m *CheckHealth_Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_CheckHealth_Request.Merge(m, src) -} -func (m *CheckHealth_Request) XXX_Size() int { - return xxx_messageInfo_CheckHealth_Request.Size(m) -} -func (m *CheckHealth_Request) XXX_DiscardUnknown() { - xxx_messageInfo_CheckHealth_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_CheckHealth_Request proto.InternalMessageInfo - -type CheckHealth_Response struct { - Status CheckHealth_Response_HealthStatus `protobuf:"varint,1,opt,name=status,proto3,enum=pluginv2.CheckHealth_Response_HealthStatus" json:"status,omitempty"` - Info string `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CheckHealth_Response) Reset() { *m = CheckHealth_Response{} } -func (m *CheckHealth_Response) String() string { return proto.CompactTextString(m) } -func (*CheckHealth_Response) ProtoMessage() {} -func (*CheckHealth_Response) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{2, 1} -} - -func (m *CheckHealth_Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CheckHealth_Response.Unmarshal(m, b) -} -func (m *CheckHealth_Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CheckHealth_Response.Marshal(b, m, deterministic) -} -func (m *CheckHealth_Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_CheckHealth_Response.Merge(m, src) -} -func (m *CheckHealth_Response) XXX_Size() int { - return xxx_messageInfo_CheckHealth_Response.Size(m) -} -func (m *CheckHealth_Response) XXX_DiscardUnknown() { - xxx_messageInfo_CheckHealth_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_CheckHealth_Response proto.InternalMessageInfo - -func (m *CheckHealth_Response) GetStatus() CheckHealth_Response_HealthStatus { - if m != nil { - return m.Status - } - return CheckHealth_Response_UNKNOWN -} - -func (m *CheckHealth_Response) GetInfo() string { - if m != nil { - return m.Info - } - return "" -} - type TimeRange struct { FromEpochMS int64 `protobuf:"varint,1,opt,name=fromEpochMS,proto3" json:"fromEpochMS,omitempty"` ToEpochMS int64 `protobuf:"varint,2,opt,name=toEpochMS,proto3" json:"toEpochMS,omitempty"` @@ -401,7 +152,7 @@ func (m *TimeRange) Reset() { *m = TimeRange{} } func (m *TimeRange) String() string { return proto.CompactTextString(m) } func (*TimeRange) ProtoMessage() {} func (*TimeRange) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{3} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{1} } func (m *TimeRange) XXX_Unmarshal(b []byte) error { @@ -451,7 +202,7 @@ func (m *DataQuery) Reset() { *m = DataQuery{} } func (m *DataQuery) String() string { return proto.CompactTextString(m) } func (*DataQuery) ProtoMessage() {} func (*DataQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{4} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{2} } func (m *DataQuery) XXX_Unmarshal(b []byte) error { @@ -523,7 +274,7 @@ func (m *DataQueryRequest) Reset() { *m = DataQueryRequest{} } func (m *DataQueryRequest) String() string { return proto.CompactTextString(m) } func (*DataQueryRequest) ProtoMessage() {} func (*DataQueryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{3} } func (m *DataQueryRequest) XXX_Unmarshal(b []byte) error { @@ -580,7 +331,7 @@ func (m *DataQueryResponse) Reset() { *m = DataQueryResponse{} } func (m *DataQueryResponse) String() string { return proto.CompactTextString(m) } func (*DataQueryResponse) ProtoMessage() {} func (*DataQueryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{4} } func (m *DataQueryResponse) XXX_Unmarshal(b []byte) error { @@ -632,7 +383,7 @@ func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (m *ResourceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { @@ -701,7 +452,7 @@ func (m *ResourceResponse) Reset() { *m = ResourceResponse{} } func (m *ResourceResponse) String() string { return proto.CompactTextString(m) } func (*ResourceResponse) ProtoMessage() {} func (*ResourceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8} + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6} } func (m *ResourceResponse) XXX_Unmarshal(b []byte) error { @@ -743,6 +494,255 @@ func (m *ResourceResponse) GetBody() []byte { return nil } +type CollectMetrics struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CollectMetrics) Reset() { *m = CollectMetrics{} } +func (m *CollectMetrics) String() string { return proto.CompactTextString(m) } +func (*CollectMetrics) ProtoMessage() {} +func (*CollectMetrics) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7} +} + +func (m *CollectMetrics) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CollectMetrics.Unmarshal(m, b) +} +func (m *CollectMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CollectMetrics.Marshal(b, m, deterministic) +} +func (m *CollectMetrics) XXX_Merge(src proto.Message) { + xxx_messageInfo_CollectMetrics.Merge(m, src) +} +func (m *CollectMetrics) XXX_Size() int { + return xxx_messageInfo_CollectMetrics.Size(m) +} +func (m *CollectMetrics) XXX_DiscardUnknown() { + xxx_messageInfo_CollectMetrics.DiscardUnknown(m) +} + +var xxx_messageInfo_CollectMetrics proto.InternalMessageInfo + +type CollectMetrics_Request struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CollectMetrics_Request) Reset() { *m = CollectMetrics_Request{} } +func (m *CollectMetrics_Request) String() string { return proto.CompactTextString(m) } +func (*CollectMetrics_Request) ProtoMessage() {} +func (*CollectMetrics_Request) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 0} +} + +func (m *CollectMetrics_Request) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CollectMetrics_Request.Unmarshal(m, b) +} +func (m *CollectMetrics_Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CollectMetrics_Request.Marshal(b, m, deterministic) +} +func (m *CollectMetrics_Request) XXX_Merge(src proto.Message) { + xxx_messageInfo_CollectMetrics_Request.Merge(m, src) +} +func (m *CollectMetrics_Request) XXX_Size() int { + return xxx_messageInfo_CollectMetrics_Request.Size(m) +} +func (m *CollectMetrics_Request) XXX_DiscardUnknown() { + xxx_messageInfo_CollectMetrics_Request.DiscardUnknown(m) +} + +var xxx_messageInfo_CollectMetrics_Request proto.InternalMessageInfo + +type CollectMetrics_Payload struct { + Prometheus []byte `protobuf:"bytes,1,opt,name=prometheus,proto3" json:"prometheus,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CollectMetrics_Payload) Reset() { *m = CollectMetrics_Payload{} } +func (m *CollectMetrics_Payload) String() string { return proto.CompactTextString(m) } +func (*CollectMetrics_Payload) ProtoMessage() {} +func (*CollectMetrics_Payload) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 1} +} + +func (m *CollectMetrics_Payload) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CollectMetrics_Payload.Unmarshal(m, b) +} +func (m *CollectMetrics_Payload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CollectMetrics_Payload.Marshal(b, m, deterministic) +} +func (m *CollectMetrics_Payload) XXX_Merge(src proto.Message) { + xxx_messageInfo_CollectMetrics_Payload.Merge(m, src) +} +func (m *CollectMetrics_Payload) XXX_Size() int { + return xxx_messageInfo_CollectMetrics_Payload.Size(m) +} +func (m *CollectMetrics_Payload) XXX_DiscardUnknown() { + xxx_messageInfo_CollectMetrics_Payload.DiscardUnknown(m) +} + +var xxx_messageInfo_CollectMetrics_Payload proto.InternalMessageInfo + +func (m *CollectMetrics_Payload) GetPrometheus() []byte { + if m != nil { + return m.Prometheus + } + return nil +} + +type CollectMetrics_Response struct { + Metrics *CollectMetrics_Payload `protobuf:"bytes,1,opt,name=metrics,proto3" json:"metrics,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CollectMetrics_Response) Reset() { *m = CollectMetrics_Response{} } +func (m *CollectMetrics_Response) String() string { return proto.CompactTextString(m) } +func (*CollectMetrics_Response) ProtoMessage() {} +func (*CollectMetrics_Response) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 2} +} + +func (m *CollectMetrics_Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CollectMetrics_Response.Unmarshal(m, b) +} +func (m *CollectMetrics_Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CollectMetrics_Response.Marshal(b, m, deterministic) +} +func (m *CollectMetrics_Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_CollectMetrics_Response.Merge(m, src) +} +func (m *CollectMetrics_Response) XXX_Size() int { + return xxx_messageInfo_CollectMetrics_Response.Size(m) +} +func (m *CollectMetrics_Response) XXX_DiscardUnknown() { + xxx_messageInfo_CollectMetrics_Response.DiscardUnknown(m) +} + +var xxx_messageInfo_CollectMetrics_Response proto.InternalMessageInfo + +func (m *CollectMetrics_Response) GetMetrics() *CollectMetrics_Payload { + if m != nil { + return m.Metrics + } + return nil +} + +type CheckHealth struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckHealth) Reset() { *m = CheckHealth{} } +func (m *CheckHealth) String() string { return proto.CompactTextString(m) } +func (*CheckHealth) ProtoMessage() {} +func (*CheckHealth) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8} +} + +func (m *CheckHealth) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckHealth.Unmarshal(m, b) +} +func (m *CheckHealth) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckHealth.Marshal(b, m, deterministic) +} +func (m *CheckHealth) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckHealth.Merge(m, src) +} +func (m *CheckHealth) XXX_Size() int { + return xxx_messageInfo_CheckHealth.Size(m) +} +func (m *CheckHealth) XXX_DiscardUnknown() { + xxx_messageInfo_CheckHealth.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckHealth proto.InternalMessageInfo + +type CheckHealth_Request struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckHealth_Request) Reset() { *m = CheckHealth_Request{} } +func (m *CheckHealth_Request) String() string { return proto.CompactTextString(m) } +func (*CheckHealth_Request) ProtoMessage() {} +func (*CheckHealth_Request) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8, 0} +} + +func (m *CheckHealth_Request) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckHealth_Request.Unmarshal(m, b) +} +func (m *CheckHealth_Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckHealth_Request.Marshal(b, m, deterministic) +} +func (m *CheckHealth_Request) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckHealth_Request.Merge(m, src) +} +func (m *CheckHealth_Request) XXX_Size() int { + return xxx_messageInfo_CheckHealth_Request.Size(m) +} +func (m *CheckHealth_Request) XXX_DiscardUnknown() { + xxx_messageInfo_CheckHealth_Request.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckHealth_Request proto.InternalMessageInfo + +type CheckHealth_Response struct { + Status CheckHealth_Response_HealthStatus `protobuf:"varint,1,opt,name=status,proto3,enum=pluginv2.CheckHealth_Response_HealthStatus" json:"status,omitempty"` + Info string `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckHealth_Response) Reset() { *m = CheckHealth_Response{} } +func (m *CheckHealth_Response) String() string { return proto.CompactTextString(m) } +func (*CheckHealth_Response) ProtoMessage() {} +func (*CheckHealth_Response) Descriptor() ([]byte, []int) { + return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8, 1} +} + +func (m *CheckHealth_Response) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CheckHealth_Response.Unmarshal(m, b) +} +func (m *CheckHealth_Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CheckHealth_Response.Marshal(b, m, deterministic) +} +func (m *CheckHealth_Response) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckHealth_Response.Merge(m, src) +} +func (m *CheckHealth_Response) XXX_Size() int { + return xxx_messageInfo_CheckHealth_Response.Size(m) +} +func (m *CheckHealth_Response) XXX_DiscardUnknown() { + xxx_messageInfo_CheckHealth_Response.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckHealth_Response proto.InternalMessageInfo + +func (m *CheckHealth_Response) GetStatus() CheckHealth_Response_HealthStatus { + if m != nil { + return m.Status + } + return CheckHealth_Response_UNKNOWN +} + +func (m *CheckHealth_Response) GetInfo() string { + if m != nil { + return m.Info + } + return "" +} + type StreamingRequest struct { PluginId int64 `protobuf:"varint,1,opt,name=pluginId,proto3" json:"pluginId,omitempty"` // Environment info @@ -922,7 +922,6 @@ type RenderRequest struct { FilePath string `protobuf:"bytes,7,opt,name=filePath,proto3" json:"filePath,omitempty"` RenderKey string `protobuf:"bytes,8,opt,name=renderKey,proto3" json:"renderKey,omitempty"` Domain string `protobuf:"bytes,9,opt,name=domain,proto3" json:"domain,omitempty"` - Debug bool `protobuf:"varint,10,opt,name=debug,proto3" json:"debug,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1016,13 +1015,6 @@ func (m *RenderRequest) GetDomain() string { return "" } -func (m *RenderRequest) GetDebug() bool { - if m != nil { - return m.Debug - } - return false -} - type RenderResponse struct { Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -1066,13 +1058,6 @@ func init() { proto.RegisterEnum("pluginv2.CheckHealth_Response_HealthStatus", CheckHealth_Response_HealthStatus_name, CheckHealth_Response_HealthStatus_value) proto.RegisterType((*PluginConfig)(nil), "pluginv2.PluginConfig") proto.RegisterMapType((map[string]string)(nil), "pluginv2.PluginConfig.DecryptedSecureJsonDataEntry") - proto.RegisterType((*CollectMetrics)(nil), "pluginv2.CollectMetrics") - proto.RegisterType((*CollectMetrics_Request)(nil), "pluginv2.CollectMetrics.Request") - proto.RegisterType((*CollectMetrics_Payload)(nil), "pluginv2.CollectMetrics.Payload") - proto.RegisterType((*CollectMetrics_Response)(nil), "pluginv2.CollectMetrics.Response") - proto.RegisterType((*CheckHealth)(nil), "pluginv2.CheckHealth") - proto.RegisterType((*CheckHealth_Request)(nil), "pluginv2.CheckHealth.Request") - proto.RegisterType((*CheckHealth_Response)(nil), "pluginv2.CheckHealth.Response") proto.RegisterType((*TimeRange)(nil), "pluginv2.TimeRange") proto.RegisterType((*DataQuery)(nil), "pluginv2.DataQuery") proto.RegisterType((*DataQueryRequest)(nil), "pluginv2.DataQueryRequest") @@ -1083,6 +1068,13 @@ func init() { proto.RegisterMapType((map[string]string)(nil), "pluginv2.ResourceRequest.HeadersEntry") proto.RegisterType((*ResourceResponse)(nil), "pluginv2.ResourceResponse") proto.RegisterMapType((map[string]string)(nil), "pluginv2.ResourceResponse.HeadersEntry") + proto.RegisterType((*CollectMetrics)(nil), "pluginv2.CollectMetrics") + proto.RegisterType((*CollectMetrics_Request)(nil), "pluginv2.CollectMetrics.Request") + proto.RegisterType((*CollectMetrics_Payload)(nil), "pluginv2.CollectMetrics.Payload") + proto.RegisterType((*CollectMetrics_Response)(nil), "pluginv2.CollectMetrics.Response") + proto.RegisterType((*CheckHealth)(nil), "pluginv2.CheckHealth") + proto.RegisterType((*CheckHealth_Request)(nil), "pluginv2.CheckHealth.Request") + proto.RegisterType((*CheckHealth_Response)(nil), "pluginv2.CheckHealth.Response") proto.RegisterType((*StreamingRequest)(nil), "pluginv2.StreamingRequest") proto.RegisterMapType((map[string]string)(nil), "pluginv2.StreamingRequest.HeadersEntry") proto.RegisterType((*StreamingMessage)(nil), "pluginv2.StreamingMessage") @@ -1095,82 +1087,82 @@ func init() { proto.RegisterFile("backend.proto", fileDescriptor_5ab9ba5b8d8b2ba var fileDescriptor_5ab9ba5b8d8b2ba5 = []byte{ // 1207 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x72, 0x1b, 0xc5, - 0x13, 0xff, 0xaf, 0x64, 0x7d, 0xb5, 0x6c, 0x47, 0x99, 0xb8, 0x92, 0xfd, 0x6f, 0x42, 0xca, 0xa8, - 0xa8, 0xe0, 0x14, 0x85, 0x02, 0xca, 0x85, 0x4a, 0xaa, 0x80, 0x20, 0x9b, 0x90, 0x18, 0x27, 0xca, - 0x38, 0x29, 0x8a, 0x0b, 0x55, 0xa3, 0xdd, 0x96, 0xb4, 0x78, 0x77, 0x47, 0x99, 0x9d, 0x35, 0x88, - 0x37, 0xe0, 0xc2, 0x85, 0x1b, 0x0f, 0x01, 0x17, 0x2e, 0x3c, 0x00, 0x8f, 0xc0, 0x7b, 0x70, 0xe3, - 0x08, 0x35, 0xb3, 0x33, 0xab, 0xb5, 0xca, 0x52, 0x55, 0x88, 0x0f, 0xdc, 0xba, 0x7b, 0x7b, 0x7e, - 0xd3, 0xdf, 0x3d, 0x0b, 0x5b, 0x23, 0xe6, 0x9f, 0x60, 0x12, 0xf4, 0x66, 0x82, 0x4b, 0x4e, 0x9a, - 0xb3, 0x28, 0x9b, 0x84, 0xc9, 0x69, 0xdf, 0xbb, 0x3e, 0xe1, 0x7c, 0x12, 0xe1, 0x1d, 0x2d, 0x1f, - 0x65, 0xe3, 0x3b, 0x18, 0xcf, 0xe4, 0x3c, 0x57, 0xeb, 0xfe, 0x5e, 0x81, 0xcd, 0xa1, 0xd6, 0x1c, - 0xf0, 0x64, 0x1c, 0x4e, 0xc8, 0x36, 0x54, 0xc2, 0xc0, 0x75, 0x76, 0x9d, 0xbd, 0x2a, 0xad, 0x84, - 0x01, 0xd9, 0x81, 0x1a, 0x17, 0x93, 0x47, 0x81, 0x5b, 0xd1, 0xa2, 0x9c, 0x21, 0x04, 0x36, 0x12, - 0x16, 0xa3, 0x5b, 0xdd, 0x75, 0xf6, 0x5a, 0x54, 0xd3, 0x4a, 0x26, 0xe7, 0x33, 0x74, 0x37, 0x72, - 0x99, 0xa2, 0x49, 0x07, 0xaa, 0x99, 0x88, 0xdc, 0x9a, 0x16, 0x29, 0x92, 0x78, 0xd0, 0xfc, 0x3a, - 0xe5, 0xc9, 0x3e, 0x93, 0xcc, 0xad, 0x6b, 0x71, 0xc1, 0x93, 0x18, 0xae, 0x05, 0xe8, 0x8b, 0xf9, - 0x4c, 0x62, 0x70, 0x8c, 0x7e, 0x26, 0xf0, 0xb1, 0x55, 0x6d, 0xec, 0x56, 0xf7, 0xda, 0xfd, 0xbb, - 0x3d, 0xeb, 0x55, 0xaf, 0x6c, 0x74, 0x6f, 0xff, 0xfc, 0x53, 0x07, 0x89, 0x14, 0x73, 0xba, 0x0a, - 0xd3, 0x7b, 0x0c, 0x37, 0xd6, 0x1d, 0x54, 0xc6, 0x9f, 0xe0, 0x5c, 0xc7, 0xa2, 0x45, 0x15, 0xa9, - 0x82, 0x71, 0xca, 0xa2, 0x0c, 0x75, 0x30, 0x5a, 0x34, 0x67, 0xee, 0x55, 0x3e, 0x70, 0xba, 0x3f, - 0x38, 0xb0, 0x3d, 0xe0, 0x51, 0x84, 0xbe, 0x3c, 0x42, 0x29, 0x42, 0x3f, 0xf5, 0x5a, 0xd0, 0xa0, - 0xf8, 0x32, 0xc3, 0x54, 0x7a, 0xb7, 0xa1, 0x31, 0x64, 0xf3, 0x88, 0xb3, 0x80, 0xdc, 0x04, 0x98, - 0x09, 0x1e, 0xa3, 0x9c, 0x62, 0x96, 0x6a, 0xec, 0x4d, 0x5a, 0x92, 0x78, 0x9f, 0x42, 0x93, 0x62, - 0x3a, 0xe3, 0x49, 0x8a, 0xe4, 0x1e, 0x34, 0xe2, 0x1c, 0x4c, 0x2b, 0xb6, 0xfb, 0xbb, 0x0b, 0xff, - 0xcf, 0x5e, 0xd6, 0x33, 0xf0, 0xd4, 0x1e, 0xe8, 0xfe, 0xec, 0x40, 0x7b, 0x30, 0x45, 0xff, 0xe4, - 0x33, 0x64, 0x91, 0x9c, 0x96, 0xad, 0xf9, 0xd1, 0x29, 0xdd, 0x31, 0x80, 0x7a, 0x2a, 0x99, 0x34, - 0xb6, 0x6c, 0xf7, 0xdf, 0x29, 0x5d, 0xb1, 0x38, 0xde, 0xb3, 0xfa, 0xbd, 0x9c, 0x3f, 0xd6, 0x47, - 0xa8, 0x39, 0xaa, 0x52, 0x1f, 0x26, 0x63, 0x6e, 0xc2, 0xa2, 0xe9, 0x6e, 0x0f, 0x36, 0xcb, 0xba, - 0xa4, 0x0d, 0x8d, 0x17, 0x4f, 0x0e, 0x9f, 0x3c, 0xfd, 0xe2, 0x49, 0xe7, 0x7f, 0xa4, 0x0e, 0x95, - 0xa7, 0x87, 0x1d, 0x87, 0xb4, 0xa0, 0x76, 0x40, 0xe9, 0x53, 0xda, 0xa9, 0x74, 0x0f, 0xa1, 0xf5, - 0x3c, 0x8c, 0x91, 0xb2, 0x64, 0x82, 0x64, 0x17, 0xda, 0x63, 0xc1, 0xe3, 0x83, 0x19, 0xf7, 0xa7, - 0x47, 0xc7, 0xa6, 0x1c, 0xcb, 0x22, 0x72, 0x03, 0x5a, 0x92, 0xdb, 0xef, 0x79, 0x6d, 0x2e, 0x04, - 0xca, 0xfb, 0x96, 0x4a, 0xe4, 0xb3, 0x0c, 0x85, 0x4e, 0x9b, 0xc0, 0xf1, 0xa3, 0xc0, 0xa4, 0x32, - 0x67, 0xc8, 0x5b, 0xb0, 0x15, 0xb3, 0x6f, 0x95, 0xd6, 0x90, 0x87, 0x89, 0x4c, 0x0d, 0xca, 0x59, - 0xa1, 0xca, 0x57, 0x98, 0x48, 0x14, 0xa7, 0x2c, 0x3a, 0x3a, 0xd6, 0xf5, 0x5e, 0xa5, 0x25, 0x09, - 0x79, 0x1f, 0x5a, 0xd2, 0x9a, 0xad, 0x4b, 0xbf, 0xdd, 0xbf, 0xb2, 0x08, 0x61, 0xe1, 0x11, 0x5d, - 0x68, 0xa9, 0x68, 0xa9, 0x92, 0xd7, 0x5d, 0xb1, 0x49, 0x35, 0xdd, 0xfd, 0xd3, 0x81, 0x4e, 0x61, - 0xb0, 0x49, 0x14, 0xe9, 0x41, 0xdd, 0xd7, 0x05, 0x6e, 0xd2, 0x7f, 0xf5, 0xfc, 0xf2, 0xa7, 0x46, - 0x8b, 0x3c, 0x80, 0xc6, 0x14, 0x59, 0x80, 0x42, 0xf9, 0xa2, 0xfa, 0xe5, 0xed, 0xc5, 0x81, 0x65, - 0x70, 0x95, 0x48, 0xa5, 0x99, 0xf7, 0x88, 0x3d, 0x47, 0xde, 0x85, 0xc6, 0xcb, 0x0c, 0x45, 0x88, - 0xa9, 0x5b, 0xd5, 0x10, 0x57, 0xce, 0x83, 0xb0, 0x3a, 0xde, 0x3d, 0x9d, 0xe4, 0x02, 0xe7, 0x95, - 0x5a, 0xe6, 0x17, 0x07, 0x2e, 0x97, 0xac, 0x32, 0xf5, 0x78, 0x15, 0xea, 0x63, 0xc1, 0x62, 0x54, - 0xf5, 0x58, 0xdd, 0xdb, 0xa4, 0x86, 0x23, 0x07, 0xd0, 0x8c, 0x51, 0xb2, 0x40, 0x0d, 0x83, 0xdc, - 0xb9, 0xdb, 0xe7, 0x3a, 0x67, 0xca, 0xf4, 0xc8, 0xe8, 0xe6, 0xee, 0x15, 0x47, 0xbd, 0xfb, 0xb0, - 0x75, 0xe6, 0xd3, 0x2b, 0x59, 0xfc, 0xb7, 0x03, 0x97, 0x28, 0xa6, 0x3c, 0x13, 0x3e, 0xfe, 0xdb, - 0x1c, 0x7d, 0xbc, 0x9c, 0xa3, 0x5b, 0x8b, 0x03, 0x4b, 0xd8, 0x2b, 0x52, 0x74, 0x15, 0xea, 0x6a, - 0x58, 0xf0, 0xc0, 0x4c, 0x5f, 0xc3, 0xa9, 0xb2, 0x9a, 0x31, 0x39, 0xb5, 0xf3, 0x57, 0xd1, 0x4a, - 0x36, 0xe2, 0xc1, 0xdc, 0x96, 0x9a, 0xa2, 0x5f, 0x2b, 0x67, 0xbf, 0x39, 0xd0, 0x59, 0x58, 0x69, - 0x52, 0x46, 0x60, 0xc3, 0xe7, 0x01, 0x6a, 0x84, 0x1a, 0xd5, 0xf4, 0xda, 0x52, 0x5c, 0x06, 0x58, - 0xe1, 0xa7, 0xb5, 0xbd, 0x7a, 0x41, 0xb6, 0xff, 0xe5, 0x40, 0xe7, 0x58, 0x0a, 0x64, 0x71, 0x98, - 0x4c, 0x6c, 0xfa, 0x3c, 0x30, 0x8b, 0xf2, 0x91, 0x5d, 0x7a, 0x05, 0xbf, 0xd6, 0x87, 0x65, 0xa0, - 0x15, 0x3e, 0xec, 0x40, 0x4d, 0xf2, 0x59, 0xe8, 0x9b, 0x54, 0xe5, 0x4c, 0xe1, 0x99, 0xc9, 0x94, - 0xa2, 0xd5, 0x9c, 0x49, 0xb3, 0x51, 0xea, 0x8b, 0x70, 0x84, 0x81, 0xce, 0x57, 0x93, 0x96, 0x24, - 0xaf, 0xe5, 0xf9, 0x57, 0x25, 0xc7, 0x8f, 0x30, 0x4d, 0xd9, 0x04, 0xd7, 0x3a, 0x5e, 0x58, 0x5d, - 0x29, 0x5b, 0xed, 0xaa, 0x6d, 0xa4, 0x0f, 0x1b, 0x6f, 0x2c, 0xdb, 0xbd, 0x05, 0xdb, 0x05, 0xfe, - 0x20, 0xe2, 0x29, 0x2a, 0x04, 0x9f, 0x67, 0x89, 0x34, 0xd0, 0x39, 0xd3, 0xfd, 0xbe, 0x02, 0x5b, - 0x14, 0x93, 0x00, 0x85, 0x0d, 0xbf, 0x79, 0x1f, 0x38, 0x8b, 0xf7, 0xc1, 0x0e, 0xd4, 0xbe, 0x09, - 0x03, 0x39, 0xd5, 0x77, 0xd7, 0x68, 0xce, 0xa8, 0x9a, 0x9f, 0x62, 0x38, 0x99, 0x4a, 0x7d, 0x75, - 0x8d, 0x1a, 0x4e, 0xd9, 0xa4, 0xe6, 0x2a, 0xcf, 0xa4, 0x0e, 0x66, 0x8d, 0x5a, 0x56, 0xf9, 0xa7, - 0xc8, 0xef, 0x78, 0x82, 0xe6, 0xf9, 0x51, 0xf0, 0xea, 0x1b, 0x26, 0x3e, 0x0f, 0xc2, 0x64, 0x62, - 0xdf, 0x20, 0x96, 0x57, 0xdf, 0xc6, 0x61, 0x84, 0x43, 0xd5, 0x49, 0x8d, 0xfc, 0x9b, 0xe5, 0xd5, - 0xce, 0x11, 0xda, 0xfc, 0x43, 0x9c, 0xbb, 0x4d, 0xfd, 0x71, 0x21, 0x50, 0x36, 0x06, 0x3c, 0x66, - 0x61, 0xe2, 0xb6, 0xf2, 0xbe, 0xcc, 0x39, 0xe5, 0x51, 0x80, 0xa3, 0x6c, 0xe2, 0x82, 0x4e, 0x6a, - 0xce, 0xa8, 0x98, 0xd9, 0x50, 0x98, 0x36, 0xda, 0x81, 0x1a, 0x0a, 0xc1, 0x85, 0xdd, 0x52, 0x9a, - 0xe9, 0xff, 0x5a, 0x81, 0x8d, 0x01, 0x17, 0x48, 0x5e, 0x2c, 0x3f, 0x30, 0xc8, 0xea, 0xd7, 0x80, - 0xdd, 0xf4, 0x6f, 0xae, 0xd1, 0x30, 0xb7, 0x7e, 0x7e, 0xe6, 0x99, 0x40, 0xde, 0x58, 0xb5, 0xfe, - 0x73, 0xc0, 0x9b, 0xeb, 0x5f, 0x07, 0xe4, 0x81, 0x7e, 0x59, 0xe8, 0xee, 0x26, 0xff, 0x5f, 0x39, - 0xd8, 0x3c, 0x6f, 0xf5, 0x30, 0x20, 0xfb, 0xe5, 0xcd, 0xed, 0xad, 0x5e, 0x60, 0xde, 0xf5, 0x35, - 0xf3, 0xbf, 0xff, 0x93, 0x03, 0x97, 0x1e, 0x0a, 0x36, 0x66, 0x09, 0x1b, 0x46, 0x4c, 0x8e, 0xb9, - 0x88, 0xff, 0x3b, 0xc6, 0x3d, 0x83, 0xd6, 0x73, 0xc1, 0x92, 0x54, 0x5b, 0x75, 0x31, 0x90, 0x5f, - 0xc2, 0xe5, 0x02, 0x72, 0xc0, 0xa2, 0xe8, 0x13, 0xe6, 0x9f, 0x5c, 0x10, 0xf4, 0x1f, 0x0e, 0x5c, - 0x2a, 0xda, 0x3b, 0xdf, 0x69, 0xe4, 0x23, 0x68, 0x0c, 0x78, 0x92, 0xa0, 0x2f, 0xc9, 0x8a, 0x85, - 0x57, 0x0e, 0xe3, 0xf2, 0xf0, 0x79, 0xcf, 0x51, 0xb3, 0x75, 0x28, 0xb8, 0x8f, 0x69, 0x4a, 0xbc, - 0xd5, 0x53, 0x75, 0x1d, 0x08, 0xf9, 0x10, 0x60, 0x3f, 0x4c, 0xfd, 0xc2, 0x8c, 0xfc, 0x37, 0xa7, - 0x67, 0x7f, 0x73, 0x7a, 0x07, 0xea, 0x37, 0xc7, 0x73, 0xcf, 0x41, 0xd0, 0x33, 0xaa, 0xff, 0x50, - 0x95, 0x83, 0xea, 0x40, 0x14, 0xe4, 0x3e, 0xd4, 0x73, 0x9a, 0x5c, 0x2b, 0x67, 0xbf, 0x34, 0xaa, - 0xca, 0x40, 0x67, 0x1b, 0x77, 0x54, 0xd7, 0x57, 0xde, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x84, - 0x8c, 0xdf, 0x9f, 0x82, 0x0d, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xdd, 0x8e, 0xdb, 0x44, + 0x14, 0xc6, 0xc9, 0xe6, 0xef, 0x64, 0x77, 0x9b, 0x4e, 0x57, 0xad, 0x71, 0x4b, 0x15, 0x22, 0x54, + 0xb6, 0x42, 0xb8, 0x90, 0xde, 0xa0, 0x56, 0xe2, 0x2f, 0xbb, 0xf4, 0x67, 0xd9, 0x6e, 0x3a, 0xdb, + 0x0a, 0x71, 0x83, 0x34, 0xb1, 0x4f, 0x12, 0xb3, 0xb6, 0x27, 0x1d, 0x8f, 0x17, 0xc2, 0x43, 0xc0, + 0x05, 0x77, 0x3c, 0x04, 0x48, 0xdc, 0xf1, 0x00, 0x3c, 0x02, 0xef, 0x81, 0xc4, 0x05, 0x97, 0xa0, + 0x19, 0x8f, 0x1d, 0x6f, 0xb4, 0x89, 0x54, 0xba, 0x17, 0xdc, 0x9d, 0x73, 0x3c, 0xe7, 0x9b, 0xef, + 0xfc, 0xcc, 0x99, 0x31, 0x6c, 0x8d, 0x98, 0x77, 0x82, 0xb1, 0xef, 0xce, 0x04, 0x97, 0x9c, 0x34, + 0x67, 0x61, 0x3a, 0x09, 0xe2, 0xd3, 0xbe, 0x73, 0x7d, 0xc2, 0xf9, 0x24, 0xc4, 0x3b, 0xda, 0x3e, + 0x4a, 0xc7, 0x77, 0x30, 0x9a, 0xc9, 0x79, 0xb6, 0xac, 0xf7, 0x7b, 0x05, 0x36, 0x87, 0x7a, 0xe5, + 0x80, 0xc7, 0xe3, 0x60, 0x42, 0xb6, 0xa1, 0x12, 0xf8, 0xb6, 0xd5, 0xb5, 0x76, 0xab, 0xb4, 0x12, + 0xf8, 0x64, 0x07, 0x6a, 0x5c, 0x4c, 0x1e, 0xf9, 0x76, 0x45, 0x9b, 0x32, 0x85, 0x10, 0xd8, 0x88, + 0x59, 0x84, 0x76, 0xb5, 0x6b, 0xed, 0xb6, 0xa8, 0x96, 0x95, 0x4d, 0xce, 0x67, 0x68, 0x6f, 0x64, + 0x36, 0x25, 0x93, 0x0e, 0x54, 0x53, 0x11, 0xda, 0x35, 0x6d, 0x52, 0x22, 0x71, 0xa0, 0xf9, 0x75, + 0xc2, 0xe3, 0x3d, 0x26, 0x99, 0x5d, 0xd7, 0xe6, 0x42, 0x27, 0x11, 0x5c, 0xf3, 0xd1, 0x13, 0xf3, + 0x99, 0x44, 0xff, 0x18, 0xbd, 0x54, 0xe0, 0xe3, 0x7c, 0x69, 0xa3, 0x5b, 0xdd, 0x6d, 0xf7, 0xef, + 0xba, 0x79, 0x54, 0x6e, 0x99, 0xb4, 0xbb, 0x77, 0xbe, 0xd7, 0x7e, 0x2c, 0xc5, 0x9c, 0xae, 0xc2, + 0x74, 0x1e, 0xc3, 0x8d, 0x75, 0x8e, 0x8a, 0xfc, 0x09, 0xce, 0x75, 0x2e, 0x5a, 0x54, 0x89, 0x2a, + 0x19, 0xa7, 0x2c, 0x4c, 0x51, 0x27, 0xa3, 0x45, 0x33, 0xe5, 0x5e, 0xe5, 0x03, 0xab, 0x77, 0x00, + 0xad, 0x67, 0x41, 0x84, 0x94, 0xc5, 0x13, 0x24, 0x5d, 0x68, 0x8f, 0x05, 0x8f, 0xf6, 0x67, 0xdc, + 0x9b, 0x1e, 0x1e, 0x9b, 0x64, 0x96, 0x4d, 0xe4, 0x06, 0xb4, 0x24, 0xcf, 0xbf, 0x67, 0x99, 0x5d, + 0x18, 0x7a, 0x3f, 0x5b, 0xd0, 0x52, 0x34, 0x9e, 0xa6, 0x28, 0xf4, 0xa6, 0x02, 0xc7, 0x8f, 0x7c, + 0x43, 0x24, 0x53, 0xc8, 0x5b, 0xb0, 0x15, 0xb1, 0x6f, 0xd5, 0xaa, 0x21, 0x0f, 0x62, 0x99, 0x18, + 0x94, 0xb3, 0x46, 0x72, 0x13, 0x20, 0x88, 0x25, 0x8a, 0x53, 0x16, 0x1e, 0x1e, 0xeb, 0x6a, 0x55, + 0x69, 0xc9, 0x42, 0xde, 0x87, 0x96, 0xcc, 0x69, 0xeb, 0xc2, 0xb5, 0xfb, 0x57, 0x16, 0x39, 0x2e, + 0x22, 0xa2, 0x8b, 0x55, 0xaa, 0xcc, 0xaa, 0x60, 0xba, 0xa6, 0x9b, 0x54, 0xcb, 0xbd, 0x3f, 0x2d, + 0xe8, 0x14, 0x84, 0x29, 0xbe, 0x48, 0x31, 0x91, 0xc4, 0x85, 0xba, 0xa7, 0xcb, 0xa3, 0x89, 0xb7, + 0xfb, 0x57, 0xcf, 0x2f, 0x1e, 0x35, 0xab, 0xc8, 0x27, 0xd0, 0x98, 0x22, 0xf3, 0x51, 0xa8, 0x58, + 0x54, 0xb5, 0xdf, 0x5e, 0x38, 0x2c, 0x83, 0xbb, 0x0f, 0xb3, 0x95, 0x59, 0x85, 0x73, 0x3f, 0xf2, + 0x2e, 0x34, 0x5e, 0xa4, 0x28, 0x02, 0x4c, 0xec, 0xaa, 0x86, 0xb8, 0x72, 0x1e, 0x44, 0xbe, 0xc6, + 0xb9, 0x07, 0x9b, 0x65, 0x9c, 0x97, 0x2a, 0xf8, 0x2f, 0x16, 0x5c, 0x2e, 0xb1, 0x4a, 0x66, 0x3c, + 0x4e, 0x90, 0x5c, 0x85, 0xfa, 0x58, 0xb0, 0x08, 0x13, 0xdb, 0xea, 0x56, 0x77, 0x37, 0xa9, 0xd1, + 0xc8, 0x3e, 0x34, 0x23, 0x94, 0xcc, 0x57, 0xad, 0x9c, 0x05, 0x77, 0xfb, 0xdc, 0xe0, 0x32, 0x18, + 0xf7, 0xd0, 0xac, 0xcd, 0xc2, 0x2b, 0x5c, 0x9d, 0xfb, 0xb0, 0x75, 0xe6, 0xd3, 0x4b, 0x31, 0xfe, + 0xc7, 0x82, 0x4b, 0x14, 0x13, 0x9e, 0x0a, 0x0f, 0xff, 0x6b, 0x8d, 0x3e, 0x5e, 0xae, 0xd1, 0xad, + 0x85, 0xc3, 0x12, 0xf6, 0x8a, 0x12, 0x5d, 0x85, 0x7a, 0x84, 0x72, 0xca, 0x7d, 0x33, 0x3b, 0x8c, + 0xa6, 0xda, 0x6a, 0xc6, 0xe4, 0x34, 0x9f, 0x1e, 0x4a, 0x56, 0xb6, 0x11, 0xf7, 0xe7, 0x79, 0xab, + 0x29, 0xf9, 0x95, 0x6a, 0xf6, 0x9b, 0x05, 0x9d, 0x05, 0x4b, 0x53, 0x32, 0x02, 0x1b, 0x1e, 0xf7, + 0x51, 0x23, 0xd4, 0xa8, 0x96, 0xd7, 0xb6, 0xe2, 0x32, 0xc0, 0x8a, 0x38, 0x73, 0xee, 0xd5, 0x0b, + 0xe2, 0xfe, 0xbd, 0x05, 0xdb, 0x03, 0x1e, 0x86, 0xe8, 0xc9, 0x43, 0x94, 0x22, 0xf0, 0x12, 0xa7, + 0x05, 0x0d, 0x93, 0x6b, 0xe7, 0x36, 0x34, 0x86, 0x6c, 0x1e, 0x72, 0xe6, 0xab, 0x23, 0x3f, 0x13, + 0x5c, 0x65, 0x15, 0xd3, 0x44, 0x63, 0x6f, 0xd2, 0x92, 0xc5, 0xf9, 0x0c, 0x9a, 0x45, 0xec, 0xf7, + 0xa0, 0x11, 0x65, 0x60, 0xa6, 0xfe, 0xdd, 0x45, 0x9c, 0x67, 0x37, 0x73, 0x0d, 0x3c, 0xcd, 0x1d, + 0xd4, 0x90, 0x6a, 0x0f, 0xa6, 0xe8, 0x9d, 0x3c, 0x44, 0x16, 0xca, 0x69, 0x99, 0xcd, 0x8f, 0x56, + 0x69, 0x8f, 0x01, 0xd4, 0x13, 0xc9, 0xa4, 0xe1, 0xb2, 0xdd, 0x7f, 0xa7, 0xb4, 0xc5, 0xc2, 0xdd, + 0x2d, 0xa7, 0x33, 0x94, 0xd3, 0x63, 0xed, 0x42, 0x8d, 0xab, 0xca, 0x66, 0x10, 0x8f, 0xb9, 0x49, + 0x8b, 0x96, 0x7b, 0xae, 0xce, 0x66, 0xb1, 0x96, 0xb4, 0xa1, 0xf1, 0xfc, 0xc9, 0xc1, 0x93, 0xa3, + 0x2f, 0x9e, 0x74, 0x5e, 0x23, 0x75, 0xa8, 0x1c, 0x1d, 0x74, 0x2c, 0xd2, 0x82, 0xda, 0x3e, 0xa5, + 0x47, 0xb4, 0x53, 0xe9, 0xfd, 0x6d, 0x41, 0xe7, 0x58, 0x0a, 0x64, 0x51, 0x10, 0x4f, 0xf2, 0x03, + 0xe0, 0x80, 0xb9, 0x28, 0x1f, 0xe5, 0x97, 0x5e, 0xa1, 0xaf, 0xed, 0x82, 0x65, 0xa0, 0x15, 0x5d, + 0xb0, 0x03, 0x35, 0xc9, 0x67, 0x81, 0x67, 0x9a, 0x3d, 0x53, 0x8a, 0xde, 0x30, 0xbd, 0xae, 0x64, + 0x55, 0xb6, 0x24, 0x1d, 0x25, 0x9e, 0x08, 0x46, 0xe8, 0xeb, 0x8e, 0x6f, 0xd2, 0x92, 0xe5, 0x95, + 0x7a, 0xe7, 0xab, 0x52, 0xe0, 0x87, 0x98, 0x24, 0x6c, 0x82, 0x6b, 0x03, 0x2f, 0x58, 0x57, 0xca, + 0xac, 0x6d, 0xd5, 0x2c, 0xda, 0xd9, 0x44, 0x93, 0xab, 0xbd, 0x5b, 0xb0, 0x5d, 0xe0, 0x0f, 0x42, + 0x9e, 0xa0, 0x42, 0xf0, 0x78, 0x1a, 0x4b, 0x03, 0x9d, 0x29, 0xbd, 0xbf, 0x2c, 0xd8, 0xa2, 0x18, + 0xfb, 0x28, 0xf2, 0xf4, 0x9b, 0xf7, 0x81, 0xb5, 0x78, 0x1f, 0xec, 0x40, 0xed, 0x9b, 0xc0, 0x97, + 0x53, 0xbd, 0x77, 0x8d, 0x66, 0x8a, 0x9a, 0x1a, 0x53, 0x0c, 0x26, 0x53, 0xa9, 0xb7, 0xae, 0x51, + 0xa3, 0x29, 0x4e, 0xea, 0x66, 0xe2, 0xa9, 0xd4, 0xc9, 0xac, 0xd1, 0x5c, 0x55, 0xf1, 0x29, 0xf1, + 0x3b, 0x1e, 0xa3, 0x79, 0x7e, 0x14, 0xba, 0xfa, 0x86, 0xb1, 0xc7, 0xfd, 0x20, 0x9e, 0xe4, 0x6f, + 0x90, 0x5c, 0x57, 0xdf, 0xc6, 0x41, 0x88, 0x43, 0x35, 0x8b, 0x1a, 0xd9, 0xb7, 0x5c, 0x57, 0xb7, + 0xb6, 0xd0, 0xf4, 0x0f, 0x70, 0x6e, 0x37, 0xf5, 0xc7, 0x85, 0x41, 0x71, 0xf4, 0x79, 0xc4, 0x82, + 0xd8, 0x6e, 0x65, 0x93, 0x2d, 0xd3, 0x54, 0x76, 0xf2, 0xa0, 0xcd, 0x91, 0xd8, 0x81, 0x1a, 0x0a, + 0xc1, 0x45, 0x7e, 0xa3, 0x6b, 0xa5, 0xff, 0x83, 0x05, 0x1b, 0x03, 0x2e, 0xd4, 0xf4, 0x69, 0xe6, + 0x43, 0x86, 0xbc, 0xbe, 0x72, 0xbe, 0x3a, 0xce, 0xea, 0x99, 0x44, 0xf6, 0xca, 0x0f, 0x08, 0x67, + 0xf5, 0x3d, 0xea, 0x5c, 0x5f, 0x73, 0x0d, 0xf5, 0x7f, 0xb5, 0xa0, 0xbd, 0x17, 0xb0, 0x49, 0xcc, + 0x13, 0x19, 0x78, 0x09, 0x79, 0xbe, 0x3c, 0x82, 0xc8, 0xea, 0x79, 0x91, 0x6f, 0xf0, 0xe6, 0x9a, + 0x15, 0x86, 0xec, 0xe7, 0x67, 0x06, 0x09, 0x79, 0x63, 0xd5, 0x80, 0xc8, 0x00, 0x6f, 0xae, 0x9f, + 0x1f, 0xfd, 0x9f, 0x2c, 0xb8, 0xf4, 0x40, 0xb0, 0x31, 0x8b, 0xd9, 0x30, 0x64, 0x72, 0xcc, 0x45, + 0xf4, 0xff, 0xc9, 0xe8, 0x53, 0x68, 0x3d, 0x13, 0x2c, 0x4e, 0x34, 0xab, 0x8b, 0x81, 0xfc, 0x12, + 0x2e, 0x17, 0x90, 0x03, 0x16, 0x86, 0x9f, 0x32, 0xef, 0xe4, 0x82, 0xa0, 0xff, 0xb0, 0xe0, 0x52, + 0x71, 0xb0, 0xb3, 0xf7, 0x00, 0xf9, 0x08, 0x1a, 0x03, 0x1e, 0xc7, 0xe8, 0x49, 0xb2, 0xe2, 0xb1, + 0x50, 0x4e, 0xe3, 0xf2, 0xd8, 0x79, 0xcf, 0x52, 0x53, 0x75, 0x28, 0xb8, 0x87, 0x49, 0x42, 0x9c, + 0xd5, 0xf3, 0x74, 0x1d, 0x08, 0xf9, 0x10, 0x60, 0x2f, 0x48, 0xbc, 0x82, 0x46, 0xf6, 0x83, 0xe3, + 0xe6, 0x3f, 0x38, 0xee, 0xbe, 0xfa, 0xc1, 0x71, 0xec, 0x73, 0x10, 0xf4, 0x74, 0xea, 0x3f, 0x50, + 0xed, 0xa0, 0x4e, 0x24, 0x0a, 0x72, 0x1f, 0xea, 0x99, 0x4c, 0xae, 0x95, 0xab, 0x5f, 0x1a, 0x52, + 0x65, 0xa0, 0xb3, 0x07, 0x79, 0x54, 0xd7, 0x5b, 0xde, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0xf3, + 0x10, 0x26, 0xf4, 0x7c, 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1185,9 +1177,6 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type CoreClient interface { - // Diagnostics - CollectMetrics(ctx context.Context, in *CollectMetrics_Request, opts ...grpc.CallOption) (*CollectMetrics_Response, error) - CheckHealth(ctx context.Context, in *CheckHealth_Request, opts ...grpc.CallOption) (*CheckHealth_Response, error) // HTTP Style request Resource(ctx context.Context, in *ResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error) // Well typed query interface @@ -1202,24 +1191,6 @@ func NewCoreClient(cc *grpc.ClientConn) CoreClient { return &coreClient{cc} } -func (c *coreClient) CollectMetrics(ctx context.Context, in *CollectMetrics_Request, opts ...grpc.CallOption) (*CollectMetrics_Response, error) { - out := new(CollectMetrics_Response) - err := c.cc.Invoke(ctx, "/pluginv2.Core/CollectMetrics", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *coreClient) CheckHealth(ctx context.Context, in *CheckHealth_Request, opts ...grpc.CallOption) (*CheckHealth_Response, error) { - out := new(CheckHealth_Response) - err := c.cc.Invoke(ctx, "/pluginv2.Core/CheckHealth", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *coreClient) Resource(ctx context.Context, in *ResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error) { out := new(ResourceResponse) err := c.cc.Invoke(ctx, "/pluginv2.Core/Resource", in, out, opts...) @@ -1240,9 +1211,6 @@ func (c *coreClient) DataQuery(ctx context.Context, in *DataQueryRequest, opts . // CoreServer is the server API for Core service. type CoreServer interface { - // Diagnostics - CollectMetrics(context.Context, *CollectMetrics_Request) (*CollectMetrics_Response, error) - CheckHealth(context.Context, *CheckHealth_Request) (*CheckHealth_Response, error) // HTTP Style request Resource(context.Context, *ResourceRequest) (*ResourceResponse, error) // Well typed query interface @@ -1253,12 +1221,6 @@ type CoreServer interface { type UnimplementedCoreServer struct { } -func (*UnimplementedCoreServer) CollectMetrics(ctx context.Context, req *CollectMetrics_Request) (*CollectMetrics_Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method CollectMetrics not implemented") -} -func (*UnimplementedCoreServer) CheckHealth(ctx context.Context, req *CheckHealth_Request) (*CheckHealth_Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method CheckHealth not implemented") -} func (*UnimplementedCoreServer) Resource(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Resource not implemented") } @@ -1270,42 +1232,6 @@ func RegisterCoreServer(s *grpc.Server, srv CoreServer) { s.RegisterService(&_Core_serviceDesc, srv) } -func _Core_CollectMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CollectMetrics_Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(CoreServer).CollectMetrics(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pluginv2.Core/CollectMetrics", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CoreServer).CollectMetrics(ctx, req.(*CollectMetrics_Request)) - } - return interceptor(ctx, in, info, handler) -} - -func _Core_CheckHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CheckHealth_Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(CoreServer).CheckHealth(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pluginv2.Core/CheckHealth", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CoreServer).CheckHealth(ctx, req.(*CheckHealth_Request)) - } - return interceptor(ctx, in, info, handler) -} - func _Core_Resource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ResourceRequest) if err := dec(in); err != nil { @@ -1346,14 +1272,6 @@ var _Core_serviceDesc = grpc.ServiceDesc{ ServiceName: "pluginv2.Core", HandlerType: (*CoreServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "CollectMetrics", - Handler: _Core_CollectMetrics_Handler, - }, - { - MethodName: "CheckHealth", - Handler: _Core_CheckHealth_Handler, - }, { MethodName: "Resource", Handler: _Core_Resource_Handler, @@ -1367,6 +1285,114 @@ var _Core_serviceDesc = grpc.ServiceDesc{ Metadata: "backend.proto", } +// DiagnosticsClient is the client API for Diagnostics service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type DiagnosticsClient interface { + CollectMetrics(ctx context.Context, in *CollectMetrics_Request, opts ...grpc.CallOption) (*CollectMetrics_Response, error) + CheckHealth(ctx context.Context, in *CheckHealth_Request, opts ...grpc.CallOption) (*CheckHealth_Response, error) +} + +type diagnosticsClient struct { + cc *grpc.ClientConn +} + +func NewDiagnosticsClient(cc *grpc.ClientConn) DiagnosticsClient { + return &diagnosticsClient{cc} +} + +func (c *diagnosticsClient) CollectMetrics(ctx context.Context, in *CollectMetrics_Request, opts ...grpc.CallOption) (*CollectMetrics_Response, error) { + out := new(CollectMetrics_Response) + err := c.cc.Invoke(ctx, "/pluginv2.Diagnostics/CollectMetrics", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *diagnosticsClient) CheckHealth(ctx context.Context, in *CheckHealth_Request, opts ...grpc.CallOption) (*CheckHealth_Response, error) { + out := new(CheckHealth_Response) + err := c.cc.Invoke(ctx, "/pluginv2.Diagnostics/CheckHealth", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DiagnosticsServer is the server API for Diagnostics service. +type DiagnosticsServer interface { + CollectMetrics(context.Context, *CollectMetrics_Request) (*CollectMetrics_Response, error) + CheckHealth(context.Context, *CheckHealth_Request) (*CheckHealth_Response, error) +} + +// UnimplementedDiagnosticsServer can be embedded to have forward compatible implementations. +type UnimplementedDiagnosticsServer struct { +} + +func (*UnimplementedDiagnosticsServer) CollectMetrics(ctx context.Context, req *CollectMetrics_Request) (*CollectMetrics_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method CollectMetrics not implemented") +} +func (*UnimplementedDiagnosticsServer) CheckHealth(ctx context.Context, req *CheckHealth_Request) (*CheckHealth_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method CheckHealth not implemented") +} + +func RegisterDiagnosticsServer(s *grpc.Server, srv DiagnosticsServer) { + s.RegisterService(&_Diagnostics_serviceDesc, srv) +} + +func _Diagnostics_CollectMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CollectMetrics_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DiagnosticsServer).CollectMetrics(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pluginv2.Diagnostics/CollectMetrics", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DiagnosticsServer).CollectMetrics(ctx, req.(*CollectMetrics_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Diagnostics_CheckHealth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CheckHealth_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DiagnosticsServer).CheckHealth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pluginv2.Diagnostics/CheckHealth", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DiagnosticsServer).CheckHealth(ctx, req.(*CheckHealth_Request)) + } + return interceptor(ctx, in, info, handler) +} + +var _Diagnostics_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pluginv2.Diagnostics", + HandlerType: (*DiagnosticsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CollectMetrics", + Handler: _Diagnostics_CollectMetrics_Handler, + }, + { + MethodName: "CheckHealth", + Handler: _Diagnostics_CheckHealth_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "backend.proto", +} + // GrafanaPlatformClient is the client API for GrafanaPlatform service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore new file mode 100644 index 00000000000..2233cff9d1f --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore @@ -0,0 +1,201 @@ +#vendor +vendor/ + +# Created by .ignore support plugin (hsz.mobi) +coverage.txt +### Go template +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +### Windows template +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk +### Kate template +# Swap Files # +.*.kate-swp +.swp.* +### SublimeText template +# cache files for sublime text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# workspace files are user-specific +*.sublime-workspace + +# project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using SublimeText +# *.sublime-project + +# sftp configuration file +sftp-config.json +### Linux template +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Xcode template +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint +### Eclipse template + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# Eclipse Core +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md new file mode 100644 index 00000000000..19a8059e1b5 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.2.0](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases/tag/v1.2.0) - 2018-06-04 + +### Added + +* Provide metrics object as `prometheus.Collector`, for conventional metric registration. +* Support non-default/global Prometheus registry. +* Allow configuring counters with `prometheus.CounterOpts`. + +### Changed + +* Remove usage of deprecated `grpc.Code()`. +* Remove usage of deprecated `grpc.Errorf` and replace with `status.Errorf`. + +--- + +This changelog was started with version `v1.2.0`, for earlier versions refer to the respective [GitHub releases](https://github.com/grpc-ecosystem/go-grpc-prometheus/releases). diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE new file mode 100644 index 00000000000..b2b065037fc --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md new file mode 100644 index 00000000000..499c5835533 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md @@ -0,0 +1,247 @@ +# Go gRPC Interceptors for Prometheus monitoring + +[![Travis Build](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus.svg)](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus) +[![Go Report Card](https://goreportcard.com/badge/github.com/grpc-ecosystem/go-grpc-prometheus)](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus) +[![GoDoc](http://img.shields.io/badge/GoDoc-Reference-blue.svg)](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus) +[![SourceGraph](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/-/badge.svg)](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge) +[![codecov](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus) +[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) + +[Prometheus](https://prometheus.io/) monitoring for your [gRPC Go](https://github.com/grpc/grpc-go) servers and clients. + +A sister implementation for [gRPC Java](https://github.com/grpc/grpc-java) (same metrics, same semantics) is in [grpc-ecosystem/java-grpc-prometheus](https://github.com/grpc-ecosystem/java-grpc-prometheus). + +## Interceptors + +[gRPC Go](https://github.com/grpc/grpc-go) recently acquired support for Interceptors, i.e. middleware that is executed +by a gRPC Server before the request is passed onto the user's application logic. It is a perfect way to implement +common patterns: auth, logging and... monitoring. + +To use Interceptors in chains, please see [`go-grpc-middleware`](https://github.com/mwitkow/go-grpc-middleware). + +## Usage + +There are two types of interceptors: client-side and server-side. This package provides monitoring Interceptors for both. + +### Server-side + +```go +import "github.com/grpc-ecosystem/go-grpc-prometheus" +... + // Initialize your gRPC server's interceptor. + myServer := grpc.NewServer( + grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor), + grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor), + ) + // Register your gRPC service implementations. + myservice.RegisterMyServiceServer(s.server, &myServiceImpl{}) + // After all your registrations, make sure all of the Prometheus metrics are initialized. + grpc_prometheus.Register(myServer) + // Register Prometheus metrics handler. + http.Handle("/metrics", promhttp.Handler()) +... +``` + +### Client-side + +```go +import "github.com/grpc-ecosystem/go-grpc-prometheus" +... + clientConn, err = grpc.Dial( + address, + grpc.WithUnaryInterceptor(grpc_prometheus.UnaryClientInterceptor), + grpc.WithStreamInterceptor(grpc_prometheus.StreamClientInterceptor) + ) + client = pb_testproto.NewTestServiceClient(clientConn) + resp, err := client.PingEmpty(s.ctx, &myservice.Request{Msg: "hello"}) +... +``` + +# Metrics + +## Labels + +All server-side metrics start with `grpc_server` as Prometheus subsystem name. All client-side metrics start with `grpc_client`. Both of them have mirror-concepts. Similarly all methods +contain the same rich labels: + + * `grpc_service` - the [gRPC service](http://www.grpc.io/docs/#defining-a-service) name, which is the combination of protobuf `package` and + the `grpc_service` section name. E.g. for `package = mwitkow.testproto` and + `service TestService` the label will be `grpc_service="mwitkow.testproto.TestService"` + * `grpc_method` - the name of the method called on the gRPC service. E.g. + `grpc_method="Ping"` + * `grpc_type` - the gRPC [type of request](http://www.grpc.io/docs/guides/concepts.html#rpc-life-cycle). + Differentiating between the two is important especially for latency measurements. + + - `unary` is single request, single response RPC + - `client_stream` is a multi-request, single response RPC + - `server_stream` is a single request, multi-response RPC + - `bidi_stream` is a multi-request, multi-response RPC + + +Additionally for completed RPCs, the following labels are used: + + * `grpc_code` - the human-readable [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go). + The list of all statuses is to long, but here are some common ones: + + - `OK` - means the RPC was successful + - `IllegalArgument` - RPC contained bad values + - `Internal` - server-side error not disclosed to the clients + +## Counters + +The counters and their up to date documentation is in [server_reporter.go](server_reporter.go) and [client_reporter.go](client_reporter.go) +the respective Prometheus handler (usually `/metrics`). + +For the purpose of this documentation we will only discuss `grpc_server` metrics. The `grpc_client` ones contain mirror concepts. + +For simplicity, let's assume we're tracking a single server-side RPC call of [`mwitkow.testproto.TestService`](examples/testproto/test.proto), +calling the method `PingList`. The call succeeds and returns 20 messages in the stream. + +First, immediately after the server receives the call it will increment the +`grpc_server_started_total` and start the handling time clock (if histograms are enabled). + +```jsoniq +grpc_server_started_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +Then the user logic gets invoked. It receives one message from the client containing the request +(it's a `server_stream`): + +```jsoniq +grpc_server_msg_received_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +The user logic may return an error, or send multiple messages back to the client. In this case, on +each of the 20 messages sent back, a counter will be incremented: + +```jsoniq +grpc_server_msg_sent_total{grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 20 +``` + +After the call completes, its status (`OK` or other [gRPC status code](https://github.com/grpc/grpc-go/blob/master/codes/codes.go)) +and the relevant call labels increment the `grpc_server_handled_total` counter. + +```jsoniq +grpc_server_handled_total{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + +## Histograms + +[Prometheus histograms](https://prometheus.io/docs/concepts/metric_types/#histogram) are a great way +to measure latency distributions of your RPCs. However, since it is bad practice to have metrics +of [high cardinality](https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels) +the latency monitoring metrics are disabled by default. To enable them please call the following +in your server initialization code: + +```jsoniq +grpc_prometheus.EnableHandlingTimeHistogram() +``` + +After the call completes, its handling time will be recorded in a [Prometheus histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) +variable `grpc_server_handling_seconds`. The histogram variable contains three sub-metrics: + + * `grpc_server_handling_seconds_count` - the count of all completed RPCs by status and method + * `grpc_server_handling_seconds_sum` - cumulative time of RPCs by status and method, useful for + calculating average handling times + * `grpc_server_handling_seconds_bucket` - contains the counts of RPCs by status and method in respective + handling-time buckets. These buckets can be used by Prometheus to estimate SLAs (see [here](https://prometheus.io/docs/practices/histograms/)) + +The counter values will look as follows: + +```jsoniq +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.005"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.01"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.025"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.05"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.1"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.25"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="0.5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="1"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="2.5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="5"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="10"} 1 +grpc_server_handling_seconds_bucket{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream",le="+Inf"} 1 +grpc_server_handling_seconds_sum{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 0.0003866430000000001 +grpc_server_handling_seconds_count{grpc_code="OK",grpc_method="PingList",grpc_service="mwitkow.testproto.TestService",grpc_type="server_stream"} 1 +``` + + +## Useful query examples + +Prometheus philosophy is to provide raw metrics to the monitoring system, and +let the aggregations be handled there. The verbosity of above metrics make it possible to have that +flexibility. Here's a couple of useful monitoring queries: + + +### request inbound rate +```jsoniq +sum(rate(grpc_server_started_total{job="foo"}[1m])) by (grpc_service) +``` +For `job="foo"` (common label to differentiate between Prometheus monitoring targets), calculate the +rate of requests per second (1 minute window) for each gRPC `grpc_service` that the job has. Please note +how the `grpc_method` is being omitted here: all methods of a given gRPC service will be summed together. + +### unary request error rate +```jsoniq +sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) +``` +For `job="foo"`, calculate the per-`grpc_service` rate of `unary` (1:1) RPCs that failed, i.e. the +ones that didn't finish with `OK` code. + +### unary request error percentage +```jsoniq +sum(rate(grpc_server_handled_total{job="foo",grpc_type="unary",grpc_code!="OK"}[1m])) by (grpc_service) + / +sum(rate(grpc_server_started_total{job="foo",grpc_type="unary"}[1m])) by (grpc_service) + * 100.0 +``` +For `job="foo"`, calculate the percentage of failed requests by service. It's easy to notice that +this is a combination of the two above examples. This is an example of a query you would like to +[alert on](https://prometheus.io/docs/alerting/rules/) in your system for SLA violations, e.g. +"no more than 1% requests should fail". + +### average response stream size +```jsoniq +sum(rate(grpc_server_msg_sent_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) + / +sum(rate(grpc_server_started_total{job="foo",grpc_type="server_stream"}[10m])) by (grpc_service) +``` +For `job="foo"` what is the `grpc_service`-wide `10m` average of messages returned for all ` +server_stream` RPCs. This allows you to track the stream sizes returned by your system, e.g. allows +you to track when clients started to send "wide" queries that ret +Note the divisor is the number of started RPCs, in order to account for in-flight requests. + +### 99%-tile latency of unary requests +```jsoniq +histogram_quantile(0.99, + sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary"}[5m])) by (grpc_service,le) +) +``` +For `job="foo"`, returns an 99%-tile [quantile estimation](https://prometheus.io/docs/practices/histograms/#quantiles) +of the handling time of RPCs per service. Please note the `5m` rate, this means that the quantile +estimation will take samples in a rolling `5m` window. When combined with other quantiles +(e.g. 50%, 90%), this query gives you tremendous insight into the responsiveness of your system +(e.g. impact of caching). + +### percentage of slow unary queries (>250ms) +```jsoniq +100.0 - ( +sum(rate(grpc_server_handling_seconds_bucket{job="foo",grpc_type="unary",le="0.25"}[5m])) by (grpc_service) + / +sum(rate(grpc_server_handling_seconds_count{job="foo",grpc_type="unary"}[5m])) by (grpc_service) +) * 100.0 +``` +For `job="foo"` calculate the by-`grpc_service` fraction of slow requests that took longer than `0.25` +seconds. This query is relatively complex, since the Prometheus aggregations use `le` (less or equal) +buckets, meaning that counting "fast" requests fractions is easier. However, simple maths helps. +This is an example of a query you would like to alert on in your system for SLA violations, +e.g. "less than 1% of requests are slower than 250ms". + + +## Status + +This code has been used since August 2015 as the basis for monitoring of *production* gRPC micro services at [Improbable](https://improbable.io). + +## License + +`go-grpc-prometheus` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go new file mode 100644 index 00000000000..751a4c72d7e --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go @@ -0,0 +1,39 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +// gRPC Prometheus monitoring interceptors for client-side gRPC. + +package grpc_prometheus + +import ( + prom "github.com/prometheus/client_golang/prometheus" +) + +var ( + // DefaultClientMetrics is the default instance of ClientMetrics. It is + // intended to be used in conjunction the default Prometheus metrics + // registry. + DefaultClientMetrics = NewClientMetrics() + + // UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. + UnaryClientInterceptor = DefaultClientMetrics.UnaryClientInterceptor() + + // StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. + StreamClientInterceptor = DefaultClientMetrics.StreamClientInterceptor() +) + +func init() { + prom.MustRegister(DefaultClientMetrics.clientStartedCounter) + prom.MustRegister(DefaultClientMetrics.clientHandledCounter) + prom.MustRegister(DefaultClientMetrics.clientStreamMsgReceived) + prom.MustRegister(DefaultClientMetrics.clientStreamMsgSent) +} + +// EnableClientHandlingTimeHistogram turns on recording of handling time of +// RPCs. Histogram metrics can be very expensive for Prometheus to retain and +// query. This function acts on the DefaultClientMetrics variable and the +// default Prometheus metrics registry. +func EnableClientHandlingTimeHistogram(opts ...HistogramOption) { + DefaultClientMetrics.EnableClientHandlingTimeHistogram(opts...) + prom.Register(DefaultClientMetrics.clientHandledHistogram) +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go new file mode 100644 index 00000000000..9b476f9832c --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go @@ -0,0 +1,170 @@ +package grpc_prometheus + +import ( + "io" + + prom "github.com/prometheus/client_golang/prometheus" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// ClientMetrics represents a collection of metrics to be registered on a +// Prometheus metrics registry for a gRPC client. +type ClientMetrics struct { + clientStartedCounter *prom.CounterVec + clientHandledCounter *prom.CounterVec + clientStreamMsgReceived *prom.CounterVec + clientStreamMsgSent *prom.CounterVec + clientHandledHistogramEnabled bool + clientHandledHistogramOpts prom.HistogramOpts + clientHandledHistogram *prom.HistogramVec +} + +// NewClientMetrics returns a ClientMetrics object. Use a new instance of +// ClientMetrics when not using the default Prometheus metrics registry, for +// example when wanting to control which metrics are added to a registry as +// opposed to automatically adding metrics via init functions. +func NewClientMetrics(counterOpts ...CounterOption) *ClientMetrics { + opts := counterOptions(counterOpts) + return &ClientMetrics{ + clientStartedCounter: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_client_started_total", + Help: "Total number of RPCs started on the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientHandledCounter: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_client_handled_total", + Help: "Total number of RPCs completed by the client, regardless of success or failure.", + }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), + + clientStreamMsgReceived: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_client_msg_received_total", + Help: "Total number of RPC stream messages received by the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientStreamMsgSent: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_client_msg_sent_total", + Help: "Total number of gRPC stream messages sent by the client.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + + clientHandledHistogramEnabled: false, + clientHandledHistogramOpts: prom.HistogramOpts{ + Name: "grpc_client_handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + Buckets: prom.DefBuckets, + }, + clientHandledHistogram: nil, + } +} + +// Describe sends the super-set of all possible descriptors of metrics +// collected by this Collector to the provided channel and returns once +// the last descriptor has been sent. +func (m *ClientMetrics) Describe(ch chan<- *prom.Desc) { + m.clientStartedCounter.Describe(ch) + m.clientHandledCounter.Describe(ch) + m.clientStreamMsgReceived.Describe(ch) + m.clientStreamMsgSent.Describe(ch) + if m.clientHandledHistogramEnabled { + m.clientHandledHistogram.Describe(ch) + } +} + +// Collect is called by the Prometheus registry when collecting +// metrics. The implementation sends each collected metric via the +// provided channel and returns once the last metric has been sent. +func (m *ClientMetrics) Collect(ch chan<- prom.Metric) { + m.clientStartedCounter.Collect(ch) + m.clientHandledCounter.Collect(ch) + m.clientStreamMsgReceived.Collect(ch) + m.clientStreamMsgSent.Collect(ch) + if m.clientHandledHistogramEnabled { + m.clientHandledHistogram.Collect(ch) + } +} + +// EnableClientHandlingTimeHistogram turns on recording of handling time of RPCs. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func (m *ClientMetrics) EnableClientHandlingTimeHistogram(opts ...HistogramOption) { + for _, o := range opts { + o(&m.clientHandledHistogramOpts) + } + if !m.clientHandledHistogramEnabled { + m.clientHandledHistogram = prom.NewHistogramVec( + m.clientHandledHistogramOpts, + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + } + m.clientHandledHistogramEnabled = true +} + +// UnaryClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Unary RPCs. +func (m *ClientMetrics) UnaryClientInterceptor() func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + monitor := newClientReporter(m, Unary, method) + monitor.SentMessage() + err := invoker(ctx, method, req, reply, cc, opts...) + if err != nil { + monitor.ReceivedMessage() + } + st, _ := status.FromError(err) + monitor.Handled(st.Code()) + return err + } +} + +// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func (m *ClientMetrics) StreamClientInterceptor() func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + monitor := newClientReporter(m, clientStreamType(desc), method) + clientStream, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + st, _ := status.FromError(err) + monitor.Handled(st.Code()) + return nil, err + } + return &monitoredClientStream{clientStream, monitor}, nil + } +} + +func clientStreamType(desc *grpc.StreamDesc) grpcType { + if desc.ClientStreams && !desc.ServerStreams { + return ClientStream + } else if !desc.ClientStreams && desc.ServerStreams { + return ServerStream + } + return BidiStream +} + +// monitoredClientStream wraps grpc.ClientStream allowing each Sent/Recv of message to increment counters. +type monitoredClientStream struct { + grpc.ClientStream + monitor *clientReporter +} + +func (s *monitoredClientStream) SendMsg(m interface{}) error { + err := s.ClientStream.SendMsg(m) + if err == nil { + s.monitor.SentMessage() + } + return err +} + +func (s *monitoredClientStream) RecvMsg(m interface{}) error { + err := s.ClientStream.RecvMsg(m) + if err == nil { + s.monitor.ReceivedMessage() + } else if err == io.EOF { + s.monitor.Handled(codes.OK) + } else { + st, _ := status.FromError(err) + s.monitor.Handled(st.Code()) + } + return err +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go new file mode 100644 index 00000000000..cbf15322996 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go @@ -0,0 +1,46 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "time" + + "google.golang.org/grpc/codes" +) + +type clientReporter struct { + metrics *ClientMetrics + rpcType grpcType + serviceName string + methodName string + startTime time.Time +} + +func newClientReporter(m *ClientMetrics, rpcType grpcType, fullMethod string) *clientReporter { + r := &clientReporter{ + metrics: m, + rpcType: rpcType, + } + if r.metrics.clientHandledHistogramEnabled { + r.startTime = time.Now() + } + r.serviceName, r.methodName = splitMethodName(fullMethod) + r.metrics.clientStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() + return r +} + +func (r *clientReporter) ReceivedMessage() { + r.metrics.clientStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *clientReporter) SentMessage() { + r.metrics.clientStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *clientReporter) Handled(code codes.Code) { + r.metrics.clientHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() + if r.metrics.clientHandledHistogramEnabled { + r.metrics.clientHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile new file mode 100644 index 00000000000..74c08422305 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile @@ -0,0 +1,16 @@ +SHELL="/bin/bash" + +GOFILES_NOVENDOR = $(shell go list ./... | grep -v /vendor/) + +all: vet fmt test + +fmt: + go fmt $(GOFILES_NOVENDOR) + +vet: + go vet $(GOFILES_NOVENDOR) + +test: vet + ./scripts/test_all.sh + +.PHONY: all vet test diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go new file mode 100644 index 00000000000..9d51aec9816 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go @@ -0,0 +1,41 @@ +package grpc_prometheus + +import ( + prom "github.com/prometheus/client_golang/prometheus" +) + +// A CounterOption lets you add options to Counter metrics using With* funcs. +type CounterOption func(*prom.CounterOpts) + +type counterOptions []CounterOption + +func (co counterOptions) apply(o prom.CounterOpts) prom.CounterOpts { + for _, f := range co { + f(&o) + } + return o +} + +// WithConstLabels allows you to add ConstLabels to Counter metrics. +func WithConstLabels(labels prom.Labels) CounterOption { + return func(o *prom.CounterOpts) { + o.ConstLabels = labels + } +} + +// A HistogramOption lets you add options to Histogram metrics using With* +// funcs. +type HistogramOption func(*prom.HistogramOpts) + +// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. +func WithHistogramBuckets(buckets []float64) HistogramOption { + return func(o *prom.HistogramOpts) { o.Buckets = buckets } +} + +// WithHistogramConstLabels allows you to add custom ConstLabels to +// histograms metrics. +func WithHistogramConstLabels(labels prom.Labels) HistogramOption { + return func(o *prom.HistogramOpts) { + o.ConstLabels = labels + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go new file mode 100644 index 00000000000..322f99046fd --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go @@ -0,0 +1,48 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +// gRPC Prometheus monitoring interceptors for server-side gRPC. + +package grpc_prometheus + +import ( + prom "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" +) + +var ( + // DefaultServerMetrics is the default instance of ServerMetrics. It is + // intended to be used in conjunction the default Prometheus metrics + // registry. + DefaultServerMetrics = NewServerMetrics() + + // UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. + UnaryServerInterceptor = DefaultServerMetrics.UnaryServerInterceptor() + + // StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. + StreamServerInterceptor = DefaultServerMetrics.StreamServerInterceptor() +) + +func init() { + prom.MustRegister(DefaultServerMetrics.serverStartedCounter) + prom.MustRegister(DefaultServerMetrics.serverHandledCounter) + prom.MustRegister(DefaultServerMetrics.serverStreamMsgReceived) + prom.MustRegister(DefaultServerMetrics.serverStreamMsgSent) +} + +// Register takes a gRPC server and pre-initializes all counters to 0. This +// allows for easier monitoring in Prometheus (no missing metrics), and should +// be called *after* all services have been registered with the server. This +// function acts on the DefaultServerMetrics variable. +func Register(server *grpc.Server) { + DefaultServerMetrics.InitializeMetrics(server) +} + +// EnableHandlingTimeHistogram turns on recording of handling time +// of RPCs. Histogram metrics can be very expensive for Prometheus +// to retain and query. This function acts on the DefaultServerMetrics +// variable and the default Prometheus metrics registry. +func EnableHandlingTimeHistogram(opts ...HistogramOption) { + DefaultServerMetrics.EnableHandlingTimeHistogram(opts...) + prom.Register(DefaultServerMetrics.serverHandledHistogram) +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go new file mode 100644 index 00000000000..5b1467e7aac --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go @@ -0,0 +1,185 @@ +package grpc_prometheus + +import ( + prom "github.com/prometheus/client_golang/prometheus" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/status" +) + +// ServerMetrics represents a collection of metrics to be registered on a +// Prometheus metrics registry for a gRPC server. +type ServerMetrics struct { + serverStartedCounter *prom.CounterVec + serverHandledCounter *prom.CounterVec + serverStreamMsgReceived *prom.CounterVec + serverStreamMsgSent *prom.CounterVec + serverHandledHistogramEnabled bool + serverHandledHistogramOpts prom.HistogramOpts + serverHandledHistogram *prom.HistogramVec +} + +// NewServerMetrics returns a ServerMetrics object. Use a new instance of +// ServerMetrics when not using the default Prometheus metrics registry, for +// example when wanting to control which metrics are added to a registry as +// opposed to automatically adding metrics via init functions. +func NewServerMetrics(counterOpts ...CounterOption) *ServerMetrics { + opts := counterOptions(counterOpts) + return &ServerMetrics{ + serverStartedCounter: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_server_started_total", + Help: "Total number of RPCs started on the server.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + serverHandledCounter: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_server_handled_total", + Help: "Total number of RPCs completed on the server, regardless of success or failure.", + }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), + serverStreamMsgReceived: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_server_msg_received_total", + Help: "Total number of RPC stream messages received on the server.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + serverStreamMsgSent: prom.NewCounterVec( + opts.apply(prom.CounterOpts{ + Name: "grpc_server_msg_sent_total", + Help: "Total number of gRPC stream messages sent by the server.", + }), []string{"grpc_type", "grpc_service", "grpc_method"}), + serverHandledHistogramEnabled: false, + serverHandledHistogramOpts: prom.HistogramOpts{ + Name: "grpc_server_handling_seconds", + Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", + Buckets: prom.DefBuckets, + }, + serverHandledHistogram: nil, + } +} + +// EnableHandlingTimeHistogram enables histograms being registered when +// registering the ServerMetrics on a Prometheus registry. Histograms can be +// expensive on Prometheus servers. It takes options to configure histogram +// options such as the defined buckets. +func (m *ServerMetrics) EnableHandlingTimeHistogram(opts ...HistogramOption) { + for _, o := range opts { + o(&m.serverHandledHistogramOpts) + } + if !m.serverHandledHistogramEnabled { + m.serverHandledHistogram = prom.NewHistogramVec( + m.serverHandledHistogramOpts, + []string{"grpc_type", "grpc_service", "grpc_method"}, + ) + } + m.serverHandledHistogramEnabled = true +} + +// Describe sends the super-set of all possible descriptors of metrics +// collected by this Collector to the provided channel and returns once +// the last descriptor has been sent. +func (m *ServerMetrics) Describe(ch chan<- *prom.Desc) { + m.serverStartedCounter.Describe(ch) + m.serverHandledCounter.Describe(ch) + m.serverStreamMsgReceived.Describe(ch) + m.serverStreamMsgSent.Describe(ch) + if m.serverHandledHistogramEnabled { + m.serverHandledHistogram.Describe(ch) + } +} + +// Collect is called by the Prometheus registry when collecting +// metrics. The implementation sends each collected metric via the +// provided channel and returns once the last metric has been sent. +func (m *ServerMetrics) Collect(ch chan<- prom.Metric) { + m.serverStartedCounter.Collect(ch) + m.serverHandledCounter.Collect(ch) + m.serverStreamMsgReceived.Collect(ch) + m.serverStreamMsgSent.Collect(ch) + if m.serverHandledHistogramEnabled { + m.serverHandledHistogram.Collect(ch) + } +} + +// UnaryServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Unary RPCs. +func (m *ServerMetrics) UnaryServerInterceptor() func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + monitor := newServerReporter(m, Unary, info.FullMethod) + monitor.ReceivedMessage() + resp, err := handler(ctx, req) + st, _ := status.FromError(err) + monitor.Handled(st.Code()) + if err == nil { + monitor.SentMessage() + } + return resp, err + } +} + +// StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs. +func (m *ServerMetrics) StreamServerInterceptor() func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + monitor := newServerReporter(m, streamRPCType(info), info.FullMethod) + err := handler(srv, &monitoredServerStream{ss, monitor}) + st, _ := status.FromError(err) + monitor.Handled(st.Code()) + return err + } +} + +// InitializeMetrics initializes all metrics, with their appropriate null +// value, for all gRPC methods registered on a gRPC server. This is useful, to +// ensure that all metrics exist when collecting and querying. +func (m *ServerMetrics) InitializeMetrics(server *grpc.Server) { + serviceInfo := server.GetServiceInfo() + for serviceName, info := range serviceInfo { + for _, mInfo := range info.Methods { + preRegisterMethod(m, serviceName, &mInfo) + } + } +} + +func streamRPCType(info *grpc.StreamServerInfo) grpcType { + if info.IsClientStream && !info.IsServerStream { + return ClientStream + } else if !info.IsClientStream && info.IsServerStream { + return ServerStream + } + return BidiStream +} + +// monitoredStream wraps grpc.ServerStream allowing each Sent/Recv of message to increment counters. +type monitoredServerStream struct { + grpc.ServerStream + monitor *serverReporter +} + +func (s *monitoredServerStream) SendMsg(m interface{}) error { + err := s.ServerStream.SendMsg(m) + if err == nil { + s.monitor.SentMessage() + } + return err +} + +func (s *monitoredServerStream) RecvMsg(m interface{}) error { + err := s.ServerStream.RecvMsg(m) + if err == nil { + s.monitor.ReceivedMessage() + } + return err +} + +// preRegisterMethod is invoked on Register of a Server, allowing all gRPC services labels to be pre-populated. +func preRegisterMethod(metrics *ServerMetrics, serviceName string, mInfo *grpc.MethodInfo) { + methodName := mInfo.Name + methodType := string(typeFromMethodInfo(mInfo)) + // These are just references (no increments), as just referencing will create the labels but not set values. + metrics.serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName) + metrics.serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName) + metrics.serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName) + if metrics.serverHandledHistogramEnabled { + metrics.serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName) + } + for _, code := range allCodes { + metrics.serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String()) + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go new file mode 100644 index 00000000000..aa9db5401a4 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go @@ -0,0 +1,46 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "time" + + "google.golang.org/grpc/codes" +) + +type serverReporter struct { + metrics *ServerMetrics + rpcType grpcType + serviceName string + methodName string + startTime time.Time +} + +func newServerReporter(m *ServerMetrics, rpcType grpcType, fullMethod string) *serverReporter { + r := &serverReporter{ + metrics: m, + rpcType: rpcType, + } + if r.metrics.serverHandledHistogramEnabled { + r.startTime = time.Now() + } + r.serviceName, r.methodName = splitMethodName(fullMethod) + r.metrics.serverStartedCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() + return r +} + +func (r *serverReporter) ReceivedMessage() { + r.metrics.serverStreamMsgReceived.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *serverReporter) SentMessage() { + r.metrics.serverStreamMsgSent.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Inc() +} + +func (r *serverReporter) Handled(code codes.Code) { + r.metrics.serverHandledCounter.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName, code.String()).Inc() + if r.metrics.serverHandledHistogramEnabled { + r.metrics.serverHandledHistogram.WithLabelValues(string(r.rpcType), r.serviceName, r.methodName).Observe(time.Since(r.startTime).Seconds()) + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go new file mode 100644 index 00000000000..7987de35f42 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go @@ -0,0 +1,50 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package grpc_prometheus + +import ( + "strings" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" +) + +type grpcType string + +const ( + Unary grpcType = "unary" + ClientStream grpcType = "client_stream" + ServerStream grpcType = "server_stream" + BidiStream grpcType = "bidi_stream" +) + +var ( + allCodes = []codes.Code{ + codes.OK, codes.Canceled, codes.Unknown, codes.InvalidArgument, codes.DeadlineExceeded, codes.NotFound, + codes.AlreadyExists, codes.PermissionDenied, codes.Unauthenticated, codes.ResourceExhausted, + codes.FailedPrecondition, codes.Aborted, codes.OutOfRange, codes.Unimplemented, codes.Internal, + codes.Unavailable, codes.DataLoss, + } +) + +func splitMethodName(fullMethodName string) (string, string) { + fullMethodName = strings.TrimPrefix(fullMethodName, "/") // remove leading slash + if i := strings.Index(fullMethodName, "/"); i >= 0 { + return fullMethodName[:i], fullMethodName[i+1:] + } + return "unknown", "unknown" +} + +func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { + if !mInfo.IsClientStream && !mInfo.IsServerStream { + return Unary + } + if mInfo.IsClientStream && !mInfo.IsServerStream { + return ClientStream + } + if !mInfo.IsClientStream && mInfo.IsServerStream { + return ServerStream + } + return BidiStream +} diff --git a/vendor/modules.txt b/vendor/modules.txt index d366ddccc7d..8be0eebc9d7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -140,11 +140,12 @@ github.com/gosimple/slug # github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 github.com/grafana/grafana-plugin-model/go/datasource github.com/grafana/grafana-plugin-model/go/renderer -# github.com/grafana/grafana-plugin-sdk-go v0.5.0 +# github.com/grafana/grafana-plugin-sdk-go v0.6.0 github.com/grafana/grafana-plugin-sdk-go/backend -github.com/grafana/grafana-plugin-sdk-go/common github.com/grafana/grafana-plugin-sdk-go/dataframe github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2 +# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 +github.com/grpc-ecosystem/go-grpc-prometheus # github.com/hashicorp/go-hclog v0.8.0 github.com/hashicorp/go-hclog # github.com/hashicorp/go-plugin v1.0.1