mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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/<plugin id>/health`. Uses sdk v0.6.0. Closes #20984
This commit is contained in:
parent
f56f54b1a3
commit
5c711bfb79
3
go.mod
3
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
|
||||
|
6
go.sum
6
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=
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -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...,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
89
pkg/plugins/backendplugin/collector/collector.go
Normal file
89
pkg/plugins/backendplugin/collector/collector.go
Normal file
@ -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)
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
47
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go
generated
vendored
47
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go
generated
vendored
@ -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)
|
||||
}
|
||||
|
32
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go
generated
vendored
32
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_grpc.go
generated
vendored
@ -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)
|
||||
}
|
||||
|
61
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go
generated
vendored
61
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core_sdk_adapter.go
generated
vendored
@ -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
|
||||
}
|
53
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go
generated
vendored
Normal file
53
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go
generated
vendored
Normal file
@ -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,
|
||||
}
|
||||
}
|
51
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go
generated
vendored
Normal file
51
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics_grpc.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package common
|
||||
package backend
|
||||
|
||||
import plugin "github.com/hashicorp/go-plugin"
|
||||
|
91
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go
generated
vendored
Normal file
91
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go
generated
vendored
Normal file
@ -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
|
||||
}
|
61
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go
generated
vendored
61
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go
generated
vendored
@ -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
|
||||
|
6
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go
generated
vendored
6
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go
generated
vendored
@ -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
|
||||
|
4
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go
generated
vendored
4
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_grpc.go
generated
vendored
@ -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) {
|
||||
|
33
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go
generated
vendored
33
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform_sdk_adapter.go
generated
vendored
@ -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
|
||||
}
|
868
vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go
generated
vendored
868
vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go
generated
vendored
@ -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.
|
||||
|
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
generated
vendored
Normal file
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
generated
vendored
Normal file
@ -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/
|
||||
|
24
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md
generated
vendored
Normal file
24
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md
generated
vendored
Normal file
@ -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).
|
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE
generated
vendored
Normal file
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE
generated
vendored
Normal file
@ -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.
|
247
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md
generated
vendored
Normal file
247
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
# Go gRPC Interceptors for Prometheus monitoring
|
||||
|
||||
[](https://travis-ci.org/grpc-ecosystem/go-grpc-prometheus)
|
||||
[](http://goreportcard.com/report/grpc-ecosystem/go-grpc-prometheus)
|
||||
[](https://godoc.org/github.com/grpc-ecosystem/go-grpc-prometheus)
|
||||
[](https://sourcegraph.com/github.com/grpc-ecosystem/go-grpc-prometheus/?badge)
|
||||
[](https://codecov.io/gh/grpc-ecosystem/go-grpc-prometheus)
|
||||
[](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.
|
39
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go
generated
vendored
Normal file
39
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
170
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
generated
vendored
Normal file
170
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
generated
vendored
Normal file
@ -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
|
||||
}
|
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go
generated
vendored
Normal file
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go
generated
vendored
Normal file
@ -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())
|
||||
}
|
||||
}
|
16
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile
generated
vendored
Normal file
16
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile
generated
vendored
Normal file
@ -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
|
41
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
generated
vendored
Normal file
41
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
generated
vendored
Normal file
@ -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
|
||||
}
|
||||
}
|
48
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go
generated
vendored
Normal file
48
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
185
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
generated
vendored
Normal file
185
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
generated
vendored
Normal file
@ -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())
|
||||
}
|
||||
}
|
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go
generated
vendored
Normal file
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go
generated
vendored
Normal file
@ -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())
|
||||
}
|
||||
}
|
50
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
generated
vendored
Normal file
50
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
generated
vendored
Normal file
@ -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
|
||||
}
|
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user