mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Auto instrumentation improvements (#94193)
This commit is contained in:
parent
4a3c6325a4
commit
b28085110d
2
go.mod
2
go.mod
@ -87,7 +87,7 @@ require (
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.3.0 // @grafana/grafana-operator-experience-squad
|
||||
github.com/grafana/grafana-google-sdk-go v0.1.0 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/grafana/pkg/aggregator v0.0.0-20240813192817-1b0e6b5c09b2 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da // @grafana/grafana-app-platform-squad
|
||||
|
4
go.sum
4
go.sum
@ -2284,8 +2284,8 @@ github.com/grafana/grafana-google-sdk-go v0.1.0/go.mod h1:Vo2TKWfDVmNTELBUM+3lkr
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 h1:r+mU5bGMzcXCRVAuOrTn54S80qbfVkvTdUJZfSfTNbs=
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79/go.mod h1:wc6Hbh3K2TgCUSfBC/BOzabItujtHMESZeFk5ZhdxhQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0 h1:gnOtxrC/1rqFvpSbQYyoZqkr47oWDlz4Q2L6Ozmsi3w=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0 h1:KaCrqqsDgVIoT8hwvwuUMKV7QbHVlvRoFN5+U2rOXR8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/grafana/apps/playlist v0.0.0-20240917082838-e2bce38a7990 h1:uQMZE/z+Y+o/U0z/g8ckAHss7U7LswedilByA2535DU=
|
||||
github.com/grafana/grafana/apps/playlist v0.0.0-20240917082838-e2bce38a7990/go.mod h1:3Vi0xv/4OBkBw4R9GAERkSrBnx06qrjpmNBRisucuSM=
|
||||
github.com/grafana/grafana/pkg/aggregator v0.0.0-20240813192817-1b0e6b5c09b2 h1:2H9x4q53pkfUGtSNYD1qSBpNnxrFgylof/TYADb5xMI=
|
||||
|
15
go.work.sum
15
go.work.sum
@ -1,7 +1,6 @@
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1 h1:tdpHgTbmbvEIARu+bixzmleMi14+3imnpoFXz+Qzjp4=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1/go.mod h1:xafc+XIsTxTy76GJQ1TKgvJWsSugFBqMaN27WhUblew=
|
||||
cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w=
|
||||
cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
|
||||
cel.dev/expr v0.16.0 h1:yloc84fytn4zmJX2GU3TkXGsaieaV7dQ057Qs4sIG2Y=
|
||||
cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg=
|
||||
cloud.google.com/go/accessapproval v1.7.11 h1:MgtE8CI+YJWPGGHnxQ9z1VQqV87h+vSGy2MeM/m0ggQ=
|
||||
@ -516,6 +515,8 @@ github.com/elastic/go-sysinfo v1.11.2/go.mod h1:GKqR8bbMK/1ITnez9NIsIfXQr25aLhRJ
|
||||
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw=
|
||||
github.com/expr-lang/expr v1.16.2 h1:JvMnzUs3LeVHBvGFcXYmXo+Q6DPDmzrlcSBO6Wy3w4s=
|
||||
github.com/expr-lang/expr v1.16.2/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
@ -598,7 +599,6 @@ github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4=
|
||||
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY=
|
||||
github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4=
|
||||
@ -906,7 +906,6 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stoewer/parquet-cli v0.0.7 h1:rhdZODIbyMS3twr4OM3am8BPPT5pbfMcHLH93whDM5o=
|
||||
github.com/stoewer/parquet-cli v0.0.7/go.mod h1:bskxHdj8q3H1EmfuCqjViFoeO3NEvs5lzZAQvI8Nfjk=
|
||||
github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
|
||||
@ -1063,6 +1062,7 @@ go.opentelemetry.io/collector/service v0.95.0 h1:t6RUHV7ByFjkjPKGz5n6n4wIoXZLC8H
|
||||
go.opentelemetry.io/collector/service v0.95.0/go.mod h1:4yappQmDE5UZmLE9wwtj6IPM4W5KGLIYfObEAaejtQc=
|
||||
go.opentelemetry.io/contrib/config v0.4.0 h1:Xb+ncYOqseLroMuBesGNRgVQolXcXOhMj7EhGwJCdHs=
|
||||
go.opentelemetry.io/contrib/config v0.4.0/go.mod h1:drNk2xRqLWW4/amk6Uh1S+sDAJTc7bcEEN1GfJzj418=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.53.0/go.mod h1:ImRBLMJv177/pwiLZ7tU7HDGNdBv7rS0HQ99eN/zBl8=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.23.0 h1:aaIGWc5JdfRGpCafLRxMJbD65MfTa206AwSKkvGS0Hg=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.23.0/go.mod h1:Gyz7V7XghvwTq+mIhLFlTgcc03UDroOg8vezs4NLhwU=
|
||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
||||
@ -1074,7 +1074,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.23.1 h1:ZqR
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.23.1/go.mod h1:D7ynngPWlGJrqyGSDOdscuv7uqttfCE3jcBvffDv9y4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.23.1 h1:q/Nj5/2TZRIt6PderQ9oU0M00fzoe8UZuINGw6ETGTw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.23.1/go.mod h1:DTE9yAu6r08jU3xa68GiSeI7oRcSEQ2RpKbbQGO+dWM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.46.0 h1:I8WIFXR351FoLJYuloU4EgXbtNX2URfU/85pUPheIEQ=
|
||||
@ -1085,7 +1084,6 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDO
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA=
|
||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.26.0 h1:cWSks5tfriHPdWFnl+qpX3P681aAYqlZHcAyHw5aU9Y=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.26.0/go.mod h1:ClMFFknnThJCksebJwz7KIyEDHO+nTB6gK8obLy8RyE=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
@ -1118,11 +1116,9 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -1134,8 +1130,6 @@ golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=
|
||||
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@ -1150,15 +1144,12 @@ gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE=
|
||||
gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:mCr1K1c8kX+1iSBREvU3Juo11CB+QOEWxbRS01wWl5M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:OFMYQFHJ4TM3JRlWDZhJbZfra2uqc3WLBZiaaqP4DtU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20240730163845-b1a4ccb954bf h1:T4tsZBlZYXK3j40sQNP5MBO32I+rn6ypV1PpklsiV8k=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:5/MT647Cn/GGhwTpXC7QqcaR5Cnee4v4MKCU1/nwnIQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
|
@ -4,7 +4,7 @@ go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/emicklei/go-restful/v3 v3.11.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435
|
||||
github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435
|
||||
github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38
|
||||
|
@ -130,8 +130,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0 h1:gnOtxrC/1rqFvpSbQYyoZqkr47oWDlz4Q2L6Ozmsi3w=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0 h1:KaCrqqsDgVIoT8hwvwuUMKV7QbHVlvRoFN5+U2rOXR8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435 h1:lmw60EW7JWlAEvgggktOyVkH4hF1m/+LSF/Ap0NCyi8=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I=
|
||||
github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 h1:SNEeqY22DrGr5E9kGF1mKSqlOom14W9+b1u4XEGJowA=
|
||||
|
@ -42,6 +42,8 @@ func New(cfg *setting.Cfg, validator validations.PluginRequestValidator, tracer
|
||||
middlewares = append(middlewares, GrafanaRequestIDHeaderMiddleware(cfg, logger))
|
||||
}
|
||||
|
||||
middlewares = append(middlewares, sdkhttpclient.ErrorSourceMiddleware())
|
||||
|
||||
// SigV4 signing should be performed after all headers are added
|
||||
if cfg.SigV4AuthEnabled {
|
||||
authSettings := awsds.AuthSettings{
|
||||
|
@ -27,7 +27,7 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
_ = New(&setting.Cfg{SigV4AuthEnabled: false}, &validations.OSSPluginRequestValidator{}, tracer)
|
||||
require.Len(t, providerOpts, 1)
|
||||
o := providerOpts[0]
|
||||
require.Len(t, o.Middlewares, 8)
|
||||
require.Len(t, o.Middlewares, 9)
|
||||
require.Equal(t, TracingMiddlewareName, o.Middlewares[0].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, DataSourceMetricsMiddlewareName, o.Middlewares[1].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ContextualMiddlewareName, o.Middlewares[2].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
@ -35,6 +35,8 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
require.Equal(t, sdkhttpclient.BasicAuthenticationMiddlewareName, o.Middlewares[4].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.CustomHeadersMiddlewareName, o.Middlewares[5].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ResponseLimitMiddlewareName, o.Middlewares[6].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, HostRedirectValidationMiddlewareName, o.Middlewares[7].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ErrorSourceMiddlewareName, o.Middlewares[8].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
})
|
||||
|
||||
t.Run("When creating new provider and SigV4 is enabled should apply expected middleware", func(t *testing.T) {
|
||||
@ -51,7 +53,7 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
_ = New(&setting.Cfg{SigV4AuthEnabled: true}, &validations.OSSPluginRequestValidator{}, tracer)
|
||||
require.Len(t, providerOpts, 1)
|
||||
o := providerOpts[0]
|
||||
require.Len(t, o.Middlewares, 9)
|
||||
require.Len(t, o.Middlewares, 10)
|
||||
require.Equal(t, TracingMiddlewareName, o.Middlewares[0].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, DataSourceMetricsMiddlewareName, o.Middlewares[1].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ContextualMiddlewareName, o.Middlewares[2].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
@ -59,7 +61,9 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
require.Equal(t, sdkhttpclient.BasicAuthenticationMiddlewareName, o.Middlewares[4].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.CustomHeadersMiddlewareName, o.Middlewares[5].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ResponseLimitMiddlewareName, o.Middlewares[6].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, awssdk.SigV4MiddlewareName, o.Middlewares[8].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, HostRedirectValidationMiddlewareName, o.Middlewares[7].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ErrorSourceMiddlewareName, o.Middlewares[8].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, awssdk.SigV4MiddlewareName, o.Middlewares[9].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
})
|
||||
|
||||
t.Run("When creating new provider and http logging is enabled for one plugin, it should apply expected middleware", func(t *testing.T) {
|
||||
@ -76,7 +80,7 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
_ = New(&setting.Cfg{PluginSettings: setting.PluginSettings{"example": {"har_log_enabled": "true"}}}, &validations.OSSPluginRequestValidator{}, tracer)
|
||||
require.Len(t, providerOpts, 1)
|
||||
o := providerOpts[0]
|
||||
require.Len(t, o.Middlewares, 9)
|
||||
require.Len(t, o.Middlewares, 10)
|
||||
require.Equal(t, TracingMiddlewareName, o.Middlewares[0].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, DataSourceMetricsMiddlewareName, o.Middlewares[1].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ContextualMiddlewareName, o.Middlewares[2].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
@ -86,5 +90,6 @@ func TestHTTPClientProvider(t *testing.T) {
|
||||
require.Equal(t, sdkhttpclient.ResponseLimitMiddlewareName, o.Middlewares[6].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, HostRedirectValidationMiddlewareName, o.Middlewares[7].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, HTTPLoggerMiddlewareName, o.Middlewares[8].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
require.Equal(t, sdkhttpclient.ErrorSourceMiddlewareName, o.Middlewares[9].(sdkhttpclient.MiddlewareName).MiddlewareName())
|
||||
})
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
package pluginrequestmeta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
)
|
||||
|
||||
// StatusSource is an enum-like string value representing the source of a
|
||||
// plugin query data response status code
|
||||
type StatusSource string
|
||||
|
||||
const (
|
||||
StatusSourcePlugin StatusSource = "plugin"
|
||||
StatusSourceDownstream StatusSource = "downstream"
|
||||
)
|
||||
|
||||
// DefaultStatusSource is the default StatusSource that should be used when it is not explicitly set by the plugin.
|
||||
const DefaultStatusSource StatusSource = StatusSourcePlugin
|
||||
|
||||
type statusSourceCtxKey struct{}
|
||||
|
||||
// StatusSourceFromContext returns the plugin request status source stored in the context.
|
||||
// If no plugin request status source is stored in the context, [DefaultStatusSource] is returned.
|
||||
func StatusSourceFromContext(ctx context.Context) StatusSource {
|
||||
value, ok := ctx.Value(statusSourceCtxKey{}).(*StatusSource)
|
||||
if ok {
|
||||
return *value
|
||||
}
|
||||
return DefaultStatusSource
|
||||
}
|
||||
|
||||
// WithStatusSource sets the plugin request status source for the context.
|
||||
func WithStatusSource(ctx context.Context, s StatusSource) context.Context {
|
||||
return context.WithValue(ctx, statusSourceCtxKey{}, &s)
|
||||
}
|
||||
|
||||
// WithDownstreamStatusSource mutates the provided context by setting the plugin request status source to
|
||||
// StatusSourceDownstream. If the provided context does not have a plugin request status source, the context
|
||||
// will not be mutated. This means that [WithStatusSource] has to be called before this function.
|
||||
func WithDownstreamStatusSource(ctx context.Context) error {
|
||||
v, ok := ctx.Value(statusSourceCtxKey{}).(*StatusSource)
|
||||
if !ok {
|
||||
return errors.New("the provided context does not have a plugin request status source")
|
||||
}
|
||||
*v = StatusSourceDownstream
|
||||
return nil
|
||||
}
|
||||
|
||||
// StatusSourceFromPluginErrorSource takes an error source returned by a plugin and returns the corresponding
|
||||
// StatusSource. If the provided value is a zero-value (i.e.: the plugin did not set it), the function returns
|
||||
// DefaultStatusSource.
|
||||
func StatusSourceFromPluginErrorSource(pluginErrorSource backend.ErrorSource) StatusSource {
|
||||
if pluginErrorSource == "" {
|
||||
return DefaultStatusSource
|
||||
}
|
||||
return StatusSource(pluginErrorSource)
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package pluginrequestmeta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStatusSource(t *testing.T) {
|
||||
t.Run("WithStatusSource", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ss := StatusSourceFromContext(ctx)
|
||||
require.Equal(t, StatusSourcePlugin, ss)
|
||||
|
||||
ctx = WithStatusSource(ctx, StatusSourceDownstream)
|
||||
ss = StatusSourceFromContext(ctx)
|
||||
require.Equal(t, StatusSourceDownstream, ss)
|
||||
})
|
||||
|
||||
t.Run("WithDownstreamStatusSource", func(t *testing.T) {
|
||||
t.Run("Returns error if no status source is set", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
err := WithDownstreamStatusSource(ctx)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, StatusSourcePlugin, StatusSourceFromContext(ctx))
|
||||
})
|
||||
|
||||
t.Run("Should mutate context if status source is set", func(t *testing.T) {
|
||||
ctx := WithStatusSource(context.Background(), StatusSourcePlugin)
|
||||
err := WithDownstreamStatusSource(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, StatusSourceDownstream, StatusSourceFromContext(ctx))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("StatusSourceFromContext", func(t *testing.T) {
|
||||
t.Run("Background returns StatusSourcePlugin", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ss := StatusSourceFromContext(ctx)
|
||||
require.Equal(t, StatusSourcePlugin, ss)
|
||||
})
|
||||
|
||||
t.Run("Context with status source returns the set status source", func(t *testing.T) {
|
||||
ctx := WithStatusSource(context.Background(), StatusSourcePlugin)
|
||||
ss := StatusSourceFromContext(ctx)
|
||||
require.Equal(t, StatusSourcePlugin, ss)
|
||||
})
|
||||
})
|
||||
}
|
@ -4,7 +4,7 @@ go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/prometheus/client_golang v1.20.4
|
||||
|
@ -98,8 +98,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3 h1:as4PmrFoYI1byS5JjsgPC7uSGTMh+SgS0ePv6hOyDGU=
|
||||
github.com/grafana/dskit v0.0.0-20240805174438-dfa83b4ed2d3/go.mod h1:lcjGB6SuaZ2o44A9nD6p/tR4QXSPbzViRY520Gy6pTQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0 h1:gnOtxrC/1rqFvpSbQYyoZqkr47oWDlz4Q2L6Ozmsi3w=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.251.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0 h1:KaCrqqsDgVIoT8hwvwuUMKV7QbHVlvRoFN5+U2rOXR8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.253.0/go.mod h1:gCGN9kHY3KeX4qyni3+Kead38Q+85pYOrsDcxZp6AIk=
|
||||
github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8=
|
||||
github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls=
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/instrumentationutils"
|
||||
plog "github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
// NewLoggerMiddleware creates a new backend.HandlerMiddleware that will
|
||||
@ -61,7 +60,7 @@ func (m *LoggerMiddleware) logRequest(ctx context.Context, pCtx backend.PluginCo
|
||||
if err != nil {
|
||||
logParams = append(logParams, "error", err)
|
||||
}
|
||||
logParams = append(logParams, "statusSource", pluginrequestmeta.StatusSourceFromContext(ctx))
|
||||
logParams = append(logParams, "statusSource", backend.ErrorSourceFromContext(ctx))
|
||||
|
||||
if status > instrumentationutils.RequestStatusOK {
|
||||
logFunc = ctxLogger.Error
|
||||
@ -93,7 +92,8 @@ func (m *LoggerMiddleware) QueryData(ctx context.Context, req *backend.QueryData
|
||||
"refID", refID,
|
||||
"status", int(dr.Status),
|
||||
"error", dr.Error,
|
||||
"statusSource", pluginrequestmeta.StatusSourceFromPluginErrorSource(dr.ErrorSource),
|
||||
"statusSource", dr.ErrorSource.String(),
|
||||
"target", m.pluginTarget(ctx, req.PluginContext),
|
||||
}
|
||||
ctxLogger.Error("Partial data response error", logParams...)
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"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"
|
||||
)
|
||||
|
||||
// pluginMetrics contains the prometheus metrics used by the MetricsMiddleware.
|
||||
@ -115,7 +114,7 @@ func (m *MetricsMiddleware) instrumentPluginRequest(ctx context.Context, pluginC
|
||||
status, err := fn(ctx)
|
||||
elapsed := time.Since(start)
|
||||
|
||||
statusSource := pluginrequestmeta.StatusSourceFromContext(ctx)
|
||||
statusSource := backend.ErrorSourceFromContext(ctx)
|
||||
endpoint := backend.EndpointFromContext(ctx)
|
||||
|
||||
pluginRequestDurationWithLabels := m.pluginRequestDuration.WithLabelValues(pluginCtx.PluginID, string(endpoint), target, string(statusSource))
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
"github.com/grafana/grafana/pkg/plugins/instrumentationutils"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -90,7 +89,7 @@ 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, string(tc.expEndpoint), instrumentationutils.RequestStatusOK.String(), string(backendplugin.TargetUnknown), string(pluginrequestmeta.DefaultStatusSource))
|
||||
counter := mw.pluginMetrics.pluginRequestCounter.WithLabelValues(pluginID, string(tc.expEndpoint), instrumentationutils.RequestStatusOK.String(), string(backendplugin.TargetUnknown), string(backend.DefaultErrorSource))
|
||||
require.Equal(t, 1.0, testutil.ToFloat64(counter))
|
||||
for _, m := range []string{metricRequestDurationMs, metricRequestDurationS} {
|
||||
require.NoError(t, checkHistogram(promRegistry, m, map[string]string{
|
||||
@ -155,12 +154,11 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
}))
|
||||
metricsMw := newMetricsMiddleware(promRegistry, pluginsRegistry)
|
||||
cdt := handlertest.NewHandlerMiddlewareTest(t, handlertest.WithMiddlewares(
|
||||
NewPluginRequestMetaMiddleware(),
|
||||
backend.HandlerMiddlewareFunc(func(next backend.Handler) backend.Handler {
|
||||
metricsMw.BaseHandler = backend.NewBaseHandler(next)
|
||||
return metricsMw
|
||||
}),
|
||||
NewStatusSourceMiddleware(),
|
||||
backend.NewErrorSourceMiddleware(),
|
||||
))
|
||||
|
||||
t.Run("Metrics", func(t *testing.T) {
|
||||
@ -185,12 +183,12 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
responses map[string]backend.DataResponse
|
||||
expStatusSource pluginrequestmeta.StatusSource
|
||||
expStatusSource backend.ErrorSource
|
||||
}{
|
||||
{
|
||||
"Default status source for ok responses should be plugin",
|
||||
map[string]backend.DataResponse{"A": okResponse},
|
||||
pluginrequestmeta.StatusSourcePlugin,
|
||||
backend.ErrorSourcePlugin,
|
||||
},
|
||||
{
|
||||
"Plugin errors should have higher priority than downstream errors",
|
||||
@ -198,12 +196,12 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
"A": pluginErrorResponse,
|
||||
"B": downstreamErrorResponse,
|
||||
},
|
||||
pluginrequestmeta.StatusSourcePlugin,
|
||||
backend.ErrorSourcePlugin,
|
||||
},
|
||||
{
|
||||
"Errors without ErrorSource should be reported as plugin status source",
|
||||
map[string]backend.DataResponse{"A": legacyErrorResponse},
|
||||
pluginrequestmeta.StatusSourcePlugin,
|
||||
backend.ErrorSourcePlugin,
|
||||
},
|
||||
{
|
||||
"Downstream errors should have higher priority than ok responses",
|
||||
@ -211,7 +209,7 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
"A": okResponse,
|
||||
"B": downstreamErrorResponse,
|
||||
},
|
||||
pluginrequestmeta.StatusSourceDownstream,
|
||||
backend.ErrorSourceDownstream,
|
||||
},
|
||||
{
|
||||
"Plugin errors should have higher priority than ok responses",
|
||||
@ -219,7 +217,7 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
"A": okResponse,
|
||||
"B": pluginErrorResponse,
|
||||
},
|
||||
pluginrequestmeta.StatusSourcePlugin,
|
||||
backend.ErrorSourcePlugin,
|
||||
},
|
||||
{
|
||||
"Legacy errors should have higher priority than ok responses",
|
||||
@ -227,7 +225,7 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
"A": okResponse,
|
||||
"B": legacyErrorResponse,
|
||||
},
|
||||
pluginrequestmeta.StatusSourcePlugin,
|
||||
backend.ErrorSourcePlugin,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@ -242,7 +240,7 @@ func TestInstrumentationMiddlewareStatusSource(t *testing.T) {
|
||||
}
|
||||
_, err := cdt.MiddlewareHandler.QueryData(context.Background(), &backend.QueryDataRequest{PluginContext: pCtx})
|
||||
require.NoError(t, err)
|
||||
ctxStatusSource := pluginrequestmeta.StatusSourceFromContext(cdt.QueryDataCtx)
|
||||
ctxStatusSource := backend.ErrorSourceFromContext(cdt.QueryDataCtx)
|
||||
require.Equal(t, tc.expStatusSource, ctxStatusSource)
|
||||
})
|
||||
}
|
||||
|
@ -1,86 +0,0 @@
|
||||
package clientmiddleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
// NewPluginRequestMetaMiddleware returns a new backend.HandlerMiddleware that sets up the default
|
||||
// values for the plugin request meta in the context.Context. All middlewares that are executed
|
||||
// after this one are be able to access plugin request meta via the pluginrequestmeta package.
|
||||
func NewPluginRequestMetaMiddleware() backend.HandlerMiddleware {
|
||||
return backend.HandlerMiddlewareFunc(func(next backend.Handler) backend.Handler {
|
||||
return &PluginRequestMetaMiddleware{
|
||||
BaseHandler: backend.NewBaseHandler(next),
|
||||
defaultStatusSource: pluginrequestmeta.DefaultStatusSource,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type PluginRequestMetaMiddleware struct {
|
||||
backend.BaseHandler
|
||||
defaultStatusSource pluginrequestmeta.StatusSource
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) withDefaultPluginRequestMeta(ctx context.Context) context.Context {
|
||||
// Setup plugin request status source
|
||||
ctx = pluginrequestmeta.WithStatusSource(ctx, m.defaultStatusSource)
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.QueryData(ctx, req)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.CallResource(ctx, req, sender)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.CheckHealth(ctx, req)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.CollectMetrics(ctx, req)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.SubscribeStream(ctx, req)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.PublishStream(ctx, req)
|
||||
}
|
||||
|
||||
func (m *PluginRequestMetaMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) ConvertObjects(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.BaseHandler.ConvertObjects(ctx, req)
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package clientmiddleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/handlertest"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
func TestPluginRequestMetaMiddleware(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
cdt := handlertest.NewHandlerMiddlewareTest(t,
|
||||
handlertest.WithMiddlewares(NewPluginRequestMetaMiddleware()),
|
||||
)
|
||||
_, err := cdt.MiddlewareHandler.QueryData(context.Background(), &backend.QueryDataRequest{})
|
||||
require.NoError(t, err)
|
||||
ss := pluginrequestmeta.StatusSourceFromContext(cdt.QueryDataCtx)
|
||||
require.Equal(t, pluginrequestmeta.StatusSourcePlugin, ss)
|
||||
})
|
||||
|
||||
t.Run("other value", func(t *testing.T) {
|
||||
cdt := handlertest.NewHandlerMiddlewareTest(t,
|
||||
handlertest.WithMiddlewares(backend.HandlerMiddlewareFunc(func(next backend.Handler) backend.Handler {
|
||||
return &PluginRequestMetaMiddleware{
|
||||
BaseHandler: backend.NewBaseHandler(next),
|
||||
defaultStatusSource: "test",
|
||||
}
|
||||
})),
|
||||
)
|
||||
_, err := cdt.MiddlewareHandler.QueryData(context.Background(), &backend.QueryDataRequest{})
|
||||
require.NoError(t, err)
|
||||
ss := pluginrequestmeta.StatusSourceFromContext(cdt.QueryDataCtx)
|
||||
require.Equal(t, pluginrequestmeta.StatusSource("test"), ss)
|
||||
})
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package clientmiddleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
// NewStatusSourceMiddleware returns a new backend.HandlerMiddleware that sets the status source in the
|
||||
// plugin request meta stored in the context.Context, according to the query data responses returned by QueryError.
|
||||
// If at least one query data response has a "downstream" status source and there isn't one with a "plugin" status source,
|
||||
// the plugin request meta in the context is set to "downstream".
|
||||
func NewStatusSourceMiddleware() backend.HandlerMiddleware {
|
||||
return backend.HandlerMiddlewareFunc(func(next backend.Handler) backend.Handler {
|
||||
return &StatusSourceMiddleware{
|
||||
BaseHandler: backend.NewBaseHandler(next),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type StatusSourceMiddleware struct {
|
||||
backend.BaseHandler
|
||||
}
|
||||
|
||||
func (m *StatusSourceMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
resp, err := m.BaseHandler.QueryData(ctx, req)
|
||||
if resp == nil || len(resp.Responses) == 0 {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Set downstream status source in the context if there's at least one response with downstream status source,
|
||||
// and if there's no plugin error
|
||||
var hasPluginError bool
|
||||
var hasDownstreamError bool
|
||||
for _, r := range resp.Responses {
|
||||
if r.Error == nil {
|
||||
continue
|
||||
}
|
||||
if r.ErrorSource == backend.ErrorSourceDownstream {
|
||||
hasDownstreamError = true
|
||||
} else {
|
||||
hasPluginError = true
|
||||
}
|
||||
}
|
||||
|
||||
// A plugin error has higher priority than a downstream error,
|
||||
// so set to downstream only if there's no plugin error
|
||||
if hasDownstreamError && !hasPluginError {
|
||||
if err := pluginrequestmeta.WithDownstreamStatusSource(ctx); err != nil {
|
||||
return resp, fmt.Errorf("failed to set downstream status source: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
package clientmiddleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/handlertest"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginrequestmeta"
|
||||
)
|
||||
|
||||
func TestStatusSourceMiddleware(t *testing.T) {
|
||||
someErr := errors.New("oops")
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
|
||||
queryDataResponse *backend.QueryDataResponse
|
||||
|
||||
expStatusSource pluginrequestmeta.StatusSource
|
||||
}{
|
||||
{
|
||||
name: `no error should be "plugin" status source`,
|
||||
queryDataResponse: nil,
|
||||
expStatusSource: pluginrequestmeta.StatusSourcePlugin,
|
||||
},
|
||||
{
|
||||
name: `single downstream error should be "downstream" status source`,
|
||||
queryDataResponse: &backend.QueryDataResponse{
|
||||
Responses: map[string]backend.DataResponse{
|
||||
"A": {Error: someErr, ErrorSource: backend.ErrorSourceDownstream},
|
||||
},
|
||||
},
|
||||
expStatusSource: pluginrequestmeta.StatusSourceDownstream,
|
||||
},
|
||||
{
|
||||
name: `single plugin error should be "plugin" status source`,
|
||||
queryDataResponse: &backend.QueryDataResponse{
|
||||
Responses: map[string]backend.DataResponse{
|
||||
"A": {Error: someErr, ErrorSource: backend.ErrorSourcePlugin},
|
||||
},
|
||||
},
|
||||
expStatusSource: pluginrequestmeta.StatusSourcePlugin,
|
||||
},
|
||||
{
|
||||
name: `multiple downstream errors should be "downstream" status source`,
|
||||
queryDataResponse: &backend.QueryDataResponse{
|
||||
Responses: map[string]backend.DataResponse{
|
||||
"A": {Error: someErr, ErrorSource: backend.ErrorSourceDownstream},
|
||||
"B": {Error: someErr, ErrorSource: backend.ErrorSourceDownstream},
|
||||
},
|
||||
},
|
||||
expStatusSource: pluginrequestmeta.StatusSourceDownstream,
|
||||
},
|
||||
{
|
||||
name: `single plugin error mixed with downstream errors should be "plugin" status source`,
|
||||
queryDataResponse: &backend.QueryDataResponse{
|
||||
Responses: map[string]backend.DataResponse{
|
||||
"A": {Error: someErr, ErrorSource: backend.ErrorSourceDownstream},
|
||||
"B": {Error: someErr, ErrorSource: backend.ErrorSourcePlugin},
|
||||
"C": {Error: someErr, ErrorSource: backend.ErrorSourceDownstream},
|
||||
},
|
||||
},
|
||||
expStatusSource: pluginrequestmeta.StatusSourcePlugin,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cdt := handlertest.NewHandlerMiddlewareTest(t,
|
||||
handlertest.WithMiddlewares(
|
||||
NewPluginRequestMetaMiddleware(),
|
||||
NewStatusSourceMiddleware(),
|
||||
),
|
||||
)
|
||||
cdt.TestHandler.QueryDataFunc = func(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
cdt.QueryDataCtx = ctx
|
||||
return tc.queryDataResponse, nil
|
||||
}
|
||||
|
||||
_, _ = cdt.MiddlewareHandler.QueryData(context.Background(), &backend.QueryDataRequest{})
|
||||
|
||||
ss := pluginrequestmeta.StatusSourceFromContext(cdt.QueryDataCtx)
|
||||
require.Equal(t, tc.expStatusSource, ss)
|
||||
})
|
||||
}
|
||||
}
|
@ -171,7 +171,6 @@ func NewMiddlewareHandler(
|
||||
|
||||
func CreateMiddlewares(cfg *setting.Cfg, oAuthTokenService oauthtoken.OAuthTokenService, tracer tracing.Tracer, cachingService caching.CachingService, features featuremgmt.FeatureToggles, promRegisterer prometheus.Registerer, registry registry.Service) []backend.HandlerMiddleware {
|
||||
middlewares := []backend.HandlerMiddleware{
|
||||
clientmiddleware.NewPluginRequestMetaMiddleware(),
|
||||
clientmiddleware.NewTracingMiddleware(tracer),
|
||||
clientmiddleware.NewMetricsMiddleware(promRegisterer, registry),
|
||||
clientmiddleware.NewContextualLoggerMiddleware(),
|
||||
@ -202,9 +201,9 @@ func CreateMiddlewares(cfg *setting.Cfg, oAuthTokenService oauthtoken.OAuthToken
|
||||
|
||||
middlewares = append(middlewares, clientmiddleware.NewHTTPClientMiddleware())
|
||||
|
||||
// StatusSourceMiddleware should be at the very bottom, or any middlewares below it won't see the
|
||||
// correct status source in their context.Context
|
||||
middlewares = append(middlewares, clientmiddleware.NewStatusSourceMiddleware())
|
||||
// ErrorSourceMiddleware should be at the very bottom, or any middlewares below it won't see the
|
||||
// correct error source in their context.Context
|
||||
middlewares = append(middlewares, backend.NewErrorSourceMiddleware())
|
||||
|
||||
return middlewares
|
||||
}
|
||||
|
@ -38,6 +38,16 @@ const (
|
||||
ErrorTypeServerPanic ErrorType = "server_panic"
|
||||
)
|
||||
|
||||
// ErrorSource defines model for TestDataQuery.ErrorSource.
|
||||
// +enum
|
||||
type ErrorSource string
|
||||
|
||||
// Defines values for ErrorSource.
|
||||
const (
|
||||
ErrorSourcePlugin ErrorSource = "plugin"
|
||||
ErrorSourceDownstream ErrorSource = "downstream"
|
||||
)
|
||||
|
||||
// TestDataQueryType defines model for TestDataQueryType.
|
||||
// +enum
|
||||
type TestDataQueryType string
|
||||
@ -50,6 +60,7 @@ const (
|
||||
TestDataQueryTypeCsvFile TestDataQueryType = "csv_file"
|
||||
TestDataQueryTypeCsvMetricValues TestDataQueryType = "csv_metric_values"
|
||||
TestDataQueryTypeDatapointsOutsideRange TestDataQueryType = "datapoints_outside_range"
|
||||
TestDataQueryTypeErrorWithSource TestDataQueryType = "error_with_source"
|
||||
TestDataQueryTypeExponentialHeatmapBucketData TestDataQueryType = "exponential_heatmap_bucket_data"
|
||||
TestDataQueryTypeFlameGraph TestDataQueryType = "flame_graph"
|
||||
TestDataQueryTypeGrafanaApi TestDataQueryType = "grafana_api"
|
||||
@ -92,21 +103,22 @@ type TestDataQuery struct {
|
||||
Channel string `json:"channel,omitempty"`
|
||||
|
||||
// Drop percentage (the chance we will lose a point 0-100)
|
||||
DropPercent float64 `json:"dropPercent,omitempty"`
|
||||
ErrorType ErrorType `json:"errorType,omitempty"`
|
||||
FlamegraphDiff bool `json:"flamegraphDiff,omitempty"`
|
||||
LevelColumn bool `json:"levelColumn,omitempty"`
|
||||
StartValue float64 `json:"startValue,omitempty"`
|
||||
Spread float64 `json:"spread,omitempty"`
|
||||
Noise float64 `json:"noise,omitempty"`
|
||||
Min *float64 `json:"min,omitempty"`
|
||||
Max *float64 `json:"max,omitempty"`
|
||||
WithNil bool `json:"withNil,omitempty"`
|
||||
Lines int64 `json:"lines,omitempty"`
|
||||
Points [][]any `json:"points,omitempty"`
|
||||
RawFrameContent string `json:"rawFrameContent,omitempty"`
|
||||
SeriesCount int `json:"seriesCount,omitempty"`
|
||||
SpanCount int `json:"spanCount,omitempty"`
|
||||
DropPercent float64 `json:"dropPercent,omitempty"`
|
||||
ErrorType ErrorType `json:"errorType,omitempty"`
|
||||
FlamegraphDiff bool `json:"flamegraphDiff,omitempty"`
|
||||
LevelColumn bool `json:"levelColumn,omitempty"`
|
||||
StartValue float64 `json:"startValue,omitempty"`
|
||||
Spread float64 `json:"spread,omitempty"`
|
||||
Noise float64 `json:"noise,omitempty"`
|
||||
Min *float64 `json:"min,omitempty"`
|
||||
Max *float64 `json:"max,omitempty"`
|
||||
WithNil bool `json:"withNil,omitempty"`
|
||||
Lines int64 `json:"lines,omitempty"`
|
||||
Points [][]any `json:"points,omitempty"`
|
||||
RawFrameContent string `json:"rawFrameContent,omitempty"`
|
||||
SeriesCount int `json:"seriesCount,omitempty"`
|
||||
SpanCount int `json:"spanCount,omitempty"`
|
||||
ErrorSource ErrorSource `json:"errorSource,omitempty"`
|
||||
|
||||
Nodes *NodesQuery `json:"nodes,omitempty"`
|
||||
PulseWave *PulseWaveQuery `json:"pulseWave,omitempty"`
|
||||
|
@ -73,6 +73,15 @@
|
||||
"description": "Drop percentage (the chance we will lose a point 0-100)",
|
||||
"type": "number"
|
||||
},
|
||||
"errorSource": {
|
||||
"description": "Possible enum values:\n - `\"plugin\"` \n - `\"downstream\"` ",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"plugin",
|
||||
"downstream"
|
||||
],
|
||||
"x-enum-description": {}
|
||||
},
|
||||
"errorType": {
|
||||
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
|
||||
"type": "string",
|
||||
@ -220,7 +229,7 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
"scenarioId": {
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"error_with_source\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"annotations",
|
||||
@ -229,6 +238,7 @@
|
||||
"csv_file",
|
||||
"csv_metric_values",
|
||||
"datapoints_outside_range",
|
||||
"error_with_source",
|
||||
"exponential_heatmap_bucket_data",
|
||||
"flame_graph",
|
||||
"grafana_api",
|
||||
|
@ -83,6 +83,15 @@
|
||||
"description": "Drop percentage (the chance we will lose a point 0-100)",
|
||||
"type": "number"
|
||||
},
|
||||
"errorSource": {
|
||||
"description": "Possible enum values:\n - `\"plugin\"` \n - `\"downstream\"` ",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"plugin",
|
||||
"downstream"
|
||||
],
|
||||
"x-enum-description": {}
|
||||
},
|
||||
"errorType": {
|
||||
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
|
||||
"type": "string",
|
||||
@ -230,7 +239,7 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
"scenarioId": {
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"error_with_source\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"annotations",
|
||||
@ -239,6 +248,7 @@
|
||||
"csv_file",
|
||||
"csv_metric_values",
|
||||
"datapoints_outside_range",
|
||||
"error_with_source",
|
||||
"exponential_heatmap_bucket_data",
|
||||
"flame_graph",
|
||||
"grafana_api",
|
||||
|
@ -8,7 +8,7 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "default",
|
||||
"resourceVersion": "1711119846950",
|
||||
"resourceVersion": "1728405292506",
|
||||
"creationTimestamp": "2024-03-01T02:53:35Z"
|
||||
},
|
||||
"spec": {
|
||||
@ -56,6 +56,15 @@
|
||||
"description": "Drop percentage (the chance we will lose a point 0-100)",
|
||||
"type": "number"
|
||||
},
|
||||
"errorSource": {
|
||||
"description": "Possible enum values:\n - `\"plugin\"` \n - `\"downstream\"` ",
|
||||
"enum": [
|
||||
"plugin",
|
||||
"downstream"
|
||||
],
|
||||
"type": "string",
|
||||
"x-enum-description": {}
|
||||
},
|
||||
"errorType": {
|
||||
"description": "Possible enum values:\n - `\"frontend_exception\"` \n - `\"frontend_observable\"` \n - `\"server_panic\"` ",
|
||||
"enum": [
|
||||
@ -142,7 +151,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"scenarioId": {
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"description": "Possible enum values:\n - `\"annotations\"` \n - `\"arrow\"` \n - `\"csv_content\"` \n - `\"csv_file\"` \n - `\"csv_metric_values\"` \n - `\"datapoints_outside_range\"` \n - `\"error_with_source\"` \n - `\"exponential_heatmap_bucket_data\"` \n - `\"flame_graph\"` \n - `\"grafana_api\"` \n - `\"linear_heatmap_bucket_data\"` \n - `\"live\"` \n - `\"logs\"` \n - `\"manual_entry\"` \n - `\"no_data_points\"` \n - `\"node_graph\"` \n - `\"predictable_csv_wave\"` \n - `\"predictable_pulse\"` \n - `\"random_walk\"` \n - `\"random_walk_table\"` \n - `\"random_walk_with_error\"` \n - `\"raw_frame\"` \n - `\"server_error_500\"` \n - `\"simulation\"` \n - `\"slow_query\"` \n - `\"streaming_client\"` \n - `\"table_static\"` \n - `\"trace\"` \n - `\"usa\"` \n - `\"variables-query\"` ",
|
||||
"enum": [
|
||||
"annotations",
|
||||
"arrow",
|
||||
@ -150,6 +159,7 @@
|
||||
"csv_file",
|
||||
"csv_metric_values",
|
||||
"datapoints_outside_range",
|
||||
"error_with_source",
|
||||
"exponential_heatmap_bucket_data",
|
||||
"flame_graph",
|
||||
"grafana_api",
|
||||
|
@ -21,6 +21,7 @@ func TestQueryTypeDefinitions(t *testing.T) {
|
||||
reflect.TypeOf(NodesQueryTypeRandom), // pick an example value (not the root)
|
||||
reflect.TypeOf(StreamingQueryTypeFetch), // pick an example value (not the root)
|
||||
reflect.TypeOf(ErrorTypeServerPanic), // pick an example value (not the root)
|
||||
reflect.TypeOf(ErrorSourcePlugin), // pick an example value (not the root)
|
||||
reflect.TypeOf(TestDataQueryTypeAnnotations), // pick an example value (not the root)
|
||||
},
|
||||
})
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
@ -198,6 +199,12 @@ Timestamps will line up evenly on timeStepSeconds (For example, 60 seconds means
|
||||
Name: "Trace",
|
||||
})
|
||||
|
||||
s.registerScenario(&Scenario{
|
||||
ID: kinds.TestDataQueryTypeErrorWithSource,
|
||||
Name: "Error with source",
|
||||
handler: s.handleErrorWithSourceScenario,
|
||||
})
|
||||
|
||||
s.queryMux.HandleFunc("", s.handleFallbackScenario)
|
||||
}
|
||||
|
||||
@ -663,6 +670,29 @@ func (s *Service) handleLogsScenario(ctx context.Context, req *backend.QueryData
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *Service) handleErrorWithSourceScenario(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
anErr := errors.New("error")
|
||||
resp := backend.NewQueryDataResponse()
|
||||
|
||||
for _, q := range req.Queries {
|
||||
model, err := GetJSONModel(q.JSON)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
respD := resp.Responses[q.RefID]
|
||||
respD.Error = anErr
|
||||
|
||||
if model.ErrorSource == kinds.ErrorSourceDownstream {
|
||||
respD.Error = backend.DownstreamError(respD.Error)
|
||||
}
|
||||
|
||||
resp.Responses[q.RefID] = respD
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func RandomWalk(query backend.DataQuery, model kinds.TestDataQuery, index int) *data.Frame {
|
||||
rand := rand.New(rand.NewSource(time.Now().UnixNano() + int64(index)))
|
||||
timeWalkerMs := query.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
||||
|
@ -4064,7 +4064,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"ErrorSource": {
|
||||
"$ref": "#/definitions/ErrorSource"
|
||||
"$ref": "#/definitions/Source"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/definitions/Frames"
|
||||
@ -4361,10 +4361,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ErrorSource": {
|
||||
"description": "ErrorSource type defines the source of the error",
|
||||
"type": "string"
|
||||
},
|
||||
"ExplorePanelsState": {
|
||||
"description": "This is an object constructed with the keys as the values of the enum VisType and the value being a bag of properties"
|
||||
},
|
||||
@ -7284,6 +7280,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Source": {
|
||||
"type": "string",
|
||||
"title": "Source type defines the status source."
|
||||
},
|
||||
"State": {
|
||||
"description": "+enum",
|
||||
"type": "string"
|
||||
|
@ -14503,7 +14503,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"ErrorSource": {
|
||||
"$ref": "#/definitions/ErrorSource"
|
||||
"$ref": "#/definitions/Source"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/definitions/Frames"
|
||||
@ -20478,6 +20478,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Source": {
|
||||
"type": "string",
|
||||
"title": "Source type defines the status source."
|
||||
},
|
||||
"Span": {
|
||||
"type": "object",
|
||||
"title": "A Span defines a continuous sequence of buckets.",
|
||||
|
@ -10,6 +10,7 @@ import { CSVContentEditor } from './components/CSVContentEditor';
|
||||
import { CSVFileEditor } from './components/CSVFileEditor';
|
||||
import { CSVWavesEditor } from './components/CSVWaveEditor';
|
||||
import ErrorEditor from './components/ErrorEditor';
|
||||
import ErrorWithSourceQueryEditor from './components/ErrorWithSourceEditor';
|
||||
import { GrafanaLiveEditor } from './components/GrafanaLiveEditor';
|
||||
import { NodeGraphEditor } from './components/NodeGraphEditor';
|
||||
import { PredictablePulseEditor } from './components/PredictablePulseEditor';
|
||||
@ -120,6 +121,9 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props)
|
||||
update.usa = {
|
||||
mode: usaQueryModes[0].value,
|
||||
};
|
||||
break;
|
||||
case TestDataQueryType.ErrorWithSource:
|
||||
update.errorSource = 'plugin';
|
||||
}
|
||||
|
||||
onUpdate(update);
|
||||
@ -379,6 +383,9 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props)
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
{scenarioId === TestDataQueryType.ErrorWithSource && (
|
||||
<ErrorWithSourceQueryEditor onChange={onUpdate} query={query} ds={datasource} />
|
||||
)}
|
||||
|
||||
{description && <p>{description}</p>}
|
||||
</>
|
||||
|
@ -0,0 +1,32 @@
|
||||
import { InlineField, InlineFieldRow, Select } from '@grafana/ui';
|
||||
|
||||
import { EditorProps } from '../QueryEditor';
|
||||
|
||||
const OPTIONS = [
|
||||
{
|
||||
label: 'Plugin',
|
||||
value: 'plugin',
|
||||
},
|
||||
{
|
||||
label: 'Downstream',
|
||||
value: 'downstream',
|
||||
},
|
||||
];
|
||||
|
||||
const ErrorWithSourceQueryEditor = ({ query, onChange }: EditorProps) => {
|
||||
return (
|
||||
<InlineFieldRow>
|
||||
<InlineField labelWidth={14} label="Error source">
|
||||
<Select
|
||||
options={OPTIONS}
|
||||
value={query.errorSource}
|
||||
onChange={(v) => {
|
||||
onChange({ ...query, errorSource: v.value });
|
||||
}}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorWithSourceQueryEditor;
|
@ -33,6 +33,7 @@ export enum TestDataQueryType {
|
||||
Trace = 'trace',
|
||||
USA = 'usa',
|
||||
VariablesQuery = 'variables-query',
|
||||
ErrorWithSource = 'error_with_source',
|
||||
}
|
||||
|
||||
export interface StreamingQuery {
|
||||
@ -125,6 +126,7 @@ export interface TestDataDataQuery extends common.DataQuery {
|
||||
stream?: StreamingQuery;
|
||||
stringInput?: string;
|
||||
usa?: USAQuery;
|
||||
errorSource?: 'plugin' | 'downstream';
|
||||
}
|
||||
|
||||
export const defaultTestDataDataQuery: Partial<TestDataDataQuery> = {
|
||||
|
@ -4728,7 +4728,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"ErrorSource": {
|
||||
"$ref": "#/components/schemas/ErrorSource"
|
||||
"$ref": "#/components/schemas/Source"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/components/schemas/Frames"
|
||||
@ -10704,6 +10704,10 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Source": {
|
||||
"title": "Source type defines the status source.",
|
||||
"type": "string"
|
||||
},
|
||||
"Span": {
|
||||
"properties": {
|
||||
"Length": {
|
||||
|
Loading…
Reference in New Issue
Block a user