Plugins: Enhanced plugin instrumentation (#90199)
* Plugins: Enhanced plugin instrumentation * use backend.CallResourceResponseSenderFunc * sdk v0.237.0 * support admission control * cover all handlers in log and metrics middlewares * fix after review
This commit is contained in:
@@ -11,7 +11,7 @@ require (
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
@@ -22,7 +22,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
||||
+14
-14
@@ -6,9 +6,9 @@ require (
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.opentelemetry.io/otel/trace v1.26.0
|
||||
go.opentelemetry.io/otel/trace v1.28.0
|
||||
k8s.io/apimachinery v0.29.3
|
||||
k8s.io/apiserver v0.29.2
|
||||
k8s.io/client-go v0.29.3
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect
|
||||
@@ -52,7 +52,7 @@ require (
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/common v0.54.0 // indirect
|
||||
github.com/prometheus/procfs v0.14.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
@@ -61,13 +61,13 @@ require (
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.10 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
@@ -78,10 +78,10 @@ require (
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
+14
-28
@@ -38,8 +38,7 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
@@ -128,16 +127,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
|
||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
||||
github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ=
|
||||
@@ -184,22 +181,14 @@ go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg
|
||||
go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -281,10 +270,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
@@ -293,8 +280,7 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
+12
-12
@@ -37,9 +37,9 @@ require (
|
||||
github.com/urfave/cli v1.22.15 // @grafana/grafana-backend-group
|
||||
github.com/urfave/cli/v2 v2.27.1 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect; @grafana/plugins-platform-backend
|
||||
go.opentelemetry.io/otel v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/trace v1.26.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect; @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/trace v1.28.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/crypto v0.24.0 // indirect; @grafana/grafana-backend-group
|
||||
golang.org/x/mod v0.18.0 // @grafana/grafana-backend-group
|
||||
golang.org/x/net v0.26.0 // indirect; @grafana/oss-big-tent @grafana/partner-datasources
|
||||
@@ -50,7 +50,7 @@ require (
|
||||
golang.org/x/tools v0.22.0 // indirect; @grafana/grafana-as-code
|
||||
google.golang.org/api v0.176.0 // @grafana/grafana-backend-group
|
||||
google.golang.org/grpc v1.64.0 // indirect; @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.34.1 // indirect; @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.34.2 // indirect; @grafana/plugins-platform-backend
|
||||
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ require (
|
||||
github.com/drone/runner-go v1.12.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect; @grafana/grafana-app-platform-squad
|
||||
github.com/go-logr/logr v1.4.2 // indirect; @grafana/grafana-app-platform-squad
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
@@ -87,13 +87,13 @@ require (
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect; @grafana/grafana-backend-group
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
@@ -112,12 +112,12 @@ require (
|
||||
github.com/vektah/gqlparser/v2 v2.5.11 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.2.0-alpha // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
)
|
||||
|
||||
+12
-23
@@ -89,8 +89,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/gogo/protobuf v0.0.0-20170307180453-100ba4e88506/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@@ -218,31 +217,24 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha h1:z2s6Zba+OUyayRv5m1AXWNUTGh57K1iMhy6emU5QT5Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.2.0-alpha/go.mod h1:paOXXyUgPW6jYxYkP0pB47H2zHE1fPvMJ4E4G9LHOi0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38=
|
||||
go.opentelemetry.io/otel/log v0.2.0-alpha h1:ixOPvMzserpqA07SENHvRzkZOsnG0XbPr74hv1AQ+n0=
|
||||
go.opentelemetry.io/otel/log v0.2.0-alpha/go.mod h1:vbFZc65yq4c4ssvXY43y/nIqkNJLxORrqw0L85P59LA=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha h1:jGTkL/jroJ31jnP6jDl34N/mDOfRGGYZHcHsCM+5kWA=
|
||||
go.opentelemetry.io/otel/sdk/log v0.2.0-alpha/go.mod h1:Hd8Lw9FPGUM3pfY7iGMRvFaC2Nyau4Ajb5WnQ9OdIho=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -327,10 +319,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
@@ -348,8 +338,7 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -25,6 +25,7 @@ type ProtoClient interface {
|
||||
pluginv2.ResourceClient
|
||||
pluginv2.DiagnosticsClient
|
||||
pluginv2.StreamClient
|
||||
pluginv2.AdmissionControlClient
|
||||
|
||||
PID(context.Context) (string, error)
|
||||
PluginID() string
|
||||
@@ -184,3 +185,27 @@ func (r *protoClient) PublishStream(ctx context.Context, in *pluginv2.PublishStr
|
||||
}
|
||||
return c.StreamClient.PublishStream(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (r *protoClient) ValidateAdmission(ctx context.Context, in *pluginv2.AdmissionRequest, opts ...grpc.CallOption) (*pluginv2.ValidationResponse, error) {
|
||||
c, exists := r.client(ctx)
|
||||
if !exists {
|
||||
return nil, errClientNotStarted
|
||||
}
|
||||
return c.AdmissionClient.ValidateAdmission(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (r *protoClient) MutateAdmission(ctx context.Context, in *pluginv2.AdmissionRequest, opts ...grpc.CallOption) (*pluginv2.MutationResponse, error) {
|
||||
c, exists := r.client(ctx)
|
||||
if !exists {
|
||||
return nil, errClientNotStarted
|
||||
}
|
||||
return c.AdmissionClient.MutateAdmission(ctx, in, opts...)
|
||||
}
|
||||
|
||||
func (r *protoClient) ConvertObject(ctx context.Context, in *pluginv2.ConversionRequest, opts ...grpc.CallOption) (*pluginv2.ConversionResponse, error) {
|
||||
c, exists := r.client(ctx)
|
||||
if !exists {
|
||||
return nil, errClientNotStarted
|
||||
}
|
||||
return c.AdmissionClient.ConvertObject(ctx, in, opts...)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package instrumentationutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
grpccodes "google.golang.org/grpc/codes"
|
||||
grpcstatus "google.golang.org/grpc/status"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
|
||||
)
|
||||
|
||||
type RequestStatus int
|
||||
|
||||
const (
|
||||
RequestStatusOK RequestStatus = iota
|
||||
RequestStatusCancelled
|
||||
RequestStatusError
|
||||
)
|
||||
|
||||
func (status RequestStatus) String() string {
|
||||
names := [...]string{"ok", "cancelled", "error"}
|
||||
if status < RequestStatusOK || status > RequestStatusError {
|
||||
return ""
|
||||
}
|
||||
|
||||
return names[status]
|
||||
}
|
||||
|
||||
func RequestStatusFromError(err error) RequestStatus {
|
||||
status := RequestStatusOK
|
||||
if err != nil {
|
||||
status = RequestStatusError
|
||||
if errors.Is(err, context.Canceled) || grpcstatus.Code(err) == grpccodes.Canceled {
|
||||
status = RequestStatusCancelled
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func RequestStatusFromErrorString(errString string) RequestStatus {
|
||||
status := RequestStatusOK
|
||||
if errString != "" {
|
||||
status = RequestStatusError
|
||||
if strings.Contains(errString, context.Canceled.Error()) || strings.Contains(errString, "code = Canceled") {
|
||||
status = RequestStatusCancelled
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func RequestStatusFromQueryDataResponse(res *backend.QueryDataResponse, err error) RequestStatus {
|
||||
if err != nil {
|
||||
return RequestStatusFromError(err)
|
||||
}
|
||||
|
||||
status := RequestStatusOK
|
||||
|
||||
if res != nil {
|
||||
for _, dr := range res.Responses {
|
||||
if dr.Error != nil {
|
||||
s := RequestStatusFromError(dr.Error)
|
||||
if s > status {
|
||||
status = s
|
||||
}
|
||||
|
||||
if status == RequestStatusError {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func RequestStatusFromProtoQueryDataResponse(res *pluginv2.QueryDataResponse, err error) RequestStatus {
|
||||
if err != nil {
|
||||
return RequestStatusFromError(err)
|
||||
}
|
||||
|
||||
status := RequestStatusOK
|
||||
|
||||
if res != nil {
|
||||
for _, dr := range res.Responses {
|
||||
if dr.Error != "" {
|
||||
s := RequestStatusFromErrorString(dr.Error)
|
||||
if s > status {
|
||||
status = s
|
||||
}
|
||||
|
||||
if status == RequestStatusError {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
+61
-18
@@ -1,4 +1,4 @@
|
||||
package clientmiddleware
|
||||
package instrumentationutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -9,23 +9,25 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func TestRequestStatus(t *testing.T) {
|
||||
tcs := []struct {
|
||||
s requestStatus
|
||||
s RequestStatus
|
||||
expectedLabel string
|
||||
}{
|
||||
{
|
||||
s: requestStatusOK,
|
||||
s: RequestStatusOK,
|
||||
expectedLabel: "ok",
|
||||
},
|
||||
{
|
||||
s: requestStatusError,
|
||||
s: RequestStatusError,
|
||||
expectedLabel: "error",
|
||||
},
|
||||
{
|
||||
s: requestStatusCancelled,
|
||||
s: RequestStatusCancelled,
|
||||
expectedLabel: "cancelled",
|
||||
},
|
||||
}
|
||||
@@ -42,28 +44,33 @@ func TestRequestStatusFromError(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
err error
|
||||
expectedStatus requestStatus
|
||||
expectedStatus RequestStatus
|
||||
}{
|
||||
{
|
||||
desc: "no error should be status ok",
|
||||
err: nil,
|
||||
expectedStatus: requestStatusOK,
|
||||
expectedStatus: RequestStatusOK,
|
||||
},
|
||||
{
|
||||
desc: "error should be status error",
|
||||
err: errors.New("boom"),
|
||||
expectedStatus: requestStatusError,
|
||||
expectedStatus: RequestStatusError,
|
||||
},
|
||||
{
|
||||
desc: "context canceled should be status cancelled",
|
||||
err: context.Canceled,
|
||||
expectedStatus: requestStatusCancelled,
|
||||
expectedStatus: RequestStatusCancelled,
|
||||
},
|
||||
{
|
||||
desc: "gRPC canceled should be status cancelled",
|
||||
err: status.Error(codes.Canceled, "canceled"),
|
||||
expectedStatus: RequestStatusCancelled,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
status := requestStatusFromError(tc.err)
|
||||
status := RequestStatusFromError(tc.err)
|
||||
require.Equal(t, tc.expectedStatus, status)
|
||||
})
|
||||
}
|
||||
@@ -94,43 +101,79 @@ func TestRequestStatusFromQueryDataResponse(t *testing.T) {
|
||||
desc string
|
||||
resp *backend.QueryDataResponse
|
||||
err error
|
||||
expectedStatus requestStatus
|
||||
expectedStatus RequestStatus
|
||||
}{
|
||||
{
|
||||
desc: "no error should be status ok",
|
||||
err: nil,
|
||||
expectedStatus: requestStatusOK,
|
||||
expectedStatus: RequestStatusOK,
|
||||
},
|
||||
{
|
||||
desc: "error should be status error",
|
||||
err: errors.New("boom"),
|
||||
expectedStatus: requestStatusError,
|
||||
expectedStatus: RequestStatusError,
|
||||
},
|
||||
{
|
||||
desc: "context canceled should be status cancelled",
|
||||
err: context.Canceled,
|
||||
expectedStatus: requestStatusCancelled,
|
||||
expectedStatus: RequestStatusCancelled,
|
||||
},
|
||||
{
|
||||
desc: "response without error should be status ok",
|
||||
resp: responseWithoutError,
|
||||
expectedStatus: requestStatusOK,
|
||||
expectedStatus: RequestStatusOK,
|
||||
},
|
||||
{
|
||||
desc: "response with error should be status error",
|
||||
resp: responseWithError,
|
||||
expectedStatus: requestStatusError,
|
||||
expectedStatus: RequestStatusError,
|
||||
},
|
||||
{
|
||||
desc: "response with multiple error should pick the highest status cancelled",
|
||||
resp: responseWithMultipleErrors,
|
||||
expectedStatus: requestStatusError,
|
||||
expectedStatus: RequestStatusError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
status := requestStatusFromQueryDataResponse(tc.resp, tc.err)
|
||||
status := RequestStatusFromQueryDataResponse(tc.resp, tc.err)
|
||||
require.Equal(t, tc.expectedStatus, status)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestStatusFromErrorString(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
err string
|
||||
expectedStatus RequestStatus
|
||||
}{
|
||||
{
|
||||
desc: "no error should be status ok",
|
||||
err: "",
|
||||
expectedStatus: RequestStatusOK,
|
||||
},
|
||||
{
|
||||
desc: "error should be status error",
|
||||
err: errors.New("boom").Error(),
|
||||
expectedStatus: RequestStatusError,
|
||||
},
|
||||
{
|
||||
desc: "context canceled should be status cancelled",
|
||||
err: context.Canceled.Error(),
|
||||
expectedStatus: RequestStatusCancelled,
|
||||
},
|
||||
{
|
||||
desc: "gRPC canceled should be status cancelled",
|
||||
err: status.Error(codes.Canceled, "canceled").Error(),
|
||||
expectedStatus: RequestStatusCancelled,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
status := RequestStatusFromErrorString(tc.err)
|
||||
require.Equal(t, tc.expectedStatus, status)
|
||||
})
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq
|
||||
removeNonAllowedHeaders(req.Headers)
|
||||
|
||||
processedStreams := 0
|
||||
wrappedSender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
wrappedSender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
// Expected that headers and status are only part of first stream
|
||||
if processedStreams == 0 && res != nil {
|
||||
if len(res.Headers) > 0 {
|
||||
@@ -354,9 +354,3 @@ func ensureContentTypeHeader(res *backend.CallResourceResponse) {
|
||||
res.Headers[contentTypeHeaderName] = []string{defaultContentType}
|
||||
}
|
||||
}
|
||||
|
||||
type callResourceResponseSenderFunc func(res *backend.CallResourceResponse) error
|
||||
|
||||
func (fn callResourceResponseSenderFunc) Send(res *backend.CallResourceResponse) error {
|
||||
return fn(res)
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ func TestCallResource(t *testing.T) {
|
||||
}
|
||||
|
||||
responses := []*backend.CallResourceResponse{}
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
responses = append(responses, res)
|
||||
return nil
|
||||
})
|
||||
@@ -232,7 +232,7 @@ func TestCallResource(t *testing.T) {
|
||||
}
|
||||
|
||||
responses := []*backend.CallResourceResponse{}
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
responses = append(responses, res)
|
||||
return nil
|
||||
})
|
||||
@@ -280,7 +280,7 @@ func TestCallResource(t *testing.T) {
|
||||
}
|
||||
|
||||
responses := []*backend.CallResourceResponse{}
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
responses = append(responses, res)
|
||||
return nil
|
||||
})
|
||||
@@ -348,7 +348,7 @@ func TestCallResource(t *testing.T) {
|
||||
}
|
||||
|
||||
responses := []*backend.CallResourceResponse{}
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
responses = append(responses, res)
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -35,6 +35,9 @@ func (d *Decorator) QueryData(ctx context.Context, req *backend.QueryDataRequest
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointQueryData)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
|
||||
@@ -46,6 +49,10 @@ func (d *Decorator) CallResource(ctx context.Context, req *backend.CallResourceR
|
||||
return errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointCallResource)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
if sender == nil {
|
||||
return errors.New("sender cannot be nil")
|
||||
}
|
||||
@@ -59,6 +66,10 @@ func (d *Decorator) CollectMetrics(ctx context.Context, req *backend.CollectMetr
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointCollectMetrics)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.CollectMetrics(ctx, req)
|
||||
}
|
||||
@@ -68,6 +79,10 @@ func (d *Decorator) CheckHealth(ctx context.Context, req *backend.CheckHealthReq
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointCheckHealth)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.CheckHealth(ctx, req)
|
||||
}
|
||||
@@ -77,6 +92,10 @@ func (d *Decorator) SubscribeStream(ctx context.Context, req *backend.SubscribeS
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointSubscribeStream)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.SubscribeStream(ctx, req)
|
||||
}
|
||||
@@ -86,6 +105,10 @@ func (d *Decorator) PublishStream(ctx context.Context, req *backend.PublishStrea
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointPublishStream)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.PublishStream(ctx, req)
|
||||
}
|
||||
@@ -95,6 +118,10 @@ func (d *Decorator) RunStream(ctx context.Context, req *backend.RunStreamRequest
|
||||
return errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointRunStream)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
if sender == nil {
|
||||
return errors.New("sender cannot be nil")
|
||||
}
|
||||
@@ -108,6 +135,10 @@ func (d *Decorator) ValidateAdmission(ctx context.Context, req *backend.Admissio
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointValidateAdmission)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.ValidateAdmission(ctx, req)
|
||||
}
|
||||
@@ -117,6 +148,10 @@ func (d *Decorator) MutateAdmission(ctx context.Context, req *backend.AdmissionR
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointMutateAdmission)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.MutateAdmission(ctx, req)
|
||||
}
|
||||
@@ -126,6 +161,10 @@ func (d *Decorator) ConvertObject(ctx context.Context, req *backend.ConversionRe
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
ctx = backend.WithEndpoint(ctx, backend.EndpointConvertObject)
|
||||
ctx = backend.WithPluginContext(ctx, req.PluginContext)
|
||||
ctx = backend.WithUser(ctx, req.PluginContext.User)
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestDecorator(t *testing.T) {
|
||||
_, _ = d.QueryData(context.Background(), &backend.QueryDataRequest{})
|
||||
require.True(t, queryDataCalled)
|
||||
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
+16
-16
@@ -3,15 +3,15 @@ module github.com/grafana/grafana/pkg/promlib
|
||||
go 1.21.10
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.235.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.237.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/prometheus/common v0.53.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/common v0.54.0
|
||||
github.com/prometheus/prometheus v1.8.2-0.20221021121301-51a44e6657c3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.opentelemetry.io/otel v1.26.0
|
||||
go.opentelemetry.io/otel/trace v1.26.0
|
||||
go.opentelemetry.io/otel v1.28.0
|
||||
go.opentelemetry.io/otel/trace v1.28.0
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
|
||||
k8s.io/apimachinery v0.29.3
|
||||
)
|
||||
@@ -39,7 +39,7 @@ require (
|
||||
github.com/getkin/kin-openapi v0.124.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.4 // indirect
|
||||
@@ -97,14 +97,14 @@ require (
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.26.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
@@ -115,10 +115,10 @@ require (
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
gonum.org/v1/gonum v0.14.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
+17
-18
@@ -49,8 +49,7 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
@@ -81,7 +80,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.235.0 h1:UnZ/iBDvCkfDgwR94opi8trAWJXv4V8Qr1ocJKRRmqA=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.237.0 h1:sxif4tl9ocYSVyeCtGijWQbW2ygfEOFGKQTCQ/ZX99M=
|
||||
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.7 h1:C11j63y7gymiW8VugJ9ZW0pWfxTZugdSJyC48olk5KY=
|
||||
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzedH7MZzRZt5/lsAHch6Z3L2ZGn5FA=
|
||||
@@ -165,9 +164,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
|
||||
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
|
||||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
||||
@@ -218,17 +217,17 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN
|
||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 h1:974XTyIwHI4nHa1+uSLxHtUnlJ2DiVtAJjk7fd07p/8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 h1:RH76Cl2pfOLLoCtxAPax9c7oYzuL1tiI7/ZPJEmEmOw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0 h1:IVtyPth4Rs5P8wIf0mP2KVKFNTJ4paX9qQ4Hkh5gFdc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.28.0 h1:xQ3ktSVS128JWIaN1DiPGIjcH+GsvkibIAVRWFjS9eM=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 h1:ja+d7Aea/9PgGxB63+E0jtRFpma717wubS0KFkZpmYw=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -280,10 +279,10 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -18,8 +18,8 @@ const (
|
||||
StatusOK = "ok"
|
||||
StatusError = "error"
|
||||
|
||||
EndpointCallResource = "callResource"
|
||||
EndpointQueryData = "queryData"
|
||||
EndpointCallResource = string(backend.EndpointCallResource)
|
||||
EndpointQueryData = string(backend.EndpointQueryData)
|
||||
|
||||
PluginSource = "plugin"
|
||||
ExternalSource = "external"
|
||||
|
||||
@@ -160,7 +160,7 @@ func (m *CachingMiddleware) CallResource(ctx context.Context, req *backend.CallR
|
||||
return m.next.CallResource(ctx, req, sender)
|
||||
}
|
||||
// Otherwise, intercept the responses in a wrapped sender so we can cache them first
|
||||
cacheSender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
cacheSender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
cr.UpdateCacheFn(ctx, res)
|
||||
return sender.Send(res)
|
||||
})
|
||||
|
||||
@@ -221,7 +221,7 @@ func TestCachingMiddleware(t *testing.T) {
|
||||
}
|
||||
|
||||
var sentResponse *backend.CallResourceResponse
|
||||
var storeOneResponseCallResourceSender = callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
var storeOneResponseCallResourceSender = backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sentResponse = res
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -24,8 +24,15 @@ type ContextualLoggerMiddleware struct {
|
||||
}
|
||||
|
||||
// instrumentContext adds a contextual logger with plugin and request details to the given context.
|
||||
func instrumentContext(ctx context.Context, endpoint string, pCtx backend.PluginContext) context.Context {
|
||||
p := []any{"endpoint", endpoint, "pluginId", pCtx.PluginID}
|
||||
func instrumentContext(ctx context.Context, pCtx backend.PluginContext) context.Context {
|
||||
p := []any{}
|
||||
|
||||
if ep := backend.EndpointFromContext(ctx); !ep.IsEmpty() {
|
||||
p = append(p, "endpoint", string(ep))
|
||||
}
|
||||
|
||||
p = append(p, "pluginId", pCtx.PluginID)
|
||||
|
||||
if pCtx.DataSourceInstanceSettings != nil {
|
||||
p = append(p, "dsName", pCtx.DataSourceInstanceSettings.Name)
|
||||
p = append(p, "dsUID", pCtx.DataSourceInstanceSettings.UID)
|
||||
@@ -37,54 +44,54 @@ func instrumentContext(ctx context.Context, endpoint string, pCtx backend.Plugin
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointQueryData, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.QueryData(ctx, req)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
ctx = instrumentContext(ctx, endpointCallResource, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.CallResource(ctx, req, sender)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
ctx = instrumentContext(ctx, endpointCheckHealth, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.CheckHealth(ctx, req)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {
|
||||
ctx = instrumentContext(ctx, endpointCollectMetrics, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.CollectMetrics(ctx, req)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointSubscribeStream, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.SubscribeStream(ctx, req)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointPublishStream, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.PublishStream(ctx, req)
|
||||
}
|
||||
|
||||
func (m *ContextualLoggerMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
ctx = instrumentContext(ctx, endpointRunStream, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointValidateAdmission, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointMutateAdmission, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointConvertObject, req.PluginContext)
|
||||
ctx = instrumentContext(ctx, req.PluginContext)
|
||||
return m.next.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/instrumentationutils"
|
||||
plog "github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
@@ -30,13 +31,13 @@ type LoggerMiddleware struct {
|
||||
logger plog.Logger
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) logRequest(ctx context.Context, fn func(ctx context.Context) (requestStatus, error)) error {
|
||||
func (m *LoggerMiddleware) logRequest(ctx context.Context, fn func(ctx context.Context) (instrumentationutils.RequestStatus, error)) error {
|
||||
start := time.Now()
|
||||
timeBeforePluginRequest := log.TimeSinceStart(ctx, start)
|
||||
|
||||
status, err := fn(ctx)
|
||||
logParams := []any{
|
||||
"status", status,
|
||||
"status", status.String(),
|
||||
"duration", time.Since(start),
|
||||
"eventName", "grafana-data-egress",
|
||||
"time_before_plugin_request", timeBeforePluginRequest,
|
||||
@@ -48,7 +49,7 @@ func (m *LoggerMiddleware) logRequest(ctx context.Context, fn func(ctx context.C
|
||||
|
||||
ctxLogger := m.logger.FromContext(ctx)
|
||||
logFunc := ctxLogger.Info
|
||||
if status > requestStatusOK {
|
||||
if status > instrumentationutils.RequestStatusOK {
|
||||
logFunc = ctxLogger.Error
|
||||
}
|
||||
|
||||
@@ -63,11 +64,12 @@ func (m *LoggerMiddleware) QueryData(ctx context.Context, req *backend.QueryData
|
||||
}
|
||||
|
||||
var resp *backend.QueryDataResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.QueryData(ctx, req)
|
||||
|
||||
if innerErr != nil {
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
}
|
||||
|
||||
ctxLogger := m.logger.FromContext(ctx)
|
||||
@@ -83,7 +85,7 @@ func (m *LoggerMiddleware) QueryData(ctx context.Context, req *backend.QueryData
|
||||
}
|
||||
}
|
||||
|
||||
return requestStatusFromQueryDataResponse(resp, innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromQueryDataResponse(resp, innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
@@ -94,9 +96,9 @@ func (m *LoggerMiddleware) CallResource(ctx context.Context, req *backend.CallRe
|
||||
return m.next.CallResource(ctx, req, sender)
|
||||
}
|
||||
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
innerErr = m.next.CallResource(ctx, req, sender)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
innerErr := m.next.CallResource(ctx, req, sender)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return err
|
||||
@@ -108,9 +110,10 @@ func (m *LoggerMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHe
|
||||
}
|
||||
|
||||
var resp *backend.CheckHealthResult
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.CheckHealth(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
@@ -122,9 +125,98 @@ func (m *LoggerMiddleware) CollectMetrics(ctx context.Context, req *backend.Coll
|
||||
}
|
||||
|
||||
var resp *backend.CollectMetricsResult
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.CollectMetrics(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
if req == nil {
|
||||
return m.next.SubscribeStream(ctx, req)
|
||||
}
|
||||
|
||||
var resp *backend.SubscribeStreamResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.SubscribeStream(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
if req == nil {
|
||||
return m.next.PublishStream(ctx, req)
|
||||
}
|
||||
|
||||
var resp *backend.PublishStreamResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.PublishStream(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
if req == nil {
|
||||
return m.next.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
innerErr := m.next.RunStream(ctx, req, sender)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if req == nil {
|
||||
return m.next.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
var resp *backend.ValidationResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.ValidateAdmission(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if req == nil {
|
||||
return m.next.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
var resp *backend.MutationResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.MutateAdmission(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *LoggerMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if req == nil {
|
||||
return m.next.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
var resp *backend.ConversionResponse
|
||||
err := m.logRequest(ctx, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.ConvertObject(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/instrumentationutils"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
@@ -94,17 +95,18 @@ func (m *MetricsMiddleware) pluginTarget(ctx context.Context, pluginID, pluginVe
|
||||
}
|
||||
|
||||
// instrumentPluginRequestSize tracks the size of the given request in the m.pluginRequestSize metric.
|
||||
func (m *MetricsMiddleware) instrumentPluginRequestSize(ctx context.Context, pluginCtx backend.PluginContext, endpoint string, requestSize float64) error {
|
||||
func (m *MetricsMiddleware) instrumentPluginRequestSize(ctx context.Context, pluginCtx backend.PluginContext, requestSize float64) error {
|
||||
target, err := m.pluginTarget(ctx, pluginCtx.PluginID, pluginCtx.PluginVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.pluginRequestSize.WithLabelValues("grafana-backend", pluginCtx.PluginID, endpoint, target).Observe(requestSize)
|
||||
endpoint := backend.EndpointFromContext(ctx)
|
||||
m.pluginRequestSize.WithLabelValues("grafana-backend", pluginCtx.PluginID, string(endpoint), target).Observe(requestSize)
|
||||
return nil
|
||||
}
|
||||
|
||||
// instrumentPluginRequest increments the m.pluginRequestCounter metric and tracks the duration of the given request.
|
||||
func (m *MetricsMiddleware) instrumentPluginRequest(ctx context.Context, pluginCtx backend.PluginContext, endpoint string, fn func(context.Context) (requestStatus, error)) error {
|
||||
func (m *MetricsMiddleware) instrumentPluginRequest(ctx context.Context, pluginCtx backend.PluginContext, fn func(context.Context) (instrumentationutils.RequestStatus, error)) error {
|
||||
target, err := m.pluginTarget(ctx, pluginCtx.PluginID, pluginCtx.PluginVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -116,10 +118,11 @@ func (m *MetricsMiddleware) instrumentPluginRequest(ctx context.Context, pluginC
|
||||
elapsed := time.Since(start)
|
||||
|
||||
statusSource := pluginrequestmeta.StatusSourceFromContext(ctx)
|
||||
endpoint := backend.EndpointFromContext(ctx)
|
||||
|
||||
pluginRequestDurationWithLabels := m.pluginRequestDuration.WithLabelValues(pluginCtx.PluginID, endpoint, target, string(statusSource))
|
||||
pluginRequestCounterWithLabels := m.pluginRequestCounter.WithLabelValues(pluginCtx.PluginID, endpoint, status.String(), target, string(statusSource))
|
||||
pluginRequestDurationSecondsWithLabels := m.pluginRequestDurationSeconds.WithLabelValues("grafana-backend", pluginCtx.PluginID, endpoint, status.String(), target, string(statusSource))
|
||||
pluginRequestDurationWithLabels := m.pluginRequestDuration.WithLabelValues(pluginCtx.PluginID, string(endpoint), target, string(statusSource))
|
||||
pluginRequestCounterWithLabels := m.pluginRequestCounter.WithLabelValues(pluginCtx.PluginID, string(endpoint), status.String(), target, string(statusSource))
|
||||
pluginRequestDurationSecondsWithLabels := m.pluginRequestDurationSeconds.WithLabelValues("grafana-backend", pluginCtx.PluginID, string(endpoint), status.String(), target, string(statusSource))
|
||||
|
||||
if traceID := tracing.TraceIDFromContext(ctx, true); traceID != "" {
|
||||
pluginRequestDurationWithLabels.(prometheus.ExemplarObserver).ObserveWithExemplar(
|
||||
@@ -144,74 +147,108 @@ func (m *MetricsMiddleware) QueryData(ctx context.Context, req *backend.QueryDat
|
||||
requestSize += float64(len(v.JSON))
|
||||
}
|
||||
|
||||
if err := m.instrumentPluginRequestSize(ctx, req.PluginContext, endpointQueryData, requestSize); err != nil {
|
||||
if err := m.instrumentPluginRequestSize(ctx, req.PluginContext, requestSize); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resp *backend.QueryDataResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointQueryData, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.QueryData(ctx, req)
|
||||
return requestStatusFromQueryDataResponse(resp, innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromQueryDataResponse(resp, innerErr), innerErr
|
||||
})
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
if err := m.instrumentPluginRequestSize(ctx, req.PluginContext, endpointCallResource, float64(len(req.Body))); err != nil {
|
||||
if err := m.instrumentPluginRequestSize(ctx, req.PluginContext, float64(len(req.Body))); err != nil {
|
||||
return err
|
||||
}
|
||||
return m.instrumentPluginRequest(ctx, req.PluginContext, endpointCallResource, func(ctx context.Context) (requestStatus, error) {
|
||||
return m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
innerErr := m.next.CallResource(ctx, req, sender)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
var result *backend.CheckHealthResult
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointCheckHealth, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.CheckHealth(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
var resp *backend.CheckHealthResult
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.CheckHealth(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {
|
||||
var result *backend.CollectMetricsResult
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointCollectMetrics, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.CollectMetrics(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
var resp *backend.CollectMetricsResult
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.CollectMetrics(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
return result, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
var resp *backend.SubscribeStreamResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.SubscribeStream(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
var resp *backend.PublishStreamResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.PublishStream(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
innerErr := m.next.RunStream(ctx, req, sender)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
var result *backend.ValidationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.ValidateAdmission(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
var resp *backend.ValidationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.ValidateAdmission(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
var result *backend.MutationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.MutateAdmission(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
var resp *backend.MutationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.MutateAdmission(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
var result *backend.ConversionResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.ConvertObject(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
var resp *backend.ConversionResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, func(ctx context.Context) (instrumentationutils.RequestStatus, error) {
|
||||
var innerErr error
|
||||
resp, innerErr = m.next.ConvertObject(ctx, req)
|
||||
return instrumentationutils.RequestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
"github.com/grafana/grafana/pkg/plugins/instrumentationutils"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/client/clienttest"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
@@ -32,12 +33,12 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
pCtx := backend.PluginContext{PluginID: pluginID}
|
||||
t.Run("should instrument requests", func(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
expEndpoint string
|
||||
expEndpoint backend.Endpoint
|
||||
fn func(cdt *clienttest.ClientDecoratorTest) error
|
||||
shouldInstrumentRequestSize bool
|
||||
}{
|
||||
{
|
||||
expEndpoint: endpointCheckHealth,
|
||||
expEndpoint: backend.EndpointCheckHealth,
|
||||
fn: func(cdt *clienttest.ClientDecoratorTest) error {
|
||||
_, err := cdt.Decorator.CheckHealth(context.Background(), &backend.CheckHealthRequest{PluginContext: pCtx})
|
||||
return err
|
||||
@@ -45,14 +46,14 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
shouldInstrumentRequestSize: false,
|
||||
},
|
||||
{
|
||||
expEndpoint: endpointCallResource,
|
||||
expEndpoint: backend.EndpointCallResource,
|
||||
fn: func(cdt *clienttest.ClientDecoratorTest) error {
|
||||
return cdt.Decorator.CallResource(context.Background(), &backend.CallResourceRequest{PluginContext: pCtx}, nopCallResourceSender)
|
||||
},
|
||||
shouldInstrumentRequestSize: true,
|
||||
},
|
||||
{
|
||||
expEndpoint: endpointQueryData,
|
||||
expEndpoint: backend.EndpointQueryData,
|
||||
fn: func(cdt *clienttest.ClientDecoratorTest) error {
|
||||
_, err := cdt.Decorator.QueryData(context.Background(), &backend.QueryDataRequest{PluginContext: pCtx})
|
||||
return err
|
||||
@@ -60,7 +61,7 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
shouldInstrumentRequestSize: true,
|
||||
},
|
||||
{
|
||||
expEndpoint: endpointCollectMetrics,
|
||||
expEndpoint: backend.EndpointCollectMetrics,
|
||||
fn: func(cdt *clienttest.ClientDecoratorTest) error {
|
||||
_, err := cdt.Decorator.CollectMetrics(context.Background(), &backend.CollectMetricsRequest{PluginContext: pCtx})
|
||||
return err
|
||||
@@ -68,7 +69,7 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
shouldInstrumentRequestSize: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.expEndpoint, func(t *testing.T) {
|
||||
t.Run(string(tc.expEndpoint), func(t *testing.T) {
|
||||
promRegistry := prometheus.NewRegistry()
|
||||
pluginsRegistry := fakes.NewFakePluginRegistry()
|
||||
require.NoError(t, pluginsRegistry.Add(context.Background(), &plugins.Plugin{
|
||||
@@ -89,12 +90,12 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
require.Equal(t, 1, testutil.CollectAndCount(promRegistry, metricRequestDurationMs))
|
||||
require.Equal(t, 1, testutil.CollectAndCount(promRegistry, metricRequestDurationS))
|
||||
|
||||
counter := mw.pluginMetrics.pluginRequestCounter.WithLabelValues(pluginID, tc.expEndpoint, requestStatusOK.String(), string(backendplugin.TargetUnknown), string(pluginrequestmeta.DefaultStatusSource))
|
||||
counter := mw.pluginMetrics.pluginRequestCounter.WithLabelValues(pluginID, string(tc.expEndpoint), instrumentationutils.RequestStatusOK.String(), string(backendplugin.TargetUnknown), string(pluginrequestmeta.DefaultStatusSource))
|
||||
require.Equal(t, 1.0, testutil.ToFloat64(counter))
|
||||
for _, m := range []string{metricRequestDurationMs, metricRequestDurationS} {
|
||||
require.NoError(t, checkHistogram(promRegistry, m, map[string]string{
|
||||
"plugin_id": pluginID,
|
||||
"endpoint": tc.expEndpoint,
|
||||
"endpoint": string(tc.expEndpoint),
|
||||
"target": string(backendplugin.TargetUnknown),
|
||||
}))
|
||||
}
|
||||
@@ -102,7 +103,7 @@ func TestInstrumentationMiddleware(t *testing.T) {
|
||||
require.Equal(t, 1, testutil.CollectAndCount(promRegistry, metricRequestSize), "request size should have been instrumented")
|
||||
require.NoError(t, checkHistogram(promRegistry, metricRequestSize, map[string]string{
|
||||
"plugin_id": pluginID,
|
||||
"endpoint": tc.expEndpoint,
|
||||
"endpoint": string(tc.expEndpoint),
|
||||
"target": string(backendplugin.TargetUnknown),
|
||||
"source": "grafana-backend",
|
||||
}), "request size should have been instrumented")
|
||||
@@ -116,8 +117,8 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
const labelStatusSource = "status_source"
|
||||
queryDataErrorCounterLabels := prometheus.Labels{
|
||||
"plugin_id": pluginID,
|
||||
"endpoint": endpointQueryData,
|
||||
"status": requestStatusError.String(),
|
||||
"endpoint": string(backend.EndpointQueryData),
|
||||
"status": instrumentationutils.RequestStatusError.String(),
|
||||
"target": string(backendplugin.TargetUnknown),
|
||||
}
|
||||
downstreamErrorResponse := backend.DataResponse{
|
||||
|
||||
@@ -35,7 +35,7 @@ func (m *ResourceResponseMiddleware) CallResource(ctx context.Context, req *back
|
||||
}
|
||||
|
||||
processedStreams := 0
|
||||
wrappedSender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
wrappedSender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
if processedStreams == 0 {
|
||||
if res.Headers == nil {
|
||||
res.Headers = map[string][]string{}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ func TestResourceResponseMiddleware(t *testing.T) {
|
||||
)
|
||||
|
||||
var sentResponse *backend.CallResourceResponse
|
||||
sender := callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sender := backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
sentResponse = res
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -2,6 +2,6 @@ package clientmiddleware
|
||||
|
||||
import "github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
var nopCallResourceSender = callResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
var nopCallResourceSender = backend.CallResourceResponseSenderFunc(func(res *backend.CallResourceResponse) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -44,10 +44,10 @@ func setSpanAttributeFromHTTPHeader(headers http.Header, span trace.Span, attrib
|
||||
// plugin id, org id, user login, ds, dashboard and panel info. The second function returned is a cleanup function,
|
||||
// which should be called by the caller (deferred) and will set the span status/error and end the span.
|
||||
func (m *TracingMiddleware) traceWrap(
|
||||
ctx context.Context, pluginContext backend.PluginContext, opName string,
|
||||
ctx context.Context, pluginContext backend.PluginContext,
|
||||
) (context.Context, func(error)) {
|
||||
// Start span
|
||||
ctx, span := m.tracer.Start(ctx, "PluginClient."+opName, trace.WithAttributes(
|
||||
endpoint := backend.EndpointFromContext(ctx)
|
||||
ctx, span := m.tracer.Start(ctx, "PluginClient."+string(endpoint), trace.WithAttributes(
|
||||
// Attach some plugin context information to span
|
||||
attribute.String("plugin_id", pluginContext.PluginID),
|
||||
attribute.Int64("org_id", pluginContext.OrgID),
|
||||
@@ -82,7 +82,7 @@ func (m *TracingMiddleware) traceWrap(
|
||||
|
||||
func (m *TracingMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "queryData")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.QueryData(ctx, req)
|
||||
return resp, err
|
||||
@@ -90,7 +90,7 @@ func (m *TracingMiddleware) QueryData(ctx context.Context, req *backend.QueryDat
|
||||
|
||||
func (m *TracingMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "callResource")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
err = m.next.CallResource(ctx, req, sender)
|
||||
return err
|
||||
@@ -98,7 +98,7 @@ func (m *TracingMiddleware) CallResource(ctx context.Context, req *backend.CallR
|
||||
|
||||
func (m *TracingMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "checkHealth")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.CheckHealth(ctx, req)
|
||||
return resp, err
|
||||
@@ -106,7 +106,7 @@ func (m *TracingMiddleware) CheckHealth(ctx context.Context, req *backend.CheckH
|
||||
|
||||
func (m *TracingMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "collectMetrics")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.CollectMetrics(ctx, req)
|
||||
return resp, err
|
||||
@@ -114,7 +114,7 @@ func (m *TracingMiddleware) CollectMetrics(ctx context.Context, req *backend.Col
|
||||
|
||||
func (m *TracingMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "subscribeStream")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.SubscribeStream(ctx, req)
|
||||
return resp, err
|
||||
@@ -122,7 +122,7 @@ func (m *TracingMiddleware) SubscribeStream(ctx context.Context, req *backend.Su
|
||||
|
||||
func (m *TracingMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "publishStream")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.PublishStream(ctx, req)
|
||||
return resp, err
|
||||
@@ -130,7 +130,7 @@ func (m *TracingMiddleware) PublishStream(ctx context.Context, req *backend.Publ
|
||||
|
||||
func (m *TracingMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, "runStream")
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
err = m.next.RunStream(ctx, req, sender)
|
||||
return err
|
||||
@@ -139,7 +139,7 @@ func (m *TracingMiddleware) RunStream(ctx context.Context, req *backend.RunStrea
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointValidateAdmission)
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.ValidateAdmission(ctx, req)
|
||||
return resp, err
|
||||
@@ -148,7 +148,7 @@ func (m *TracingMiddleware) ValidateAdmission(ctx context.Context, req *backend.
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointMutateAdmission)
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.MutateAdmission(ctx, req)
|
||||
return resp, err
|
||||
@@ -157,7 +157,7 @@ func (m *TracingMiddleware) MutateAdmission(ctx context.Context, req *backend.Ad
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointConvertObject)
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.ConvertObject(ctx, req)
|
||||
return resp, err
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package clientmiddleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
)
|
||||
|
||||
type requestStatus int
|
||||
|
||||
const (
|
||||
requestStatusOK requestStatus = iota
|
||||
requestStatusCancelled
|
||||
requestStatusError
|
||||
)
|
||||
|
||||
func (status requestStatus) String() string {
|
||||
names := [...]string{"ok", "cancelled", "error"}
|
||||
if status < requestStatusOK || status > requestStatusError {
|
||||
return ""
|
||||
}
|
||||
|
||||
return names[status]
|
||||
}
|
||||
|
||||
const (
|
||||
endpointCallResource = "callResource"
|
||||
endpointCheckHealth = "checkHealth"
|
||||
endpointCollectMetrics = "collectMetrics"
|
||||
endpointQueryData = "queryData"
|
||||
endpointSubscribeStream = "subscribeStream"
|
||||
endpointPublishStream = "publishStream"
|
||||
endpointRunStream = "runStream"
|
||||
endpointValidateAdmission = "validateAdmission"
|
||||
endpointMutateAdmission = "mutateAdmission"
|
||||
endpointConvertObject = "convertObject"
|
||||
)
|
||||
|
||||
type callResourceResponseSenderFunc func(res *backend.CallResourceResponse) error
|
||||
|
||||
func (fn callResourceResponseSenderFunc) Send(res *backend.CallResourceResponse) error {
|
||||
return fn(res)
|
||||
}
|
||||
|
||||
func requestStatusFromError(err error) requestStatus {
|
||||
status := requestStatusOK
|
||||
if err != nil {
|
||||
status = requestStatusError
|
||||
if errors.Is(err, context.Canceled) {
|
||||
status = requestStatusCancelled
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func requestStatusFromQueryDataResponse(res *backend.QueryDataResponse, err error) requestStatus {
|
||||
if err != nil {
|
||||
return requestStatusFromError(err)
|
||||
}
|
||||
|
||||
status := requestStatusOK
|
||||
|
||||
if res != nil {
|
||||
for _, dr := range res.Responses {
|
||||
if dr.Error != nil {
|
||||
s := requestStatusFromError(dr.Error)
|
||||
if s > status {
|
||||
status = s
|
||||
}
|
||||
|
||||
if status == requestStatusError {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
@@ -19,8 +19,8 @@ require (
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -13,8 +13,8 @@ golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
)
|
||||
@@ -71,7 +70,7 @@ func (s *httpServiceProxy) Do(rw http.ResponseWriter, req *http.Request, cli *ht
|
||||
|
||||
func (s *Service) getDataSourceFromHTTPReq(req *http.Request) (types.DatasourceInfo, error) {
|
||||
ctx := req.Context()
|
||||
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
||||
pluginContext := backend.PluginConfigFromContext(ctx)
|
||||
i, err := s.im.Get(ctx, pluginContext)
|
||||
if err != nil {
|
||||
return types.DatasourceInfo{}, err
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
|
||||
"github.com/andybalholm/brotli"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
)
|
||||
|
||||
// nameExp matches the part after the last '/' symbol
|
||||
@@ -397,7 +396,7 @@ func writeResponse(rw http.ResponseWriter, code int, msg string) {
|
||||
|
||||
func (s *Service) getDataSourceFromHTTPReq(req *http.Request) (*datasourceInfo, error) {
|
||||
ctx := req.Context()
|
||||
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
||||
pluginContext := backend.PluginConfigFromContext(ctx)
|
||||
i, err := s.im.Get(ctx, pluginContext)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
|
||||
@@ -192,12 +192,12 @@ func (e *cloudWatchExecutor) getRequestContextOnlySettings(ctx context.Context,
|
||||
}
|
||||
|
||||
func (e *cloudWatchExecutor) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
ctx = instrumentContext(ctx, "callResource", req.PluginContext)
|
||||
ctx = instrumentContext(ctx, string(backend.EndpointCallResource), req.PluginContext)
|
||||
return e.resourceHandler.CallResource(ctx, req, sender)
|
||||
}
|
||||
|
||||
func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
ctx = instrumentContext(ctx, "queryData", req.PluginContext)
|
||||
ctx = instrumentContext(ctx, string(backend.EndpointQueryData), req.PluginContext)
|
||||
q := req.Queries[0]
|
||||
var model DataQueryJson
|
||||
err := json.Unmarshal(q.JSON, &model)
|
||||
@@ -236,7 +236,7 @@ func (e *cloudWatchExecutor) QueryData(ctx context.Context, req *backend.QueryDa
|
||||
}
|
||||
|
||||
func (e *cloudWatchExecutor) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
ctx = instrumentContext(ctx, "checkHealth", req.PluginContext)
|
||||
ctx = instrumentContext(ctx, string(backend.EndpointCheckHealth), req.PluginContext)
|
||||
status := backend.HealthStatusOk
|
||||
metricsTest := "Successfully queried the CloudWatch metrics API."
|
||||
logsTest := "Successfully queried the CloudWatch logs API."
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/routes"
|
||||
)
|
||||
|
||||
@@ -38,7 +37,7 @@ type handleFn func(ctx context.Context, pluginCtx backend.PluginContext, paramet
|
||||
func handleResourceReq(handleFunc handleFn, logger log.Logger) func(rw http.ResponseWriter, req *http.Request) {
|
||||
return func(rw http.ResponseWriter, req *http.Request) {
|
||||
ctx := req.Context()
|
||||
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
||||
pluginContext := backend.PluginConfigFromContext(ctx)
|
||||
err := req.ParseForm()
|
||||
if err != nil {
|
||||
writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err), logger.FromContext(ctx))
|
||||
|
||||
@@ -3,8 +3,8 @@ package routes
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||
)
|
||||
@@ -17,7 +17,7 @@ func ResourceRequestMiddleware(handleFunc models.RouteHandlerFunc, logger log.Lo
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
pluginContext := httpadapter.PluginConfigFromContext(ctx)
|
||||
pluginContext := backend.PluginConfigFromContext(ctx)
|
||||
json, httpError := handleFunc(ctx, pluginContext, reqCtxFactory, req.URL.Query())
|
||||
if httpError != nil {
|
||||
logger.FromContext(ctx).Error("Error handling resource request", "error", httpError.Message)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
@@ -18,12 +19,8 @@ var (
|
||||
}, []string{"status", "endpoint"})
|
||||
)
|
||||
|
||||
const (
|
||||
EndpointQueryData = "queryData"
|
||||
)
|
||||
|
||||
func UpdatePluginParsingResponseDurationSeconds(ctx context.Context, duration time.Duration, status string) {
|
||||
histogram := pluginParsingResponseDurationSeconds.WithLabelValues(status, EndpointQueryData)
|
||||
histogram := pluginParsingResponseDurationSeconds.WithLabelValues(status, string(backend.EndpointQueryData))
|
||||
|
||||
if traceID := tracing.TraceIDFromContext(ctx, true); traceID != "" {
|
||||
histogram.(prometheus.ExemplarObserver).ObserveWithExemplar(duration.Seconds(), prometheus.Labels{"traceID": traceID})
|
||||
|
||||
@@ -215,7 +215,7 @@ func instrumentScenarioHandler(logger log.Logger, scenario kinds.TestDataQueryTy
|
||||
defer span.End()
|
||||
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
ctxLogger.Debug("queryData", "scenario", scenario)
|
||||
ctxLogger.Debug(string(backend.EndpointQueryData), "scenario", scenario)
|
||||
|
||||
return fn(ctx, req)
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
@@ -18,12 +19,8 @@ var (
|
||||
}, []string{"status", "endpoint"})
|
||||
)
|
||||
|
||||
const (
|
||||
EndpointQueryData = "queryData"
|
||||
)
|
||||
|
||||
func UpdatePluginParsingResponseDurationSeconds(ctx context.Context, duration time.Duration, status string) {
|
||||
histogram := pluginParsingResponseDurationSeconds.WithLabelValues(status, EndpointQueryData)
|
||||
histogram := pluginParsingResponseDurationSeconds.WithLabelValues(status, string(backend.EndpointQueryData))
|
||||
|
||||
if traceID := tracing.TraceIDFromContext(ctx, true); traceID != "" {
|
||||
histogram.(prometheus.ExemplarObserver).ObserveWithExemplar(duration.Seconds(), prometheus.Labels{"traceID": traceID})
|
||||
|
||||
Reference in New Issue
Block a user