grafana/pkg/promlib/instrumentation/instrumentation.go
Marcus Efraimsson c8af659f02
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
2024-07-09 15:03:46 +02:00

88 lines
2.1 KiB
Go

package instrumentation
import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
pluginRequestCounter = promauto.NewCounterVec(prometheus.CounterOpts{
Namespace: "grafana",
Name: "prometheus_plugin_backend_request_count",
Help: "The total amount of prometheus backend plugin requests",
}, []string{"endpoint", "status", "errorSource"})
)
const (
StatusOK = "ok"
StatusError = "error"
EndpointCallResource = string(backend.EndpointCallResource)
EndpointQueryData = string(backend.EndpointQueryData)
PluginSource = "plugin"
ExternalSource = "external"
DatabaseSource = "database"
NoneSource = "none"
)
func UpdateQueryDataMetrics(err error, resp *backend.QueryDataResponse) {
status := StatusOK
if err != nil {
status = StatusError
}
errorSource := getErrorSource(err, resp)
pluginRequestCounter.WithLabelValues(EndpointQueryData, status, errorSource).Inc()
}
func getErrorSource(err error, resp *backend.QueryDataResponse) string {
if err != nil {
return PluginSource
}
// If there is different errorSource from the list of responses, we want to return the most severe one.
// The priority order is: pluginSource > databaseSource > externalSource > noneSource
var errorSource = NoneSource
for _, res := range resp.Responses {
responseErrorSource := getErrorSourceForResponse(res)
if responseErrorSource == PluginSource {
return PluginSource
}
if responseErrorSource == DatabaseSource {
errorSource = DatabaseSource
}
if responseErrorSource == ExternalSource && errorSource == NoneSource {
errorSource = ExternalSource
}
}
return errorSource
}
func getErrorSourceForResponse(res backend.DataResponse) string {
if res.Error != nil {
return PluginSource
}
if res.Status >= 500 {
return DatabaseSource
}
if res.Status >= 400 {
// Those error codes are related to authentication and authorization.
if res.Status == 401 || res.Status == 402 || res.Status == 403 || res.Status == 407 {
return ExternalSource
}
return PluginSource
}
return NoneSource
}