mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Backend plugins: Implement support for resources (#21805)
Implements initial support for resources using v0.14.0 of SDK. Ref #21512
This commit is contained in:
parent
5345868148
commit
0390b5601e
2
go.mod
2
go.mod
@ -32,7 +32,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.11.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.14.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
|
||||
|
8
go.sum
8
go.sum
@ -9,8 +9,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20190716210558-5f564424c71c h1:iHUHzx3S1TU5xt+D7vLb0PAk3e+RfayF9IhR6+hyO/k=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20190716210558-5f564424c71c/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191025121910-b789226ccb21 h1:xI+FQ/TsyD7jy22vP9wQBtJsPFRQTLZHfrr1IMLl0g0=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191025121910-b789226ccb21/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
|
||||
github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk=
|
||||
@ -127,10 +125,8 @@ 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.6.0 h1:rMMp84CdEKxI4i6SEpIUgsHgcKa1JdXDjLrDDw6QhXI=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.6.0/go.mod h1:0eV4vNOYNZKOBbl23MieYiLa2y8M8S3D6ytLdggctqo=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.11.0 h1:MkefJEWDMYk86eHUzCatTfK2/atAYNN1FncBqP5mx20=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.11.0/go.mod h1:Dgc2ygLBJXTTIcfIgCGG6mxRcC/aZ36rKZ1tq5B5XmY=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.14.0 h1:7Y34uhBkmkZ1ywYNfTXYXZihRgxgCf9WQbad4iqJ+t8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.14.0/go.mod h1:Dgc2ygLBJXTTIcfIgCGG6mxRcC/aZ36rKZ1tq5B5XmY=
|
||||
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=
|
||||
|
@ -251,6 +251,9 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Get("/plugins", Wrap(hs.GetPluginList))
|
||||
apiRoute.Get("/plugins/:pluginId/settings", Wrap(GetPluginSettingByID))
|
||||
apiRoute.Get("/plugins/:pluginId/markdown/:name", Wrap(GetPluginMarkdown))
|
||||
apiRoute.Get("/plugins/:pluginId/health", Wrap(hs.CheckHealth))
|
||||
apiRoute.Any("/plugins/:pluginId/resources", Wrap(hs.CallResource))
|
||||
apiRoute.Any("/plugins/:pluginId/resources/*", Wrap(hs.CallResource))
|
||||
|
||||
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
|
||||
pluginRoute.Get("/:pluginId/dashboards/", Wrap(GetPluginDashboards))
|
||||
@ -260,6 +263,8 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Get("/frontend/settings/", hs.GetFrontendSettings)
|
||||
apiRoute.Any("/datasources/proxy/:id/*", reqSignedIn, hs.ProxyDataSourceRequest)
|
||||
apiRoute.Any("/datasources/proxy/:id", reqSignedIn, hs.ProxyDataSourceRequest)
|
||||
apiRoute.Any("/datasources/:id/resources", Wrap(hs.CallDatasourceResource))
|
||||
apiRoute.Any("/datasources/:id/resources/*", Wrap(hs.CallDatasourceResource))
|
||||
|
||||
// Folders
|
||||
apiRoute.Group("/folders", func(folderRoute routing.RouteRegister) {
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@ -253,6 +254,60 @@ func GetDataSourceIdByName(c *m.ReqContext) Response {
|
||||
return JSON(200, &dtos)
|
||||
}
|
||||
|
||||
// /api/datasources/:id/resources/*
|
||||
func (hs *HTTPServer) CallDatasourceResource(c *m.ReqContext) Response {
|
||||
datasourceID := c.ParamsInt64(":id")
|
||||
ds, err := hs.DatasourceCache.GetDatasource(datasourceID, c.SignedInUser, c.SkipCache)
|
||||
if err != nil {
|
||||
if err == m.ErrDataSourceAccessDenied {
|
||||
return Error(403, "Access denied to datasource", err)
|
||||
}
|
||||
return Error(500, "Unable to load datasource meta data", err)
|
||||
}
|
||||
|
||||
// find plugin
|
||||
plugin, ok := plugins.DataSources[ds.Type]
|
||||
if !ok {
|
||||
return Error(500, "Unable to find datasource plugin", err)
|
||||
}
|
||||
|
||||
body, err := c.Req.Body().Bytes()
|
||||
if err != nil {
|
||||
return Error(500, "Failed to read request body", err)
|
||||
}
|
||||
req := backendplugin.CallResourceRequest{
|
||||
Config: backendplugin.PluginConfig{
|
||||
OrgID: c.OrgId,
|
||||
PluginID: plugin.Id,
|
||||
Instance: &backendplugin.PluginInstance{
|
||||
ID: ds.Id,
|
||||
Name: ds.Name,
|
||||
Type: ds.Type,
|
||||
URL: ds.Url,
|
||||
},
|
||||
},
|
||||
Path: c.Params("*"),
|
||||
Method: c.Req.Method,
|
||||
URL: c.Req.URL.String(),
|
||||
Headers: c.Req.Header.Clone(),
|
||||
Body: body,
|
||||
}
|
||||
resp, err := hs.BackendPluginManager.CallResource(c.Req.Context(), req)
|
||||
if err != nil {
|
||||
return Error(500, "Failed to call datasource resource", err)
|
||||
}
|
||||
|
||||
if resp.Status >= 400 {
|
||||
return Error(resp.Status, "", nil)
|
||||
}
|
||||
|
||||
return &NormalResponse{
|
||||
body: resp.Body,
|
||||
status: resp.Status,
|
||||
header: resp.Headers,
|
||||
}
|
||||
}
|
||||
|
||||
func convertModelToDtos(ds *m.DataSource) dtos.DataSource {
|
||||
dto := dtos.DataSource{
|
||||
Id: ds.Id,
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/live"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
httpstatic "github.com/grafana/grafana/pkg/api/static"
|
||||
@ -57,19 +59,20 @@ type HTTPServer struct {
|
||||
streamManager *live.StreamManager
|
||||
httpSrv *http.Server
|
||||
|
||||
RouteRegister routing.RouteRegister `inject:""`
|
||||
Bus bus.Bus `inject:""`
|
||||
RenderService rendering.Service `inject:""`
|
||||
Cfg *setting.Cfg `inject:""`
|
||||
HooksService *hooks.HooksService `inject:""`
|
||||
CacheService *localcache.CacheService `inject:""`
|
||||
DatasourceCache datasources.CacheService `inject:""`
|
||||
AuthTokenService models.UserTokenService `inject:""`
|
||||
QuotaService *quota.QuotaService `inject:""`
|
||||
RemoteCacheService *remotecache.RemoteCache `inject:""`
|
||||
ProvisioningService ProvisioningService `inject:""`
|
||||
Login *login.LoginService `inject:""`
|
||||
License models.Licensing `inject:""`
|
||||
RouteRegister routing.RouteRegister `inject:""`
|
||||
Bus bus.Bus `inject:""`
|
||||
RenderService rendering.Service `inject:""`
|
||||
Cfg *setting.Cfg `inject:""`
|
||||
HooksService *hooks.HooksService `inject:""`
|
||||
CacheService *localcache.CacheService `inject:""`
|
||||
DatasourceCache datasources.CacheService `inject:""`
|
||||
AuthTokenService models.UserTokenService `inject:""`
|
||||
QuotaService *quota.QuotaService `inject:""`
|
||||
RemoteCacheService *remotecache.RemoteCache `inject:""`
|
||||
ProvisioningService ProvisioningService `inject:""`
|
||||
Login *login.LoginService `inject:""`
|
||||
License models.Licensing `inject:""`
|
||||
BackendPluginManager backendplugin.Manager `inject:""`
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) Init() error {
|
||||
|
@ -3,6 +3,8 @@ package api
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
@ -200,3 +202,74 @@ func ImportDashboard(c *m.ReqContext, apiCmd dtos.ImportDashboardCommand) Respon
|
||||
|
||||
return JSON(200, cmd.Result)
|
||||
}
|
||||
|
||||
// /api/plugins/:pluginId/health
|
||||
func (hs *HTTPServer) CheckHealth(c *m.ReqContext) Response {
|
||||
pluginID := c.Params("pluginId")
|
||||
resp, err := hs.BackendPluginManager.CheckHealth(c.Req.Context(), pluginID)
|
||||
if err != nil {
|
||||
if err == backendplugin.ErrPluginNotRegistered {
|
||||
return Error(404, "Plugin not found", err)
|
||||
}
|
||||
|
||||
// Return status unknown instead?
|
||||
if err == backendplugin.ErrDiagnosticsNotSupported {
|
||||
return Error(404, "Health check not implemented", err)
|
||||
}
|
||||
|
||||
// Return status unknown or error instead?
|
||||
if err == backendplugin.ErrHealthCheckFailed {
|
||||
return Error(500, "Plugin health check failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"status": resp.Status.String(),
|
||||
"info": resp.Info,
|
||||
}
|
||||
|
||||
if resp.Status != backendplugin.HealthStatusOk {
|
||||
return JSON(503, payload)
|
||||
}
|
||||
|
||||
return JSON(200, payload)
|
||||
}
|
||||
|
||||
// /api/plugins/:pluginId/resources/*
|
||||
func (hs *HTTPServer) CallResource(c *m.ReqContext) Response {
|
||||
pluginID := c.Params("pluginId")
|
||||
_, exists := plugins.Plugins[pluginID]
|
||||
if !exists {
|
||||
return Error(404, "Plugin not found, no installed plugin with that id", nil)
|
||||
}
|
||||
|
||||
body, err := c.Req.Body().Bytes()
|
||||
if err != nil {
|
||||
return Error(500, "Failed to read request body", err)
|
||||
}
|
||||
req := backendplugin.CallResourceRequest{
|
||||
Config: backendplugin.PluginConfig{
|
||||
OrgID: c.OrgId,
|
||||
PluginID: pluginID,
|
||||
},
|
||||
Path: c.Params("*"),
|
||||
Method: c.Req.Method,
|
||||
URL: c.Req.URL.String(),
|
||||
Headers: c.Req.Header.Clone(),
|
||||
Body: body,
|
||||
}
|
||||
resp, err := hs.BackendPluginManager.CallResource(c.Req.Context(), req)
|
||||
if err != nil {
|
||||
return Error(500, "Failed to call resource", err)
|
||||
}
|
||||
|
||||
if resp.Status >= 400 {
|
||||
return Error(resp.Status, "", nil)
|
||||
}
|
||||
|
||||
return &NormalResponse{
|
||||
body: resp.Body,
|
||||
status: resp.Status,
|
||||
header: resp.Headers,
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
@ -14,7 +15,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"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/collector"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
@ -31,7 +31,8 @@ type BackendPlugin struct {
|
||||
client *plugin.Client
|
||||
logger log.Logger
|
||||
startFns PluginStartFuncs
|
||||
diagnostics backend.DiagnosticsPlugin
|
||||
diagnostics DiagnosticsPlugin
|
||||
core CorePlugin
|
||||
}
|
||||
|
||||
func (p *BackendPlugin) start(ctx context.Context) error {
|
||||
@ -61,20 +62,21 @@ func (p *BackendPlugin) start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if rawDiagnostics != nil {
|
||||
if plugin, ok := rawDiagnostics.(backend.DiagnosticsPlugin); ok {
|
||||
if plugin, ok := rawDiagnostics.(DiagnosticsPlugin); ok {
|
||||
p.diagnostics = plugin
|
||||
}
|
||||
}
|
||||
|
||||
client = &Client{}
|
||||
if rawBackend != nil {
|
||||
if plugin, ok := rawBackend.(backend.BackendPlugin); ok {
|
||||
client.BackendPlugin = plugin
|
||||
if plugin, ok := rawBackend.(CorePlugin); ok {
|
||||
p.core = plugin
|
||||
client.DatasourcePlugin = plugin
|
||||
}
|
||||
}
|
||||
|
||||
if rawTransform != nil {
|
||||
if plugin, ok := rawTransform.(backend.TransformPlugin); ok {
|
||||
if plugin, ok := rawTransform.(TransformPlugin); ok {
|
||||
client.TransformPlugin = plugin
|
||||
}
|
||||
}
|
||||
@ -194,6 +196,47 @@ func (p *BackendPlugin) checkHealth(ctx context.Context) (*pluginv2.CheckHealth_
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (p *BackendPlugin) callResource(ctx context.Context, req CallResourceRequest) (*CallResourceResult, error) {
|
||||
p.logger.Debug("Calling resource", "path", req.Path, "method", req.Method)
|
||||
|
||||
reqHeaders := map[string]*pluginv2.CallResource_StringList{}
|
||||
for k, v := range req.Headers {
|
||||
reqHeaders[k] = &pluginv2.CallResource_StringList{Values: v}
|
||||
}
|
||||
|
||||
protoReq := &pluginv2.CallResource_Request{
|
||||
Config: &pluginv2.PluginConfig{},
|
||||
Path: req.Path,
|
||||
Method: req.Method,
|
||||
Url: req.URL,
|
||||
Headers: reqHeaders,
|
||||
Body: req.Body,
|
||||
}
|
||||
protoResp, err := p.core.CallResource(ctx, protoReq)
|
||||
if err != nil {
|
||||
if st, ok := status.FromError(err); ok {
|
||||
if st.Code() == codes.Unimplemented {
|
||||
return &CallResourceResult{
|
||||
Status: http.StatusNotImplemented,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errutil.Wrap("Failed to call resource", err)
|
||||
}
|
||||
|
||||
respHeaders := map[string][]string{}
|
||||
for key, values := range protoResp.Headers {
|
||||
respHeaders[key] = values.Values
|
||||
}
|
||||
|
||||
return &CallResourceResult{
|
||||
Headers: respHeaders,
|
||||
Body: protoResp.Body,
|
||||
Status: int(protoResp.Code),
|
||||
}, 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) {
|
||||
|
@ -1,14 +1,17 @@
|
||||
package backendplugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/plugin"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
|
||||
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/hashicorp/go-plugin"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
goplugin "github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -19,24 +22,24 @@ const (
|
||||
)
|
||||
|
||||
// Handshake is the HandshakeConfig used to configure clients and servers.
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
var handshake = goplugin.HandshakeConfig{
|
||||
// The ProtocolVersion is the version that must match between Grafana core
|
||||
// and Grafana plugins. This should be bumped whenever a (breaking) change
|
||||
// happens in one or the other that makes it so that they can't safely communicate.
|
||||
ProtocolVersion: DefaultProtocolVersion,
|
||||
|
||||
// The magic cookie values should NEVER be changed.
|
||||
MagicCookieKey: backend.MagicCookieKey,
|
||||
MagicCookieValue: backend.MagicCookieValue,
|
||||
MagicCookieKey: plugin.MagicCookieKey,
|
||||
MagicCookieValue: plugin.MagicCookieValue,
|
||||
}
|
||||
|
||||
func newClientConfig(executablePath string, logger log.Logger, versionedPlugins map[int]plugin.PluginSet) *plugin.ClientConfig {
|
||||
return &plugin.ClientConfig{
|
||||
func newClientConfig(executablePath string, logger log.Logger, versionedPlugins map[int]goplugin.PluginSet) *goplugin.ClientConfig {
|
||||
return &goplugin.ClientConfig{
|
||||
Cmd: exec.Command(executablePath),
|
||||
HandshakeConfig: handshake,
|
||||
VersionedPlugins: versionedPlugins,
|
||||
Logger: logWrapper{Logger: logger},
|
||||
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
|
||||
AllowedProtocols: []goplugin.Protocol{goplugin.ProtocolGRPC},
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +60,7 @@ type PluginDescriptor struct {
|
||||
pluginID string
|
||||
executablePath string
|
||||
managed bool
|
||||
versionedPlugins map[int]plugin.PluginSet
|
||||
versionedPlugins map[int]goplugin.PluginSet
|
||||
startFns PluginStartFuncs
|
||||
}
|
||||
|
||||
@ -68,14 +71,14 @@ func NewBackendPluginDescriptor(pluginID, executablePath string, startFns Plugin
|
||||
pluginID: pluginID,
|
||||
executablePath: executablePath,
|
||||
managed: true,
|
||||
versionedPlugins: map[int]plugin.PluginSet{
|
||||
versionedPlugins: map[int]goplugin.PluginSet{
|
||||
DefaultProtocolVersion: {
|
||||
pluginID: &datasourceV1.DatasourcePluginImpl{},
|
||||
},
|
||||
backend.ProtocolVersion: {
|
||||
"diagnostics": &backend.DiagnosticsGRPCPlugin{},
|
||||
"backend": &backend.CoreGRPCPlugin{},
|
||||
"transform": &backend.TransformGRPCPlugin{},
|
||||
plugin.ProtocolVersion: {
|
||||
"diagnostics": &plugin.DiagnosticsGRPCPlugin{},
|
||||
"backend": &plugin.CoreGRPCPlugin{},
|
||||
"transform": &plugin.TransformGRPCPlugin{},
|
||||
},
|
||||
},
|
||||
startFns: startFns,
|
||||
@ -89,7 +92,7 @@ func NewRendererPluginDescriptor(pluginID, executablePath string, startFns Plugi
|
||||
pluginID: pluginID,
|
||||
executablePath: executablePath,
|
||||
managed: false,
|
||||
versionedPlugins: map[int]plugin.PluginSet{
|
||||
versionedPlugins: map[int]goplugin.PluginSet{
|
||||
DefaultProtocolVersion: {
|
||||
pluginID: &rendererV1.RendererPluginImpl{},
|
||||
},
|
||||
@ -98,6 +101,28 @@ func NewRendererPluginDescriptor(pluginID, executablePath string, startFns Plugi
|
||||
}
|
||||
}
|
||||
|
||||
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 DatasourcePlugin interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
type CorePlugin interface {
|
||||
CallResource(ctx context.Context, req *pluginv2.CallResource_Request) (*pluginv2.CallResource_Response, error)
|
||||
DatasourcePlugin
|
||||
}
|
||||
|
||||
type TransformCallBack interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
type TransformPlugin interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest, callback TransformCallBack) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
// LegacyClient client for communicating with a plugin using the old plugin protocol.
|
||||
type LegacyClient struct {
|
||||
DatasourcePlugin datasourceV1.DatasourcePlugin
|
||||
@ -106,7 +131,6 @@ type LegacyClient struct {
|
||||
|
||||
// Client client for communicating with a plugin using the current plugin protocol.
|
||||
type Client struct {
|
||||
DiagnosticsPlugin backend.DiagnosticsPlugin
|
||||
BackendPlugin backend.BackendPlugin
|
||||
TransformPlugin backend.TransformPlugin
|
||||
DatasourcePlugin DatasourcePlugin
|
||||
TransformPlugin TransformPlugin
|
||||
}
|
||||
|
85
pkg/plugins/backendplugin/contracts.go
Normal file
85
pkg/plugins/backendplugin/contracts.go
Normal file
@ -0,0 +1,85 @@
|
||||
package backendplugin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
)
|
||||
|
||||
// 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
|
||||
)
|
||||
|
||||
var healthStatusNames = map[int]string{
|
||||
0: "UNKNOWN",
|
||||
1: "OK",
|
||||
2: "ERROR",
|
||||
}
|
||||
|
||||
func (hs HealthStatus) String() string {
|
||||
s, exists := healthStatusNames[int(hs)]
|
||||
if exists {
|
||||
return s
|
||||
}
|
||||
return strconv.Itoa(int(hs))
|
||||
}
|
||||
|
||||
// CheckHealthResult check health result.
|
||||
type CheckHealthResult struct {
|
||||
Status HealthStatus
|
||||
Info string
|
||||
}
|
||||
|
||||
func checkHealthResultFromProto(protoResp *pluginv2.CheckHealth_Response) *CheckHealthResult {
|
||||
status := HealthStatusUnknown
|
||||
switch protoResp.Status {
|
||||
case pluginv2.CheckHealth_Response_ERROR:
|
||||
status = HealthStatusError
|
||||
case pluginv2.CheckHealth_Response_OK:
|
||||
status = HealthStatusOk
|
||||
}
|
||||
|
||||
return &CheckHealthResult{
|
||||
Status: status,
|
||||
Info: protoResp.Info,
|
||||
}
|
||||
}
|
||||
|
||||
type PluginInstance struct {
|
||||
ID int64
|
||||
Name string
|
||||
Type string
|
||||
URL string
|
||||
JSONData json.RawMessage
|
||||
}
|
||||
|
||||
type PluginConfig struct {
|
||||
PluginID string
|
||||
OrgID int64
|
||||
Instance *PluginInstance
|
||||
}
|
||||
|
||||
type CallResourceRequest struct {
|
||||
Config PluginConfig
|
||||
Path string
|
||||
Method string
|
||||
URL string
|
||||
Headers map[string][]string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
// CallResourceResult call resource result.
|
||||
type CallResourceResult struct {
|
||||
Status int
|
||||
Headers map[string][]string
|
||||
Body []byte
|
||||
}
|
@ -6,19 +6,24 @@ 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"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrPluginNotRegistered error returned when plugin not registered.
|
||||
ErrPluginNotRegistered = errors.New("Plugin not registered")
|
||||
// ErrDiagnosticsNotSupported error returned when plugin doesn't support diagnostics.
|
||||
ErrDiagnosticsNotSupported = errors.New("Plugin diagnostics not supported")
|
||||
// ErrHealthCheckFailed error returned when health check failed.
|
||||
ErrHealthCheckFailed = errors.New("Health check failed")
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register(®istry.Descriptor{
|
||||
Name: "BackendPluginManager",
|
||||
@ -33,10 +38,13 @@ type Manager interface {
|
||||
Register(descriptor PluginDescriptor) error
|
||||
// StartPlugin starts a non-managed backend plugin
|
||||
StartPlugin(ctx context.Context, pluginID string) error
|
||||
// CheckHealth checks the health of a registered backend plugin.
|
||||
CheckHealth(ctx context.Context, pluginID string) (*CheckHealthResult, error)
|
||||
// CallResource calls a plugin resource.
|
||||
CallResource(ctx context.Context, req CallResourceRequest) (*CallResourceResult, error)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
RouteRegister routing.RouteRegister `inject:""`
|
||||
pluginsMu sync.RWMutex
|
||||
plugins map[string]*BackendPlugin
|
||||
pluginCollector collector.PluginCollector
|
||||
@ -49,8 +57,6 @@ func (m *manager) Init() error {
|
||||
m.pluginCollector = collector.NewPluginCollector()
|
||||
prometheus.MustRegister(m.pluginCollector)
|
||||
|
||||
m.RouteRegister.Get("/api/plugins/:pluginId/health", m.checkHealth)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -140,38 +146,50 @@ func (m *manager) stop() {
|
||||
}
|
||||
}
|
||||
|
||||
// checkHealth http handler for checking plugin health.
|
||||
func (m *manager) checkHealth(c *models.ReqContext) {
|
||||
pluginID := c.Params("pluginId")
|
||||
// CheckHealth checks the health of a registered backend plugin.
|
||||
func (m *manager) CheckHealth(ctx context.Context, pluginID string) (*CheckHealthResult, error) {
|
||||
m.pluginsMu.RLock()
|
||||
p, registered := m.plugins[pluginID]
|
||||
m.pluginsMu.RUnlock()
|
||||
|
||||
if !registered || !p.supportsDiagnostics() {
|
||||
c.JsonApiErr(404, "Plugin not found", nil)
|
||||
return
|
||||
if !registered {
|
||||
return nil, ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
res, err := p.checkHealth(c.Req.Context())
|
||||
if !p.supportsDiagnostics() {
|
||||
return nil, ErrDiagnosticsNotSupported
|
||||
}
|
||||
|
||||
res, err := p.checkHealth(ctx)
|
||||
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
|
||||
return nil, ErrHealthCheckFailed
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"status": res.Status.String(),
|
||||
"info": res.Info,
|
||||
return checkHealthResultFromProto(res), nil
|
||||
}
|
||||
|
||||
// CallResource calls a plugin resource.
|
||||
func (m *manager) CallResource(ctx context.Context, req CallResourceRequest) (*CallResourceResult, error) {
|
||||
m.pluginsMu.RLock()
|
||||
p, registered := m.plugins[req.Config.PluginID]
|
||||
m.pluginsMu.RUnlock()
|
||||
|
||||
if !registered {
|
||||
return nil, ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
if res.Status != pluginv2.CheckHealth_Response_OK {
|
||||
c.JSON(503, payload)
|
||||
return
|
||||
res, err := p.callResource(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.JSON(200, payload)
|
||||
// Make sure a content type always is returned in response
|
||||
if _, exists := res.Headers["Content-Type"]; !exists {
|
||||
res.Headers["Content-Type"] = []string{"application/json"}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func startPluginAndRestartKilledProcesses(ctx context.Context, p *BackendPlugin) error {
|
||||
|
137
pkg/plugins/backendplugin/resource/response_writer.go
Normal file
137
pkg/plugins/backendplugin/resource/response_writer.go
Normal file
@ -0,0 +1,137 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
)
|
||||
|
||||
// ResourceResponseWriter is an implementation of http.ResponseWriter that
|
||||
// records its mutations for later inspection in tests.
|
||||
type ResourceResponseWriter struct {
|
||||
// Code is the HTTP response code set by WriteHeader.
|
||||
//
|
||||
// Note that if a Handler never calls WriteHeader or Write,
|
||||
// this might end up being 0, rather than the implicit
|
||||
// http.StatusOK. To get the implicit value, use the Result
|
||||
// method.
|
||||
Code int
|
||||
|
||||
// HeaderMap contains the headers explicitly set by the Handler.
|
||||
// It is an internal detail.
|
||||
//
|
||||
// Deprecated: HeaderMap exists for historical compatibility
|
||||
// and should not be used. To access the headers returned by a handler,
|
||||
// use the Response.Header map as returned by the Result method.
|
||||
HeaderMap http.Header
|
||||
|
||||
// Body is the buffer to which the Handler's Write calls are sent.
|
||||
// If nil, the Writes are silently discarded.
|
||||
Body *bytes.Buffer
|
||||
|
||||
// Flushed is whether the Handler called Flush.
|
||||
Flushed bool
|
||||
|
||||
wroteHeader bool
|
||||
}
|
||||
|
||||
// NewResourceResponseWriter returns an initialized ResponseWriter.
|
||||
func NewResourceResponseWriter() *ResourceResponseWriter {
|
||||
return &ResourceResponseWriter{
|
||||
HeaderMap: make(http.Header),
|
||||
Body: new(bytes.Buffer),
|
||||
Code: 200,
|
||||
}
|
||||
}
|
||||
|
||||
// Header implements http.ResponseWriter. It returns the response
|
||||
// headers to mutate within a handler. To test the headers that were
|
||||
// written after a handler completes, use the Result method and see
|
||||
// the returned Response value's Header.
|
||||
func (rw *ResourceResponseWriter) Header() http.Header {
|
||||
m := rw.HeaderMap
|
||||
if m == nil {
|
||||
m = make(http.Header)
|
||||
rw.HeaderMap = m
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// writeHeader writes a header if it was not written yet and
|
||||
// detects Content-Type if needed.
|
||||
//
|
||||
// bytes or str are the beginning of the response body.
|
||||
// We pass both to avoid unnecessarily generate garbage
|
||||
// in rw.WriteString which was created for performance reasons.
|
||||
// Non-nil bytes win.
|
||||
func (rw *ResourceResponseWriter) writeHeader(b []byte, str string) {
|
||||
if rw.wroteHeader {
|
||||
return
|
||||
}
|
||||
if len(str) > 512 {
|
||||
str = str[:512]
|
||||
}
|
||||
|
||||
m := rw.Header()
|
||||
|
||||
_, hasType := m["Content-Type"]
|
||||
hasTE := m.Get("Transfer-Encoding") != ""
|
||||
if !hasType && !hasTE {
|
||||
if b == nil {
|
||||
b = []byte(str)
|
||||
}
|
||||
m.Set("Content-Type", http.DetectContentType(b))
|
||||
}
|
||||
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
// Write implements http.ResponseWriter. The data in buf is written to
|
||||
// rw.Body, if not nil.
|
||||
func (rw *ResourceResponseWriter) Write(buf []byte) (int, error) {
|
||||
rw.writeHeader(buf, "")
|
||||
if rw.Body != nil {
|
||||
rw.Body.Write(buf)
|
||||
}
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
// WriteHeader implements http.ResponseWriter.
|
||||
func (rw *ResourceResponseWriter) WriteHeader(code int) {
|
||||
if rw.wroteHeader {
|
||||
return
|
||||
}
|
||||
rw.Code = code
|
||||
rw.wroteHeader = true
|
||||
if rw.HeaderMap == nil {
|
||||
rw.HeaderMap = make(http.Header)
|
||||
}
|
||||
}
|
||||
|
||||
// Flush implements http.Flusher.
|
||||
func (rw *ResourceResponseWriter) Flush() {
|
||||
if !rw.wroteHeader {
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
}
|
||||
|
||||
// Result returns the response generated by the handler.
|
||||
func (rw *ResourceResponseWriter) Result() *pluginv2.CallResource_Response {
|
||||
res := &pluginv2.CallResource_Response{
|
||||
Code: int32(rw.Code),
|
||||
Headers: map[string]*pluginv2.CallResource_StringList{},
|
||||
}
|
||||
|
||||
if rw.Body != nil {
|
||||
res.Body = rw.Body.Bytes()
|
||||
}
|
||||
|
||||
for key, values := range rw.Header().Clone() {
|
||||
res.Headers[key] = &pluginv2.CallResource_StringList{
|
||||
Values: values,
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
@ -3,7 +3,8 @@ package wrapper
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@ -11,12 +12,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/tsdb"
|
||||
)
|
||||
|
||||
func NewDatasourcePluginWrapperV2(log log.Logger, plugin sdk.BackendPlugin) *DatasourcePluginWrapperV2 {
|
||||
return &DatasourcePluginWrapperV2{BackendPlugin: plugin, logger: log}
|
||||
func NewDatasourcePluginWrapperV2(log log.Logger, plugin backendplugin.DatasourcePlugin) *DatasourcePluginWrapperV2 {
|
||||
return &DatasourcePluginWrapperV2{DatasourcePlugin: plugin, logger: log}
|
||||
}
|
||||
|
||||
type DatasourcePluginWrapperV2 struct {
|
||||
sdk.BackendPlugin
|
||||
backendplugin.DatasourcePlugin
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ func (tw *DatasourcePluginWrapperV2) Query(ctx context.Context, ds *models.DataS
|
||||
})
|
||||
}
|
||||
|
||||
pbRes, err := tw.BackendPlugin.DataQuery(ctx, pbQuery)
|
||||
pbRes, err := tw.DatasourcePlugin.DataQuery(ctx, pbQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ func (p *DataSourcePlugin) onLegacyPluginStart(pluginID string, client *backendp
|
||||
}
|
||||
|
||||
func (p *DataSourcePlugin) onPluginStart(pluginID string, client *backendplugin.Client, logger log.Logger) error {
|
||||
if client.BackendPlugin != nil {
|
||||
if client.DatasourcePlugin != nil {
|
||||
tsdb.RegisterTsdbQueryEndpoint(pluginID, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapperV2(logger, client.BackendPlugin), nil
|
||||
return wrapper.NewDatasourcePluginWrapperV2(logger, client.DatasourcePlugin), nil
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/dataframe"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@ -54,9 +53,9 @@ func (p *TransformPlugin) Load(decoder *json.Decoder, pluginDir string, backendP
|
||||
func (p *TransformPlugin) onPluginStart(pluginID string, client *backendplugin.Client, logger log.Logger) error {
|
||||
p.TransformWrapper = NewTransformWrapper(logger, client.TransformPlugin)
|
||||
|
||||
if client.BackendPlugin != nil {
|
||||
if client.DatasourcePlugin != nil {
|
||||
tsdb.RegisterTsdbQueryEndpoint(pluginID, func(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
|
||||
return wrapper.NewDatasourcePluginWrapperV2(logger, client.BackendPlugin), nil
|
||||
return wrapper.NewDatasourcePluginWrapperV2(logger, client.DatasourcePlugin), nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -67,12 +66,12 @@ func (p *TransformPlugin) onPluginStart(pluginID string, client *backendplugin.C
|
||||
// Wrapper Code
|
||||
// ...
|
||||
|
||||
func NewTransformWrapper(log log.Logger, plugin backend.TransformPlugin) *TransformWrapper {
|
||||
func NewTransformWrapper(log log.Logger, plugin backendplugin.TransformPlugin) *TransformWrapper {
|
||||
return &TransformWrapper{plugin, log, &transformCallback{log}}
|
||||
}
|
||||
|
||||
type TransformWrapper struct {
|
||||
backend.TransformPlugin
|
||||
backendplugin.TransformPlugin
|
||||
logger log.Logger
|
||||
callback *transformCallback
|
||||
}
|
||||
|
215
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go
generated
vendored
215
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/core.go
generated
vendored
@ -1,215 +0,0 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/dataframe"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
)
|
||||
|
||||
// PluginConfig holds configuration for the queried plugin.
|
||||
type PluginConfig struct {
|
||||
ID int64
|
||||
OrgID int64
|
||||
Name string
|
||||
Type string
|
||||
URL string
|
||||
JSONData json.RawMessage
|
||||
}
|
||||
|
||||
// PluginConfigFromProto converts the generated protobuf PluginConfig to this
|
||||
// package's PluginConfig.
|
||||
func pluginConfigFromProto(pc *pluginv2.PluginConfig) PluginConfig {
|
||||
return PluginConfig{
|
||||
ID: pc.Id,
|
||||
OrgID: pc.OrgId,
|
||||
Name: pc.Name,
|
||||
Type: pc.Type,
|
||||
URL: pc.Url,
|
||||
JSONData: json.RawMessage([]byte(pc.JsonData)),
|
||||
}
|
||||
}
|
||||
|
||||
func (pc PluginConfig) toProtobuf() *pluginv2.PluginConfig {
|
||||
return &pluginv2.PluginConfig{
|
||||
Id: pc.ID,
|
||||
OrgId: pc.OrgID,
|
||||
Name: pc.Name,
|
||||
Type: pc.Type,
|
||||
Url: pc.URL,
|
||||
JsonData: string(pc.JSONData),
|
||||
}
|
||||
}
|
||||
|
||||
type DataQueryRequest struct {
|
||||
PluginConfig PluginConfig
|
||||
Headers map[string]string
|
||||
Queries []DataQuery
|
||||
}
|
||||
|
||||
func dataQueryRequestFromProto(pc *pluginv2.DataQueryRequest) *DataQueryRequest {
|
||||
queries := make([]DataQuery, len(pc.Queries))
|
||||
for i, q := range pc.Queries {
|
||||
queries[i] = *dataQueryFromProtobuf(q)
|
||||
}
|
||||
return &DataQueryRequest{
|
||||
PluginConfig: pluginConfigFromProto(pc.Config),
|
||||
Headers: pc.Headers,
|
||||
Queries: queries,
|
||||
}
|
||||
}
|
||||
|
||||
func (dr *DataQueryRequest) toProtobuf() *pluginv2.DataQueryRequest {
|
||||
queries := make([]*pluginv2.DataQuery, len(dr.Queries))
|
||||
for i, q := range dr.Queries {
|
||||
queries[i] = q.toProtobuf()
|
||||
}
|
||||
return &pluginv2.DataQueryRequest{
|
||||
Config: dr.PluginConfig.toProtobuf(),
|
||||
Headers: dr.Headers,
|
||||
Queries: queries,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DataQuery represents the query as sent from the frontend.
|
||||
type DataQuery struct {
|
||||
RefID string
|
||||
MaxDataPoints int64
|
||||
Interval time.Duration
|
||||
TimeRange TimeRange
|
||||
JSON json.RawMessage
|
||||
}
|
||||
|
||||
func (q *DataQuery) toProtobuf() *pluginv2.DataQuery {
|
||||
return &pluginv2.DataQuery{
|
||||
RefId: q.RefID,
|
||||
MaxDataPoints: q.MaxDataPoints,
|
||||
IntervalMS: q.Interval.Microseconds(),
|
||||
TimeRange: q.TimeRange.toProtobuf(),
|
||||
Json: q.JSON,
|
||||
}
|
||||
}
|
||||
|
||||
func dataQueryFromProtobuf(q *pluginv2.DataQuery) *DataQuery {
|
||||
return &DataQuery{
|
||||
RefID: q.RefId,
|
||||
MaxDataPoints: q.MaxDataPoints,
|
||||
TimeRange: timeRangeFromProtobuf(q.TimeRange),
|
||||
Interval: time.Duration(q.IntervalMS) * time.Millisecond,
|
||||
JSON: []byte(q.Json),
|
||||
}
|
||||
}
|
||||
|
||||
// DataQueryResponse holds the results for a given query.
|
||||
type DataQueryResponse struct {
|
||||
Frames []*dataframe.Frame
|
||||
Metadata map[string]string
|
||||
}
|
||||
|
||||
func (res *DataQueryResponse) toProtobuf() (*pluginv2.DataQueryResponse, error) {
|
||||
encodedFrames := make([][]byte, len(res.Frames))
|
||||
var err error
|
||||
for i, frame := range res.Frames {
|
||||
encodedFrames[i], err = dataframe.MarshalArrow(frame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &pluginv2.DataQueryResponse{
|
||||
Frames: encodedFrames,
|
||||
Metadata: res.Metadata,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dataQueryResponseFromProtobuf(res *pluginv2.DataQueryResponse) (*DataQueryResponse, error) {
|
||||
frames := make([]*dataframe.Frame, len(res.Frames))
|
||||
var err error
|
||||
for i, encodedFrame := range res.Frames {
|
||||
frames[i], err = dataframe.UnmarshalArrow(encodedFrame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &DataQueryResponse{Metadata: res.Metadata, Frames: frames}, nil
|
||||
}
|
||||
|
||||
// TimeRange represents a time range for a query.
|
||||
type TimeRange struct {
|
||||
From time.Time
|
||||
To time.Time
|
||||
}
|
||||
|
||||
func (tr *TimeRange) toProtobuf() *pluginv2.TimeRange {
|
||||
return &pluginv2.TimeRange{
|
||||
FromEpochMS: tr.From.UnixNano() / int64(time.Millisecond),
|
||||
ToEpochMS: tr.To.UnixNano() / int64(time.Millisecond),
|
||||
}
|
||||
}
|
||||
|
||||
// TimeRangeFromProtobuf converts the generated protobuf TimeRange to this
|
||||
// package's FetchInfo.
|
||||
func timeRangeFromProtobuf(tr *pluginv2.TimeRange) TimeRange {
|
||||
return TimeRange{
|
||||
From: time.Unix(0, tr.FromEpochMS*int64(time.Millisecond)),
|
||||
To: time.Unix(0, tr.ToEpochMS*int64(time.Millisecond)),
|
||||
}
|
||||
}
|
||||
|
||||
type ResourceRequest struct {
|
||||
PluginConfig PluginConfig
|
||||
Headers map[string]string
|
||||
Method string
|
||||
Path string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
func resourceRequestFromProtobuf(req *pluginv2.ResourceRequest) *ResourceRequest {
|
||||
return &ResourceRequest{
|
||||
PluginConfig: pluginConfigFromProto(req.Config),
|
||||
Headers: req.Headers,
|
||||
Method: req.Method,
|
||||
Path: req.Path,
|
||||
Body: req.Body,
|
||||
}
|
||||
}
|
||||
|
||||
type ResourceResponse struct {
|
||||
Headers map[string]string
|
||||
Code int32
|
||||
Body []byte
|
||||
}
|
||||
|
||||
func (rr *ResourceResponse) toProtobuf() *pluginv2.ResourceResponse {
|
||||
return &pluginv2.ResourceResponse{
|
||||
Headers: rr.Headers,
|
||||
Code: rr.Code,
|
||||
Body: rr.Body,
|
||||
}
|
||||
}
|
||||
|
||||
// DataQueryHandler handles data source queries.
|
||||
type DataQueryHandler interface {
|
||||
DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error)
|
||||
}
|
||||
|
||||
// ResourceHandler handles backend plugin checks.
|
||||
type ResourceHandler interface {
|
||||
Resource(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error)
|
||||
}
|
||||
|
||||
// PluginHandlers is the collection of handlers that corresponds to the
|
||||
// grpc "service BackendPlugin".
|
||||
type PluginHandlers interface {
|
||||
DataQueryHandler
|
||||
ResourceHandler
|
||||
}
|
||||
|
||||
// BackendPlugin is the Grafana backend plugin interface.
|
||||
type BackendPlugin interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error)
|
||||
Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error)
|
||||
}
|
53
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go
generated
vendored
53
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/diagnostics.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
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,
|
||||
}
|
||||
}
|
15
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/handshake.go
generated
vendored
15
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/handshake.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package backend
|
||||
|
||||
import plugin "github.com/hashicorp/go-plugin"
|
||||
|
||||
const (
|
||||
MagicCookieKey = "grafana_plugin_type"
|
||||
MagicCookieValue = "datasource"
|
||||
ProtocolVersion = 2
|
||||
)
|
||||
|
||||
var Handshake = plugin.HandshakeConfig{
|
||||
ProtocolVersion: ProtocolVersion,
|
||||
MagicCookieKey: MagicCookieKey,
|
||||
MagicCookieValue: MagicCookieValue,
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package backend
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -8,16 +8,20 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type CoreServer interface {
|
||||
pluginv2.CoreServer
|
||||
}
|
||||
|
||||
// CoreGRPCPlugin implements the GRPCPlugin interface from github.com/hashicorp/go-plugin.
|
||||
type CoreGRPCPlugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
plugin.GRPCPlugin
|
||||
server pluginv2.CoreServer
|
||||
CoreServer CoreServer
|
||||
}
|
||||
|
||||
func (p *CoreGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
pluginv2.RegisterCoreServer(s, &coreGRPCServer{
|
||||
server: p.server,
|
||||
server: p.CoreServer,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -27,15 +31,15 @@ func (p *CoreGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBrok
|
||||
}
|
||||
|
||||
type coreGRPCServer struct {
|
||||
server pluginv2.CoreServer
|
||||
server CoreServer
|
||||
}
|
||||
|
||||
func (s *coreGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
return s.server.DataQuery(ctx, req)
|
||||
}
|
||||
|
||||
func (s *coreGRPCServer) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) {
|
||||
return s.server.Resource(ctx, req)
|
||||
func (s *coreGRPCServer) CallResource(ctx context.Context, req *pluginv2.CallResource_Request) (*pluginv2.CallResource_Response, error) {
|
||||
return s.server.CallResource(ctx, req)
|
||||
}
|
||||
|
||||
type coreGRPCClient struct {
|
||||
@ -46,6 +50,9 @@ func (m *coreGRPCClient) DataQuery(ctx context.Context, req *pluginv2.DataQueryR
|
||||
return m.client.DataQuery(ctx, req)
|
||||
}
|
||||
|
||||
func (m *coreGRPCClient) Resource(ctx context.Context, req *pluginv2.ResourceRequest) (*pluginv2.ResourceResponse, error) {
|
||||
return m.client.Resource(ctx, req)
|
||||
func (m *coreGRPCClient) CallResource(ctx context.Context, req *pluginv2.CallResource_Request) (*pluginv2.CallResource_Response, error) {
|
||||
return m.client.CallResource(ctx, req)
|
||||
}
|
||||
|
||||
var _ CoreServer = &coreGRPCServer{}
|
||||
var _ CoreServer = &coreGRPCClient{}
|
@ -1,4 +1,4 @@
|
||||
package backend
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -8,16 +8,20 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type DiagnosticsServer interface {
|
||||
pluginv2.DiagnosticsServer
|
||||
}
|
||||
|
||||
// DiagnosticsGRPCPlugin implements the GRPCPlugin interface from github.com/hashicorp/go-plugin.
|
||||
type DiagnosticsGRPCPlugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
plugin.GRPCPlugin
|
||||
server pluginv2.DiagnosticsServer
|
||||
DiagnosticsServer DiagnosticsServer
|
||||
}
|
||||
|
||||
func (p *DiagnosticsGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
pluginv2.RegisterDiagnosticsServer(s, &diagnosticsGRPCServer{
|
||||
server: p.server,
|
||||
server: p.DiagnosticsServer,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -27,7 +31,7 @@ func (p *DiagnosticsGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.G
|
||||
}
|
||||
|
||||
type diagnosticsGRPCServer struct {
|
||||
server pluginv2.DiagnosticsServer
|
||||
server DiagnosticsServer
|
||||
}
|
||||
|
||||
func (s *diagnosticsGRPCServer) CollectMetrics(ctx context.Context, req *pluginv2.CollectMetrics_Request) (*pluginv2.CollectMetrics_Response, error) {
|
||||
@ -49,3 +53,6 @@ func (s *diagnosticsGRPCClient) CollectMetrics(ctx context.Context, req *pluginv
|
||||
func (s *diagnosticsGRPCClient) CheckHealth(ctx context.Context, req *pluginv2.CheckHealth_Request) (*pluginv2.CheckHealth_Response, error) {
|
||||
return s.client.CheckHealth(ctx, req)
|
||||
}
|
||||
|
||||
var _ DiagnosticsServer = &diagnosticsGRPCServer{}
|
||||
var _ DiagnosticsServer = &diagnosticsGRPCClient{}
|
@ -1,4 +1,4 @@
|
||||
package backend
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -11,17 +11,29 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
type TransformServer interface {
|
||||
TransformData(ctx context.Context, req *pluginv2.DataQueryRequest, callback TransformCallBack) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
type transformClient interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest, callback TransformCallBack) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
type TransformCallBack interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
// TransformGRPCPlugin implements the GRPCPlugin interface from github.com/hashicorp/go-plugin.
|
||||
type TransformGRPCPlugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
plugin.GRPCPlugin
|
||||
adapter *sdkAdapter
|
||||
TransformServer TransformServer
|
||||
}
|
||||
|
||||
func (p *TransformGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
pluginv2.RegisterTransformServer(s, &transformGRPCServer{
|
||||
adapter: p.adapter,
|
||||
broker: broker,
|
||||
server: p.TransformServer,
|
||||
broker: broker,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@ -31,8 +43,8 @@ func (p *TransformGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRP
|
||||
}
|
||||
|
||||
type transformGRPCServer struct {
|
||||
broker *plugin.GRPCBroker
|
||||
adapter *sdkAdapter
|
||||
broker *plugin.GRPCBroker
|
||||
server TransformServer
|
||||
}
|
||||
|
||||
func (t *transformGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
@ -53,8 +65,8 @@ func (t *transformGRPCServer) DataQuery(ctx context.Context, req *pluginv2.DataQ
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
api := &TransformCallBackGrpcClient{pluginv2.NewTransformCallBackClient(conn)}
|
||||
return t.adapter.TransformData(ctx, req, api)
|
||||
api := &transformCallBackGrpcClient{pluginv2.NewTransformCallBackClient(conn)}
|
||||
return t.server.TransformData(ctx, req, api)
|
||||
}
|
||||
|
||||
type transformGRPCClient struct {
|
||||
@ -63,7 +75,7 @@ type transformGRPCClient struct {
|
||||
}
|
||||
|
||||
func (t *transformGRPCClient) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest, callBack TransformCallBack) (*pluginv2.DataQueryResponse, error) {
|
||||
callBackServer := &TransformCallBackGrpcServer{Impl: callBack}
|
||||
callBackServer := &transformCallBackGrpcServer{Impl: callBack}
|
||||
|
||||
var s *grpc.Server
|
||||
serverFunc := func(opts []grpc.ServerOption) *grpc.Server {
|
||||
@ -83,18 +95,23 @@ func (t *transformGRPCClient) DataQuery(ctx context.Context, req *pluginv2.DataQ
|
||||
|
||||
// Callback
|
||||
|
||||
type TransformCallBackGrpcClient struct {
|
||||
client pluginv2.TransformCallBackClient
|
||||
}
|
||||
|
||||
func (t *TransformCallBackGrpcClient) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
return t.client.DataQuery(ctx, req)
|
||||
}
|
||||
|
||||
type TransformCallBackGrpcServer struct {
|
||||
type transformCallBackGrpcServer struct {
|
||||
Impl TransformCallBack
|
||||
}
|
||||
|
||||
func (g *TransformCallBackGrpcServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
func (g *transformCallBackGrpcServer) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
return g.Impl.DataQuery(ctx, req)
|
||||
}
|
||||
|
||||
type transformCallBackGrpcClient struct {
|
||||
client pluginv2.TransformCallBackClient
|
||||
}
|
||||
|
||||
func (t *transformCallBackGrpcClient) DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error) {
|
||||
return t.client.DataQuery(ctx, req)
|
||||
}
|
||||
|
||||
var _ pluginv2.TransformServer = &transformGRPCServer{}
|
||||
var _ transformClient = &transformGRPCClient{}
|
||||
var _ pluginv2.TransformServer = &transformCallBackGrpcServer{}
|
||||
var _ pluginv2.TransformServer = &transformCallBackGrpcClient{}
|
27
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/plugin/handshake.go
generated
vendored
Normal file
27
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/plugin/handshake.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProtocolVersion is the current (latest) supported protocol version.
|
||||
ProtocolVersion = 2
|
||||
|
||||
// MagicCookieKey is the the magic cookie key that will be used for negotiating
|
||||
// between plugin host and client.
|
||||
// Should NEVER be changed.
|
||||
MagicCookieKey = "grafana_plugin_type"
|
||||
|
||||
// MagicCookieValue is the the magic cookie value that will be used for negotiating
|
||||
// between plugin host and client.
|
||||
// Should NEVER be changed.
|
||||
MagicCookieValue = "datasource"
|
||||
)
|
||||
|
||||
// handshake is the HandshakeConfig used to configure clients and servers.
|
||||
var handshake = plugin.HandshakeConfig{
|
||||
ProtocolVersion: ProtocolVersion,
|
||||
MagicCookieKey: MagicCookieKey,
|
||||
MagicCookieValue: MagicCookieValue,
|
||||
}
|
55
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/plugin/serve.go
generated
vendored
Normal file
55
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/plugin/serve.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
//ServeOpts options for serving plugins.
|
||||
type ServeOpts struct {
|
||||
DiagnosticsServer DiagnosticsServer
|
||||
CoreServer CoreServer
|
||||
TransformServer TransformServer
|
||||
|
||||
// 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 opts.DiagnosticsServer != nil {
|
||||
pSet["diagnostics"] = &DiagnosticsGRPCPlugin{
|
||||
DiagnosticsServer: opts.DiagnosticsServer,
|
||||
}
|
||||
}
|
||||
|
||||
if opts.CoreServer != nil {
|
||||
pSet["backend"] = &CoreGRPCPlugin{
|
||||
CoreServer: opts.CoreServer,
|
||||
}
|
||||
}
|
||||
|
||||
if opts.TransformServer != nil {
|
||||
pSet["transform"] = &TransformGRPCPlugin{
|
||||
TransformServer: opts.TransformServer,
|
||||
}
|
||||
}
|
||||
|
||||
versionedPlugins[ProtocolVersion] = pSet
|
||||
|
||||
if opts.GRPCServer == nil {
|
||||
opts.GRPCServer = plugin.DefaultGRPCServer
|
||||
}
|
||||
|
||||
plugin.Serve(&plugin.ServeConfig{
|
||||
HandshakeConfig: handshake,
|
||||
VersionedPlugins: versionedPlugins,
|
||||
GRPCServer: opts.GRPCServer,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
91
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go
generated
vendored
91
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/sdk_adapter.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
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
|
||||
}
|
69
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go
generated
vendored
69
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/serve.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
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{
|
||||
server: sdkAdapter,
|
||||
}
|
||||
}
|
||||
|
||||
if opts.TransformDataHandler != nil {
|
||||
pSet["transform"] = &TransformGRPCPlugin{
|
||||
adapter: sdkAdapter,
|
||||
}
|
||||
}
|
||||
|
||||
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: Handshake,
|
||||
VersionedPlugins: versionedPlugins,
|
||||
GRPCServer: opts.GRPCServer,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
46
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go
generated
vendored
46
vendor/github.com/grafana/grafana-plugin-sdk-go/backend/transform.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
)
|
||||
|
||||
type TransformHandlers interface {
|
||||
TransformDataHandler
|
||||
}
|
||||
|
||||
type TransformDataHandler interface {
|
||||
TransformData(ctx context.Context, req *DataQueryRequest, callBack TransformCallBackHandler) (*DataQueryResponse, error)
|
||||
}
|
||||
|
||||
// Callback
|
||||
|
||||
type TransformCallBackHandler interface {
|
||||
// TODO: Forget if I actually need PluginConfig on the callback or not.
|
||||
DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error)
|
||||
}
|
||||
|
||||
type transformCallBackWrapper struct {
|
||||
callBack TransformCallBack
|
||||
}
|
||||
|
||||
func (tw *transformCallBackWrapper) DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error) {
|
||||
protoRes, err := tw.callBack.DataQuery(ctx, req.toProtobuf())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dataQueryResponseFromProtobuf(protoRes)
|
||||
}
|
||||
|
||||
// TransformPlugin is the Grafana transform plugin interface.
|
||||
type TransformPlugin interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest, callback TransformCallBack) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
||||
|
||||
// Callback
|
||||
|
||||
type TransformCallBack interface {
|
||||
DataQuery(ctx context.Context, req *pluginv2.DataQueryRequest) (*pluginv2.DataQueryResponse, error)
|
||||
}
|
21
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/arrow.go
generated
vendored
21
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/arrow.go
generated
vendored
@ -80,10 +80,14 @@ func buildArrowFields(f *Frame) ([]arrow.Field, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fieldMeta := map[string]string{
|
||||
"name": field.Name,
|
||||
"labels": field.Labels.String(),
|
||||
fieldMeta := map[string]string{"name": field.Name}
|
||||
|
||||
if field.Labels != nil {
|
||||
if fieldMeta["labels"], err = toJSONString(field.Labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if field.Config != nil {
|
||||
str, err := toJSONString(field.Config)
|
||||
if err != nil {
|
||||
@ -293,16 +297,12 @@ func initializeFrameFields(schema *arrow.Schema, frame *Frame) ([]bool, error) {
|
||||
Name: field.Name,
|
||||
}
|
||||
if labelsAsString, ok := getMDKey("labels", field.Metadata); ok {
|
||||
var err error
|
||||
sdkField.Labels, err = LabelsFromString(labelsAsString)
|
||||
if err != nil {
|
||||
if err := json.Unmarshal([]byte(labelsAsString), &sdkField.Labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if configAsString, ok := getMDKey("config", field.Metadata); ok {
|
||||
var err error
|
||||
sdkField.Config, err = FieldConfigFromJSON(configAsString)
|
||||
if err != nil {
|
||||
if err := json.Unmarshal([]byte(configAsString), &sdkField.Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -645,7 +645,8 @@ func UnmarshalArrow(b []byte) (*Frame, error) {
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
// ToJSONString return the FieldConfig as a json string
|
||||
// ToJSONString calls json.Marshal on val and returns it as a string. An
|
||||
// error is returned if json.Marshal errors.
|
||||
func toJSONString(val interface{}) (string, error) {
|
||||
b, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
|
11
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/field_config.go
generated
vendored
11
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/field_config.go
generated
vendored
@ -1,7 +1,6 @@
|
||||
package dataframe
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
@ -72,16 +71,6 @@ func (sf *ConfFloat64) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldConfigFromJSON create a FieldConfig from json string
|
||||
func FieldConfigFromJSON(jsonStr string) (*FieldConfig, error) {
|
||||
var cfg FieldConfig
|
||||
err := json.Unmarshal([]byte(jsonStr), &cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// SetDecimals modifies the FieldConfig's Decimals property to
|
||||
// be set to v and returns the FieldConfig. It is a convenance function
|
||||
// since the Decimals property is a pointer.
|
||||
|
4
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/generic_nullable_vector.go
generated
vendored
4
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/generic_nullable_vector.go
generated
vendored
@ -1,5 +1,3 @@
|
||||
// -build !test
|
||||
|
||||
package dataframe
|
||||
|
||||
//go:generate genny -in=$GOFILE -out=nullable_vector.gen.go gen "gen=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
@ -28,7 +26,5 @@ func (v *nullablegenVector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullablegenVector) PrimitiveType() VectorPType {
|
||||
// following generates the right code but makes this invalid
|
||||
//return VectorPTypeNullablegen
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
52
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/nullable_vector.gen.go
generated
vendored
52
vendor/github.com/grafana/grafana-plugin-sdk-go/dataframe/nullable_vector.gen.go
generated
vendored
@ -2,8 +2,6 @@
|
||||
// Any changes will be lost if this file is regenerated.
|
||||
// see https://github.com/cheekybits/genny
|
||||
|
||||
// -build !test
|
||||
|
||||
package dataframe
|
||||
|
||||
import "time"
|
||||
@ -34,13 +32,9 @@ func (v *nullableUint8Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableUint8Vector) PrimitiveType() VectorPType {
|
||||
// following uint8erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableUint8
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Uint16erate uint16ny -in=$GOFILE -out=nullable_vector.Uint16.go uint16 "Uint16=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableUint16Vector []*uint16
|
||||
@ -67,13 +61,9 @@ func (v *nullableUint16Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableUint16Vector) PrimitiveType() VectorPType {
|
||||
// following uint16erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableUint16
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Uint32erate uint32ny -in=$GOFILE -out=nullable_vector.Uint32.go uint32 "Uint32=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableUint32Vector []*uint32
|
||||
@ -100,13 +90,9 @@ func (v *nullableUint32Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableUint32Vector) PrimitiveType() VectorPType {
|
||||
// following uint32erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableUint32
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Uint64erate uint64ny -in=$GOFILE -out=nullable_vector.Uint64.go uint64 "Uint64=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableUint64Vector []*uint64
|
||||
@ -133,13 +119,9 @@ func (v *nullableUint64Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableUint64Vector) PrimitiveType() VectorPType {
|
||||
// following uint64erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableUint64
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Int8erate int8ny -in=$GOFILE -out=nullable_vector.Int8.go int8 "Int8=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableInt8Vector []*int8
|
||||
@ -166,13 +148,9 @@ func (v *nullableInt8Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableInt8Vector) PrimitiveType() VectorPType {
|
||||
// following int8erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableInt8
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Int16erate int16ny -in=$GOFILE -out=nullable_vector.Int16.go int16 "Int16=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableInt16Vector []*int16
|
||||
@ -199,13 +177,9 @@ func (v *nullableInt16Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableInt16Vector) PrimitiveType() VectorPType {
|
||||
// following int16erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableInt16
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Int32erate int32ny -in=$GOFILE -out=nullable_vector.Int32.go int32 "Int32=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableInt32Vector []*int32
|
||||
@ -232,13 +206,9 @@ func (v *nullableInt32Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableInt32Vector) PrimitiveType() VectorPType {
|
||||
// following int32erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableInt32
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Int64erate int64ny -in=$GOFILE -out=nullable_vector.Int64.go int64 "Int64=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableInt64Vector []*int64
|
||||
@ -265,13 +235,9 @@ func (v *nullableInt64Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableInt64Vector) PrimitiveType() VectorPType {
|
||||
// following int64erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableInt64
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Float32erate float32ny -in=$GOFILE -out=nullable_vector.Float32.go float32 "Float32=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableFloat32Vector []*float32
|
||||
@ -298,13 +264,9 @@ func (v *nullableFloat32Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableFloat32Vector) PrimitiveType() VectorPType {
|
||||
// following float32erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableFloat32
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Float64erate float64ny -in=$GOFILE -out=nullable_vector.Float64.go float64 "Float64=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableFloat64Vector []*float64
|
||||
@ -331,13 +293,9 @@ func (v *nullableFloat64Vector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableFloat64Vector) PrimitiveType() VectorPType {
|
||||
// following float64erates the right code but makes this invalid
|
||||
//return VectorPTypeNullableFloat64
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Stringerate stringny -in=$GOFILE -out=nullable_vector.String.go string "String=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableStringVector []*string
|
||||
@ -364,13 +322,9 @@ func (v *nullableStringVector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableStringVector) PrimitiveType() VectorPType {
|
||||
// following stringerates the right code but makes this invalid
|
||||
//return VectorPTypeNullableString
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:Boolerate boolny -in=$GOFILE -out=nullable_vector.Bool.go bool "Bool=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableBoolVector []*bool
|
||||
@ -397,13 +351,9 @@ func (v *nullableBoolVector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableBoolVector) PrimitiveType() VectorPType {
|
||||
// following boolerates the right code but makes this invalid
|
||||
//return VectorPTypeNullableBool
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
||||
// -build !test
|
||||
|
||||
//go:TimeTimeerate timeTimeny -in=$GOFILE -out=nullable_vector.TimeTime.go time.Time "TimeTime=uint8,uint16,uint32,uint64,int8,int16,int32,int64,float32,float64,string,bool,time.Time"
|
||||
|
||||
type nullableTimeTimeVector []*time.Time
|
||||
@ -430,7 +380,5 @@ func (v *nullableTimeTimeVector) Len() int {
|
||||
}
|
||||
|
||||
func (v *nullableTimeTimeVector) PrimitiveType() VectorPType {
|
||||
// following timeTimeerates the right code but makes this invalid
|
||||
//return VectorPTypeNullableTimeTime
|
||||
return vectorPType(v)
|
||||
}
|
||||
|
479
vendor/github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2/backend.pb.go
generated
vendored
479
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{8, 1, 0}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 1, 0}
|
||||
}
|
||||
|
||||
type PluginConfig struct {
|
||||
@ -366,128 +366,204 @@ func (m *DataQueryResponse) GetMetadata() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ResourceRequest struct {
|
||||
// Plugin Configuration
|
||||
Config *PluginConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
// HTTP Style parameters
|
||||
Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
|
||||
Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Body []byte `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
type CallResource struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) Reset() { *m = ResourceRequest{} }
|
||||
func (m *ResourceRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ResourceRequest) ProtoMessage() {}
|
||||
func (*ResourceRequest) Descriptor() ([]byte, []int) {
|
||||
func (m *CallResource) Reset() { *m = CallResource{} }
|
||||
func (m *CallResource) String() string { return proto.CompactTextString(m) }
|
||||
func (*CallResource) ProtoMessage() {}
|
||||
func (*CallResource) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5}
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ResourceRequest.Unmarshal(m, b)
|
||||
func (m *CallResource) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CallResource.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ResourceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ResourceRequest.Marshal(b, m, deterministic)
|
||||
func (m *CallResource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CallResource.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ResourceRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ResourceRequest.Merge(m, src)
|
||||
func (m *CallResource) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CallResource.Merge(m, src)
|
||||
}
|
||||
func (m *ResourceRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ResourceRequest.Size(m)
|
||||
func (m *CallResource) XXX_Size() int {
|
||||
return xxx_messageInfo_CallResource.Size(m)
|
||||
}
|
||||
func (m *ResourceRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ResourceRequest.DiscardUnknown(m)
|
||||
func (m *CallResource) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CallResource.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ResourceRequest proto.InternalMessageInfo
|
||||
var xxx_messageInfo_CallResource proto.InternalMessageInfo
|
||||
|
||||
func (m *ResourceRequest) GetConfig() *PluginConfig {
|
||||
type CallResource_StringList struct {
|
||||
Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CallResource_StringList) Reset() { *m = CallResource_StringList{} }
|
||||
func (m *CallResource_StringList) String() string { return proto.CompactTextString(m) }
|
||||
func (*CallResource_StringList) ProtoMessage() {}
|
||||
func (*CallResource_StringList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5, 0}
|
||||
}
|
||||
|
||||
func (m *CallResource_StringList) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CallResource_StringList.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CallResource_StringList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CallResource_StringList.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CallResource_StringList) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CallResource_StringList.Merge(m, src)
|
||||
}
|
||||
func (m *CallResource_StringList) XXX_Size() int {
|
||||
return xxx_messageInfo_CallResource_StringList.Size(m)
|
||||
}
|
||||
func (m *CallResource_StringList) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CallResource_StringList.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CallResource_StringList proto.InternalMessageInfo
|
||||
|
||||
func (m *CallResource_StringList) GetValues() []string {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CallResource_Request struct {
|
||||
Config *PluginConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
|
||||
Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"`
|
||||
Headers map[string]*CallResource_StringList `protobuf:"bytes,5,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Body []byte `protobuf:"bytes,6,opt,name=body,proto3" json:"body,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CallResource_Request) Reset() { *m = CallResource_Request{} }
|
||||
func (m *CallResource_Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*CallResource_Request) ProtoMessage() {}
|
||||
func (*CallResource_Request) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5, 1}
|
||||
}
|
||||
|
||||
func (m *CallResource_Request) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CallResource_Request.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CallResource_Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CallResource_Request.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CallResource_Request) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CallResource_Request.Merge(m, src)
|
||||
}
|
||||
func (m *CallResource_Request) XXX_Size() int {
|
||||
return xxx_messageInfo_CallResource_Request.Size(m)
|
||||
}
|
||||
func (m *CallResource_Request) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CallResource_Request.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CallResource_Request proto.InternalMessageInfo
|
||||
|
||||
func (m *CallResource_Request) GetConfig() *PluginConfig {
|
||||
if m != nil {
|
||||
return m.Config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) GetHeaders() map[string]string {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) GetMethod() string {
|
||||
if m != nil {
|
||||
return m.Method
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) GetPath() string {
|
||||
func (m *CallResource_Request) GetPath() string {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ResourceRequest) GetBody() []byte {
|
||||
func (m *CallResource_Request) GetMethod() string {
|
||||
if m != nil {
|
||||
return m.Body
|
||||
return m.Method
|
||||
}
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
type ResourceResponse struct {
|
||||
Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
|
||||
Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
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{6}
|
||||
}
|
||||
|
||||
func (m *ResourceResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ResourceResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ResourceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ResourceResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ResourceResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ResourceResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ResourceResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ResourceResponse.Size(m)
|
||||
}
|
||||
func (m *ResourceResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ResourceResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ResourceResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ResourceResponse) GetCode() int32 {
|
||||
func (m *CallResource_Request) GetUrl() string {
|
||||
if m != nil {
|
||||
return m.Code
|
||||
return m.Url
|
||||
}
|
||||
return 0
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ResourceResponse) GetHeaders() map[string]string {
|
||||
func (m *CallResource_Request) GetHeaders() map[string]*CallResource_StringList {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ResourceResponse) GetBody() []byte {
|
||||
func (m *CallResource_Request) GetBody() []byte {
|
||||
if m != nil {
|
||||
return m.Body
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CallResource_Response struct {
|
||||
Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
|
||||
Headers map[string]*CallResource_StringList `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CallResource_Response) Reset() { *m = CallResource_Response{} }
|
||||
func (m *CallResource_Response) String() string { return proto.CompactTextString(m) }
|
||||
func (*CallResource_Response) ProtoMessage() {}
|
||||
func (*CallResource_Response) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{5, 2}
|
||||
}
|
||||
|
||||
func (m *CallResource_Response) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CallResource_Response.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CallResource_Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CallResource_Response.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CallResource_Response) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CallResource_Response.Merge(m, src)
|
||||
}
|
||||
func (m *CallResource_Response) XXX_Size() int {
|
||||
return xxx_messageInfo_CallResource_Response.Size(m)
|
||||
}
|
||||
func (m *CallResource_Response) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CallResource_Response.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CallResource_Response proto.InternalMessageInfo
|
||||
|
||||
func (m *CallResource_Response) GetCode() int32 {
|
||||
if m != nil {
|
||||
return m.Code
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *CallResource_Response) GetHeaders() map[string]*CallResource_StringList {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CallResource_Response) GetBody() []byte {
|
||||
if m != nil {
|
||||
return m.Body
|
||||
}
|
||||
@ -504,7 +580,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6}
|
||||
}
|
||||
|
||||
func (m *CollectMetrics) XXX_Unmarshal(b []byte) error {
|
||||
@ -535,7 +611,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6, 0}
|
||||
}
|
||||
|
||||
func (m *CollectMetrics_Request) XXX_Unmarshal(b []byte) error {
|
||||
@ -567,7 +643,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6, 1}
|
||||
}
|
||||
|
||||
func (m *CollectMetrics_Payload) XXX_Unmarshal(b []byte) error {
|
||||
@ -606,7 +682,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{6, 2}
|
||||
}
|
||||
|
||||
func (m *CollectMetrics_Response) XXX_Unmarshal(b []byte) error {
|
||||
@ -644,7 +720,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7}
|
||||
}
|
||||
|
||||
func (m *CheckHealth) XXX_Unmarshal(b []byte) error {
|
||||
@ -675,7 +751,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 0}
|
||||
}
|
||||
|
||||
func (m *CheckHealth_Request) XXX_Unmarshal(b []byte) error {
|
||||
@ -708,7 +784,7 @@ 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}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{7, 1}
|
||||
}
|
||||
|
||||
func (m *CheckHealth_Response) XXX_Unmarshal(b []byte) error {
|
||||
@ -762,7 +838,7 @@ func (m *StreamingRequest) Reset() { *m = StreamingRequest{} }
|
||||
func (m *StreamingRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*StreamingRequest) ProtoMessage() {}
|
||||
func (*StreamingRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{9}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{8}
|
||||
}
|
||||
|
||||
func (m *StreamingRequest) XXX_Unmarshal(b []byte) error {
|
||||
@ -831,7 +907,7 @@ func (m *StreamingMessage) Reset() { *m = StreamingMessage{} }
|
||||
func (m *StreamingMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*StreamingMessage) ProtoMessage() {}
|
||||
func (*StreamingMessage) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{10}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{9}
|
||||
}
|
||||
|
||||
func (m *StreamingMessage) XXX_Unmarshal(b []byte) error {
|
||||
@ -884,7 +960,7 @@ func (m *StreamingClose) Reset() { *m = StreamingClose{} }
|
||||
func (m *StreamingClose) String() string { return proto.CompactTextString(m) }
|
||||
func (*StreamingClose) ProtoMessage() {}
|
||||
func (*StreamingClose) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{11}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{10}
|
||||
}
|
||||
|
||||
func (m *StreamingClose) XXX_Unmarshal(b []byte) error {
|
||||
@ -931,7 +1007,7 @@ func (m *RenderRequest) Reset() { *m = RenderRequest{} }
|
||||
func (m *RenderRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*RenderRequest) ProtoMessage() {}
|
||||
func (*RenderRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{12}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{11}
|
||||
}
|
||||
|
||||
func (m *RenderRequest) XXX_Unmarshal(b []byte) error {
|
||||
@ -1026,7 +1102,7 @@ func (m *RenderResponse) Reset() { *m = RenderResponse{} }
|
||||
func (m *RenderResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*RenderResponse) ProtoMessage() {}
|
||||
func (*RenderResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{13}
|
||||
return fileDescriptor_5ab9ba5b8d8b2ba5, []int{12}
|
||||
}
|
||||
|
||||
func (m *RenderResponse) XXX_Unmarshal(b []byte) error {
|
||||
@ -1064,10 +1140,12 @@ func init() {
|
||||
proto.RegisterMapType((map[string]string)(nil), "pluginv2.DataQueryRequest.HeadersEntry")
|
||||
proto.RegisterType((*DataQueryResponse)(nil), "pluginv2.DataQueryResponse")
|
||||
proto.RegisterMapType((map[string]string)(nil), "pluginv2.DataQueryResponse.MetadataEntry")
|
||||
proto.RegisterType((*ResourceRequest)(nil), "pluginv2.ResourceRequest")
|
||||
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((*CallResource)(nil), "pluginv2.CallResource")
|
||||
proto.RegisterType((*CallResource_StringList)(nil), "pluginv2.CallResource.StringList")
|
||||
proto.RegisterType((*CallResource_Request)(nil), "pluginv2.CallResource.Request")
|
||||
proto.RegisterMapType((map[string]*CallResource_StringList)(nil), "pluginv2.CallResource.Request.HeadersEntry")
|
||||
proto.RegisterType((*CallResource_Response)(nil), "pluginv2.CallResource.Response")
|
||||
proto.RegisterMapType((map[string]*CallResource_StringList)(nil), "pluginv2.CallResource.Response.HeadersEntry")
|
||||
proto.RegisterType((*CollectMetrics)(nil), "pluginv2.CollectMetrics")
|
||||
proto.RegisterType((*CollectMetrics_Request)(nil), "pluginv2.CollectMetrics.Request")
|
||||
proto.RegisterType((*CollectMetrics_Payload)(nil), "pluginv2.CollectMetrics.Payload")
|
||||
@ -1086,83 +1164,86 @@ func init() {
|
||||
func init() { proto.RegisterFile("backend.proto", fileDescriptor_5ab9ba5b8d8b2ba5) }
|
||||
|
||||
var fileDescriptor_5ab9ba5b8d8b2ba5 = []byte{
|
||||
// 1207 bytes of a gzipped FileDescriptorProto
|
||||
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,
|
||||
// 1261 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x6e, 0x1c, 0x45,
|
||||
0x10, 0x66, 0xf6, 0xd7, 0x5b, 0xbb, 0x76, 0x9c, 0x8e, 0x95, 0xac, 0x26, 0x21, 0x38, 0xab, 0x08,
|
||||
0x1c, 0x01, 0x1b, 0xd8, 0x1c, 0x40, 0x89, 0x04, 0x82, 0xb5, 0xf3, 0xe7, 0x38, 0x76, 0xda, 0x89,
|
||||
0x10, 0x07, 0x90, 0xda, 0x33, 0xb5, 0xbb, 0x83, 0x67, 0xba, 0x37, 0x3d, 0x3d, 0x81, 0xe5, 0x21,
|
||||
0xb8, 0x70, 0xe6, 0xc6, 0x19, 0x04, 0xcf, 0x00, 0x8f, 0xc0, 0x81, 0xb7, 0x40, 0xe2, 0xc0, 0x15,
|
||||
0x75, 0x4f, 0xcf, 0xcf, 0x5a, 0xde, 0x8d, 0x02, 0x11, 0xe2, 0x56, 0x55, 0x53, 0x5d, 0xfd, 0xd5,
|
||||
0x4f, 0x7f, 0xdd, 0x03, 0xab, 0x47, 0xcc, 0x3b, 0x46, 0xee, 0xf7, 0xa7, 0x52, 0x28, 0x41, 0x56,
|
||||
0xa6, 0x61, 0x32, 0x0e, 0xf8, 0xb3, 0x81, 0x7b, 0x71, 0x2c, 0xc4, 0x38, 0xc4, 0xeb, 0xc6, 0x7e,
|
||||
0x94, 0x8c, 0xae, 0x63, 0x34, 0x55, 0xb3, 0xd4, 0xad, 0xf7, 0x6b, 0x05, 0x3a, 0x07, 0xc6, 0x73,
|
||||
0x28, 0xf8, 0x28, 0x18, 0x93, 0x35, 0xa8, 0x04, 0x7e, 0xd7, 0xd9, 0x74, 0xb6, 0xaa, 0xb4, 0x12,
|
||||
0xf8, 0x64, 0x03, 0xea, 0x42, 0x8e, 0xef, 0xf9, 0xdd, 0x8a, 0x31, 0xa5, 0x0a, 0x21, 0x50, 0xe3,
|
||||
0x2c, 0xc2, 0x6e, 0x75, 0xd3, 0xd9, 0x6a, 0x51, 0x23, 0x6b, 0x9b, 0x9a, 0x4d, 0xb1, 0x5b, 0x4b,
|
||||
0x6d, 0x5a, 0x26, 0xeb, 0x50, 0x4d, 0x64, 0xd8, 0xad, 0x1b, 0x93, 0x16, 0x89, 0x0b, 0x2b, 0x5f,
|
||||
0xc4, 0x82, 0x6f, 0x33, 0xc5, 0xba, 0x0d, 0x63, 0xce, 0x75, 0x12, 0xc1, 0x05, 0x1f, 0x3d, 0x39,
|
||||
0x9b, 0x2a, 0xf4, 0x0f, 0xd1, 0x4b, 0x24, 0xde, 0xcf, 0x5c, 0x9b, 0x9b, 0xd5, 0xad, 0xf6, 0xe0,
|
||||
0x46, 0x3f, 0xcb, 0xaa, 0x5f, 0x06, 0xdd, 0xdf, 0x3e, 0x7d, 0xd5, 0x0e, 0x57, 0x72, 0x46, 0x17,
|
||||
0xc5, 0x74, 0xef, 0xc3, 0xa5, 0x65, 0x0b, 0x35, 0xf8, 0x63, 0x9c, 0x99, 0x5a, 0xb4, 0xa8, 0x16,
|
||||
0x75, 0x31, 0x9e, 0xb1, 0x30, 0x41, 0x53, 0x8c, 0x16, 0x4d, 0x95, 0x9b, 0x95, 0xf7, 0x9d, 0xde,
|
||||
0x2e, 0xb4, 0x1e, 0x07, 0x11, 0x52, 0xc6, 0xc7, 0x48, 0x36, 0xa1, 0x3d, 0x92, 0x22, 0xda, 0x99,
|
||||
0x0a, 0x6f, 0xb2, 0x77, 0x68, 0x8b, 0x59, 0x36, 0x91, 0x4b, 0xd0, 0x52, 0x22, 0xfb, 0x9e, 0x56,
|
||||
0xb6, 0x30, 0xf4, 0x7e, 0x70, 0xa0, 0xa5, 0x61, 0x3c, 0x4a, 0x50, 0x9a, 0x4d, 0x25, 0x8e, 0xee,
|
||||
0xf9, 0x16, 0x48, 0xaa, 0x90, 0xab, 0xb0, 0x1a, 0xb1, 0xaf, 0xb4, 0xd7, 0x81, 0x08, 0xb8, 0x8a,
|
||||
0x6d, 0x94, 0x79, 0x23, 0xb9, 0x0c, 0x10, 0x70, 0x85, 0xf2, 0x19, 0x0b, 0xf7, 0x0e, 0x4d, 0xb7,
|
||||
0xaa, 0xb4, 0x64, 0x21, 0xef, 0x42, 0x4b, 0x65, 0xb0, 0x4d, 0xe3, 0xda, 0x83, 0x73, 0x45, 0x8d,
|
||||
0xf3, 0x8c, 0x68, 0xe1, 0xa5, 0xdb, 0xac, 0x1b, 0x66, 0x7a, 0xda, 0xa1, 0x46, 0xee, 0xfd, 0xe1,
|
||||
0xc0, 0x7a, 0x0e, 0x98, 0xe2, 0xd3, 0x04, 0x63, 0x45, 0xfa, 0xd0, 0xf0, 0x4c, 0x7b, 0x0c, 0xf0,
|
||||
0xf6, 0xe0, 0xfc, 0xe9, 0xcd, 0xa3, 0xd6, 0x8b, 0x7c, 0x04, 0xcd, 0x09, 0x32, 0x1f, 0xa5, 0xce,
|
||||
0x45, 0x77, 0xfb, 0x8d, 0x62, 0xc1, 0xc9, 0xe0, 0xfd, 0xbb, 0xa9, 0x67, 0xda, 0xe1, 0x6c, 0x1d,
|
||||
0x79, 0x1b, 0x9a, 0x4f, 0x13, 0x94, 0x01, 0xc6, 0xdd, 0xaa, 0x09, 0x71, 0xee, 0xb4, 0x10, 0x99,
|
||||
0x8f, 0x7b, 0x13, 0x3a, 0xe5, 0x38, 0x2f, 0xd4, 0xf0, 0x1f, 0x1d, 0x38, 0x5b, 0x42, 0x15, 0x4f,
|
||||
0x05, 0x8f, 0x91, 0x9c, 0x87, 0xc6, 0x48, 0xb2, 0x08, 0xe3, 0xae, 0xb3, 0x59, 0xdd, 0xea, 0x50,
|
||||
0xab, 0x91, 0x1d, 0x58, 0x89, 0x50, 0x31, 0x5f, 0x8f, 0x72, 0x9a, 0xdc, 0xb5, 0x53, 0x93, 0x4b,
|
||||
0xc3, 0xf4, 0xf7, 0xac, 0x6f, 0x9a, 0x5e, 0xbe, 0xd4, 0xbd, 0x05, 0xab, 0x73, 0x9f, 0x5e, 0x08,
|
||||
0xf1, 0x2f, 0x35, 0xe8, 0x0c, 0x59, 0x18, 0x52, 0x8c, 0x45, 0x22, 0x3d, 0x74, 0xaf, 0x02, 0x1c,
|
||||
0x2a, 0x19, 0xf0, 0xf1, 0x83, 0x20, 0x56, 0x1a, 0xba, 0xf1, 0x4d, 0xa1, 0xb7, 0xa8, 0xd5, 0xdc,
|
||||
0x9f, 0x2a, 0xd0, 0xfc, 0xa7, 0x2d, 0x25, 0x50, 0x9b, 0x32, 0x35, 0xb1, 0x58, 0x8c, 0xac, 0xf7,
|
||||
0x89, 0x50, 0x4d, 0x84, 0x6f, 0xc9, 0xc3, 0x6a, 0x19, 0x55, 0xd4, 0x0a, 0xaa, 0xd8, 0x29, 0x06,
|
||||
0xa2, 0x6e, 0x6a, 0xf6, 0x66, 0xb1, 0x5d, 0x39, 0x91, 0xfe, 0xf2, 0xa1, 0x20, 0x50, 0x3b, 0x12,
|
||||
0xfe, 0xcc, 0xb0, 0x4d, 0x87, 0x1a, 0xd9, 0xfd, 0xec, 0xb9, 0x9d, 0x7f, 0xaf, 0x5c, 0xc7, 0xf6,
|
||||
0xe0, 0xca, 0x82, 0xad, 0x8b, 0x02, 0x96, 0x4a, 0xed, 0xfe, 0xee, 0xc0, 0x4a, 0x3e, 0x13, 0x04,
|
||||
0x6a, 0x9e, 0xf0, 0xd1, 0x04, 0xaf, 0x53, 0x23, 0x93, 0xdb, 0x27, 0x67, 0xfd, 0xad, 0x85, 0xa9,
|
||||
0xd9, 0x91, 0x58, 0x9e, 0x5b, 0xf5, 0x3f, 0xcb, 0xad, 0xf7, 0x8d, 0x03, 0x6b, 0x43, 0x11, 0x86,
|
||||
0xe8, 0xa9, 0x3d, 0x54, 0x32, 0xf0, 0x62, 0xb7, 0x95, 0x4f, 0x88, 0x7b, 0x0d, 0x9a, 0x07, 0x6c,
|
||||
0x16, 0x0a, 0xe6, 0x6b, 0xee, 0x99, 0x4a, 0xa1, 0xbb, 0x8b, 0x49, 0x6c, 0xb6, 0xef, 0xd0, 0x92,
|
||||
0xc5, 0xbd, 0x5d, 0xaa, 0xd1, 0x4d, 0x68, 0x46, 0x69, 0x30, 0x3b, 0x59, 0x9b, 0x25, 0x4c, 0x73,
|
||||
0x9b, 0xf5, 0x6d, 0x78, 0x9a, 0x2d, 0xd0, 0x6c, 0xd9, 0x1e, 0x4e, 0xd0, 0x3b, 0xbe, 0x8b, 0x2c,
|
||||
0x54, 0x93, 0x32, 0x9a, 0x6f, 0xcb, 0x7d, 0x18, 0x42, 0x23, 0x56, 0x4c, 0x59, 0x2c, 0x6b, 0x73,
|
||||
0xd3, 0x54, 0x2c, 0x9f, 0xab, 0x78, 0xa8, 0x26, 0x87, 0x66, 0x09, 0xb5, 0x4b, 0x75, 0xc1, 0x03,
|
||||
0x3e, 0x12, 0xd9, 0x44, 0x6b, 0xb9, 0xd7, 0x37, 0x05, 0xcf, 0x7d, 0x49, 0x1b, 0x9a, 0x4f, 0x1e,
|
||||
0xee, 0x3e, 0xdc, 0xff, 0xe4, 0xe1, 0xfa, 0x2b, 0xa4, 0x01, 0x95, 0xfd, 0xdd, 0x75, 0x87, 0xb4,
|
||||
0xa0, 0xbe, 0x43, 0xe9, 0x3e, 0x5d, 0xaf, 0xf4, 0xfe, 0x72, 0x60, 0xfd, 0x50, 0x49, 0x64, 0x51,
|
||||
0xc0, 0xc7, 0xd9, 0xd1, 0x72, 0xc1, 0xde, 0xd8, 0xf7, 0xb2, 0xdb, 0x37, 0xd7, 0x97, 0x32, 0xe3,
|
||||
0xc9, 0x40, 0x0b, 0x06, 0x65, 0x03, 0xea, 0x4a, 0x4c, 0x03, 0xcf, 0x1e, 0xba, 0x54, 0xc9, 0xc7,
|
||||
0xc7, 0x5e, 0xd9, 0x5a, 0xd6, 0x6d, 0x8b, 0x93, 0xa3, 0xd8, 0x93, 0xc1, 0x11, 0xfa, 0x86, 0xe5,
|
||||
0x57, 0x68, 0xc9, 0xf2, 0xaf, 0x48, 0xf3, 0xf3, 0x52, 0xe2, 0x7b, 0x18, 0xc7, 0x6c, 0x8c, 0x4b,
|
||||
0x13, 0xcf, 0x51, 0x57, 0xca, 0xa8, 0xbb, 0x7a, 0x58, 0xcc, 0x62, 0x9b, 0x4d, 0xa6, 0xf6, 0x5e,
|
||||
0x87, 0xb5, 0x3c, 0xfe, 0x30, 0x14, 0x31, 0xea, 0x08, 0x9e, 0x48, 0xb8, 0xb2, 0xa1, 0x53, 0xa5,
|
||||
0xf7, 0xa7, 0x03, 0xab, 0x14, 0xb9, 0x8f, 0x32, 0x2b, 0xbf, 0x65, 0x1f, 0xa7, 0x60, 0x9f, 0x0d,
|
||||
0xa8, 0x7f, 0x19, 0xf8, 0x96, 0xbc, 0xea, 0x34, 0x55, 0x34, 0x7b, 0x4d, 0x30, 0x18, 0x4f, 0x94,
|
||||
0xd9, 0xba, 0x4e, 0xad, 0xa6, 0x31, 0xe9, 0x2b, 0x52, 0x24, 0xca, 0x14, 0xb3, 0x4e, 0x33, 0x55,
|
||||
0xe7, 0xa7, 0xc5, 0xaf, 0x05, 0x47, 0xfb, 0x0e, 0xca, 0x75, 0xfd, 0x0d, 0xb9, 0x27, 0xfc, 0x80,
|
||||
0x8f, 0xb3, 0xc7, 0x50, 0xa6, 0xeb, 0x6f, 0xa3, 0x20, 0xc4, 0x03, 0xcd, 0x9f, 0xcd, 0xf4, 0x5b,
|
||||
0xa6, 0xeb, 0xe7, 0x83, 0x34, 0xf0, 0x77, 0x71, 0xd6, 0x5d, 0x31, 0x1f, 0x0b, 0x83, 0xc6, 0xe8,
|
||||
0x8b, 0x88, 0x05, 0xbc, 0xdb, 0x4a, 0x19, 0x36, 0xd5, 0x74, 0x75, 0xb2, 0xa4, 0xed, 0x91, 0xd8,
|
||||
0x80, 0x3a, 0x4a, 0x29, 0x64, 0xf6, 0xb4, 0x30, 0xca, 0xe0, 0x3b, 0x07, 0x6a, 0x43, 0x21, 0x91,
|
||||
0xec, 0xcf, 0x5f, 0x18, 0xe4, 0xf2, 0x72, 0xfe, 0x75, 0x5f, 0x7b, 0x0e, 0x89, 0x91, 0xed, 0xf2,
|
||||
0xbb, 0xc6, 0x5d, 0x7c, 0xbd, 0xbb, 0x17, 0x97, 0xdc, 0x8e, 0x83, 0x9f, 0x1d, 0x68, 0x6f, 0x07,
|
||||
0x6c, 0xcc, 0x45, 0xac, 0x02, 0x2f, 0x26, 0x4f, 0x4e, 0x12, 0x12, 0x59, 0xcc, 0x1e, 0xd9, 0x06,
|
||||
0x57, 0x96, 0x78, 0x58, 0xb0, 0x0f, 0xe6, 0x68, 0x85, 0xbc, 0xba, 0x88, 0x2e, 0xd2, 0x80, 0x97,
|
||||
0x97, 0xb3, 0xc9, 0xe0, 0x7b, 0x07, 0xce, 0xdc, 0x91, 0x6c, 0xc4, 0x38, 0x3b, 0x08, 0x99, 0x1a,
|
||||
0x09, 0x19, 0x91, 0x5d, 0xc3, 0x4e, 0xff, 0xab, 0xda, 0x3e, 0x82, 0xd6, 0x63, 0xc9, 0x78, 0x6c,
|
||||
0xf0, 0xbd, 0x9c, 0x90, 0x9f, 0xc2, 0xd9, 0x3c, 0xa4, 0x86, 0xfe, 0x31, 0xf3, 0x8e, 0x5f, 0x52,
|
||||
0xe8, 0xdf, 0x1c, 0x38, 0x93, 0x1f, 0xf8, 0xf4, 0x05, 0x42, 0x3e, 0x84, 0xe6, 0x50, 0x70, 0x8e,
|
||||
0x9e, 0x22, 0x0b, 0x9e, 0x27, 0xae, 0x7b, 0x0a, 0x7d, 0x5a, 0x3a, 0x7a, 0xc7, 0xd1, 0x6c, 0x7b,
|
||||
0x20, 0x85, 0x87, 0x71, 0x4c, 0xdc, 0xc5, 0x3c, 0xbb, 0x2c, 0x08, 0xf9, 0x00, 0x60, 0x3b, 0x88,
|
||||
0xbd, 0x1c, 0x46, 0xfa, 0x07, 0xd6, 0xcf, 0xfe, 0xc0, 0xfa, 0x3b, 0xfa, 0x0f, 0xcc, 0xed, 0x9e,
|
||||
0x12, 0xc1, 0xb0, 0xd6, 0xe0, 0x8e, 0x1e, 0x0c, 0x7d, 0x52, 0x51, 0x92, 0x5b, 0xd0, 0x48, 0x65,
|
||||
0x72, 0xa1, 0xf0, 0x9f, 0x23, 0xaf, 0x72, 0xa0, 0xf9, 0x03, 0x7e, 0xd4, 0x30, 0x5b, 0xde, 0xf8,
|
||||
0x3b, 0x00, 0x00, 0xff, 0xff, 0x85, 0x4e, 0xfe, 0x13, 0x1d, 0x0e, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -1178,7 +1259,7 @@ 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 {
|
||||
// HTTP Style request
|
||||
Resource(ctx context.Context, in *ResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
CallResource(ctx context.Context, in *CallResource_Request, opts ...grpc.CallOption) (*CallResource_Response, error)
|
||||
// Well typed query interface
|
||||
DataQuery(ctx context.Context, in *DataQueryRequest, opts ...grpc.CallOption) (*DataQueryResponse, error)
|
||||
}
|
||||
@ -1191,9 +1272,9 @@ func NewCoreClient(cc *grpc.ClientConn) CoreClient {
|
||||
return &coreClient{cc}
|
||||
}
|
||||
|
||||
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...)
|
||||
func (c *coreClient) CallResource(ctx context.Context, in *CallResource_Request, opts ...grpc.CallOption) (*CallResource_Response, error) {
|
||||
out := new(CallResource_Response)
|
||||
err := c.cc.Invoke(ctx, "/pluginv2.Core/CallResource", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1212,7 +1293,7 @@ func (c *coreClient) DataQuery(ctx context.Context, in *DataQueryRequest, opts .
|
||||
// CoreServer is the server API for Core service.
|
||||
type CoreServer interface {
|
||||
// HTTP Style request
|
||||
Resource(context.Context, *ResourceRequest) (*ResourceResponse, error)
|
||||
CallResource(context.Context, *CallResource_Request) (*CallResource_Response, error)
|
||||
// Well typed query interface
|
||||
DataQuery(context.Context, *DataQueryRequest) (*DataQueryResponse, error)
|
||||
}
|
||||
@ -1221,8 +1302,8 @@ type CoreServer interface {
|
||||
type UnimplementedCoreServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedCoreServer) Resource(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Resource not implemented")
|
||||
func (*UnimplementedCoreServer) CallResource(ctx context.Context, req *CallResource_Request) (*CallResource_Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CallResource not implemented")
|
||||
}
|
||||
func (*UnimplementedCoreServer) DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DataQuery not implemented")
|
||||
@ -1232,20 +1313,20 @@ func RegisterCoreServer(s *grpc.Server, srv CoreServer) {
|
||||
s.RegisterService(&_Core_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Core_Resource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ResourceRequest)
|
||||
func _Core_CallResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CallResource_Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CoreServer).Resource(ctx, in)
|
||||
return srv.(CoreServer).CallResource(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pluginv2.Core/Resource",
|
||||
FullMethod: "/pluginv2.Core/CallResource",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CoreServer).Resource(ctx, req.(*ResourceRequest))
|
||||
return srv.(CoreServer).CallResource(ctx, req.(*CallResource_Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@ -1273,8 +1354,8 @@ var _Core_serviceDesc = grpc.ServiceDesc{
|
||||
HandlerType: (*CoreServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Resource",
|
||||
Handler: _Core_Resource_Handler,
|
||||
MethodName: "CallResource",
|
||||
Handler: _Core_CallResource_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DataQuery",
|
||||
@ -1397,7 +1478,7 @@ var _Diagnostics_serviceDesc = grpc.ServiceDesc{
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type GrafanaPlatformClient interface {
|
||||
Resource(ctx context.Context, in *ResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
Resource(ctx context.Context, in *CallResource_Request, opts ...grpc.CallOption) (*CallResource_Response, error)
|
||||
DataQuery(ctx context.Context, in *DataQueryRequest, opts ...grpc.CallOption) (*DataQueryResponse, error)
|
||||
}
|
||||
|
||||
@ -1409,8 +1490,8 @@ func NewGrafanaPlatformClient(cc *grpc.ClientConn) GrafanaPlatformClient {
|
||||
return &grafanaPlatformClient{cc}
|
||||
}
|
||||
|
||||
func (c *grafanaPlatformClient) Resource(ctx context.Context, in *ResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error) {
|
||||
out := new(ResourceResponse)
|
||||
func (c *grafanaPlatformClient) Resource(ctx context.Context, in *CallResource_Request, opts ...grpc.CallOption) (*CallResource_Response, error) {
|
||||
out := new(CallResource_Response)
|
||||
err := c.cc.Invoke(ctx, "/pluginv2.GrafanaPlatform/Resource", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1429,7 +1510,7 @@ func (c *grafanaPlatformClient) DataQuery(ctx context.Context, in *DataQueryRequ
|
||||
|
||||
// GrafanaPlatformServer is the server API for GrafanaPlatform service.
|
||||
type GrafanaPlatformServer interface {
|
||||
Resource(context.Context, *ResourceRequest) (*ResourceResponse, error)
|
||||
Resource(context.Context, *CallResource_Request) (*CallResource_Response, error)
|
||||
DataQuery(context.Context, *DataQueryRequest) (*DataQueryResponse, error)
|
||||
}
|
||||
|
||||
@ -1437,7 +1518,7 @@ type GrafanaPlatformServer interface {
|
||||
type UnimplementedGrafanaPlatformServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedGrafanaPlatformServer) Resource(ctx context.Context, req *ResourceRequest) (*ResourceResponse, error) {
|
||||
func (*UnimplementedGrafanaPlatformServer) Resource(ctx context.Context, req *CallResource_Request) (*CallResource_Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Resource not implemented")
|
||||
}
|
||||
func (*UnimplementedGrafanaPlatformServer) DataQuery(ctx context.Context, req *DataQueryRequest) (*DataQueryResponse, error) {
|
||||
@ -1449,7 +1530,7 @@ func RegisterGrafanaPlatformServer(s *grpc.Server, srv GrafanaPlatformServer) {
|
||||
}
|
||||
|
||||
func _GrafanaPlatform_Resource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ResourceRequest)
|
||||
in := new(CallResource_Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1461,7 +1542,7 @@ func _GrafanaPlatform_Resource_Handler(srv interface{}, ctx context.Context, dec
|
||||
FullMethod: "/pluginv2.GrafanaPlatform/Resource",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GrafanaPlatformServer).Resource(ctx, req.(*ResourceRequest))
|
||||
return srv.(GrafanaPlatformServer).Resource(ctx, req.(*CallResource_Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
generated
vendored
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/.gitignore
generated
vendored
@ -1,201 +0,0 @@
|
||||
#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
24
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/CHANGELOG.md
generated
vendored
@ -1,24 +0,0 @@
|
||||
# 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
201
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/LICENSE
generated
vendored
@ -1,201 +0,0 @@
|
||||
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
247
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/README.md
generated
vendored
@ -1,247 +0,0 @@
|
||||
# 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
39
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// 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
170
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
generated
vendored
@ -1,170 +0,0 @@
|
||||
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
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_reporter.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
// 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
16
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/makefile
generated
vendored
@ -1,16 +0,0 @@
|
||||
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
41
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
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
48
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
// 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
185
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
generated
vendored
@ -1,185 +0,0 @@
|
||||
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
46
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_reporter.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
// 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
50
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
// 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
|
||||
}
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -148,12 +148,10 @@ 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.11.0
|
||||
github.com/grafana/grafana-plugin-sdk-go/backend
|
||||
# github.com/grafana/grafana-plugin-sdk-go v0.14.0
|
||||
github.com/grafana/grafana-plugin-sdk-go/backend/plugin
|
||||
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