3
0
mirror of https://github.com/grafana/grafana.git synced 2025-02-25 18:55:37 -06:00

web: add slo group to request meta ()

Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
Carl Bergquist 2023-09-22 10:52:28 +02:00 committed by GitHub
parent 61cdfba87a
commit e5fbc4a4cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 14 deletions
docs/sources/setup-grafana/configure-grafana/feature-toggles
packages/grafana-data/src/types
pkg

View File

@ -138,6 +138,7 @@ Experimental features might be changed or removed without prior notice.
| `alertingInsights` | Show the new alerting insights landing page | | `alertingInsights` | Show the new alerting insights landing page |
| `externalCorePlugins` | Allow core plugins to be loaded as external | | `externalCorePlugins` | Allow core plugins to be loaded as external |
| `pluginsAPIMetrics` | Sends metrics of public grafana packages usage by plugins | | `pluginsAPIMetrics` | Sends metrics of public grafana packages usage by plugins |
| `httpSLOLevels` | Adds SLO level to http request metrics |
## Development feature toggles ## Development feature toggles

View File

@ -129,4 +129,5 @@ export interface FeatureToggles {
alertingInsights?: boolean; alertingInsights?: boolean;
externalCorePlugins?: boolean; externalCorePlugins?: boolean;
pluginsAPIMetrics?: boolean; pluginsAPIMetrics?: boolean;
httpSLOLevels?: boolean;
} }

View File

@ -436,19 +436,19 @@ func (hs *HTTPServer) registerRoutes() {
} }
apiRoute.Get("/frontend/settings/", hs.GetFrontendSettings) apiRoute.Get("/frontend/settings/", hs.GetFrontendSettings)
apiRoute.Any("/datasources/proxy/:id/*", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequest) apiRoute.Any("/datasources/proxy/:id/*", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequest)
apiRoute.Any("/datasources/proxy/uid/:uid/*", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID) apiRoute.Any("/datasources/proxy/uid/:uid/*", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID)
apiRoute.Any("/datasources/proxy/:id", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequest) apiRoute.Any("/datasources/proxy/:id", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequest)
apiRoute.Any("/datasources/proxy/uid/:uid", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID) apiRoute.Any("/datasources/proxy/uid/:uid", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.ProxyDataSourceRequestWithUID)
// Deprecated: use /datasources/uid/:uid/resources API instead. // Deprecated: use /datasources/uid/:uid/resources API instead.
apiRoute.Any("/datasources/:id/resources", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource) apiRoute.Any("/datasources/:id/resources", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource)
apiRoute.Any("/datasources/uid/:uid/resources", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID) apiRoute.Any("/datasources/uid/:uid/resources", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID)
// Deprecated: use /datasources/uid/:uid/resources/* API instead. // Deprecated: use /datasources/uid/:uid/resources/* API instead.
apiRoute.Any("/datasources/:id/resources/*", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource) apiRoute.Any("/datasources/:id/resources/*", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResource)
apiRoute.Any("/datasources/uid/:uid/resources/*", authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID) apiRoute.Any("/datasources/uid/:uid/resources/*", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), hs.CallDatasourceResourceWithUID)
// Deprecated: use /datasources/uid/:uid/health API instead. // Deprecated: use /datasources/uid/:uid/health API instead.
apiRoute.Any("/datasources/:id/health", authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealth)) apiRoute.Any("/datasources/:id/health", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealth))
apiRoute.Any("/datasources/uid/:uid/health", authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealthWithUID)) apiRoute.Any("/datasources/uid/:uid/health", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.CheckDatasourceHealthWithUID))
// Folders // Folders
apiRoute.Group("/folders", func(folderRoute routing.RouteRegister) { apiRoute.Group("/folders", func(folderRoute routing.RouteRegister) {
@ -532,7 +532,7 @@ func (hs *HTTPServer) registerRoutes() {
// metrics // metrics
// DataSource w/ expressions // DataSource w/ expressions
apiRoute.Post("/ds/query", authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.QueryMetricsV2)) apiRoute.Post("/ds/query", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(datasources.ActionQuery)), routing.Wrap(hs.QueryMetricsV2))
apiRoute.Group("/alerts", func(alertsRoute routing.RouteRegister) { apiRoute.Group("/alerts", func(alertsRoute routing.RouteRegister) {
alertsRoute.Post("/test", routing.Wrap(hs.AlertTest)) alertsRoute.Post("/test", routing.Wrap(hs.AlertTest))
@ -597,7 +597,7 @@ func (hs *HTTPServer) registerRoutes() {
// Some channels may have info // Some channels may have info
liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP)) liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP))
}) }, requestmeta.SetSLOGroup(requestmeta.SLOGroupNone))
// short urls // short urls
apiRoute.Post("/short-urls", routing.Wrap(hs.createShortURL)) apiRoute.Post("/short-urls", routing.Wrap(hs.createShortURL))

View File

@ -45,6 +45,10 @@ func RequestMetrics(features featuremgmt.FeatureToggles, cfg *setting.Cfg, promR
histogramLabels = append(histogramLabels, "team") histogramLabels = append(histogramLabels, "team")
} }
if features.IsEnabled(featuremgmt.FlagHttpSLOLevels) {
histogramLabels = append(histogramLabels, "slo_group")
}
httpRequestDurationHistogram := prometheus.NewHistogramVec( httpRequestDurationHistogram := prometheus.NewHistogramVec(
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Namespace: "grafana", Namespace: "grafana",
@ -95,6 +99,10 @@ func RequestMetrics(features featuremgmt.FeatureToggles, cfg *setting.Cfg, promR
labelValues = append(labelValues, rmd.Team) labelValues = append(labelValues, rmd.Team)
} }
if features.IsEnabled(featuremgmt.FlagHttpSLOLevels) {
labelValues = append(labelValues, string(rmd.SLOGroup))
}
// avoiding the sanitize functions for in the new instrumentation // avoiding the sanitize functions for in the new instrumentation
// since they dont make much sense. We should remove them later. // since they dont make much sense. We should remove them later.
histogram := httpRequestDurationHistogram. histogram := httpRequestDurationHistogram.

View File

@ -20,13 +20,38 @@ const (
StatusSourceDownstream StatusSource = "downstream" StatusSourceDownstream StatusSource = "downstream"
) )
type rMDContextKey struct{}
type RequestMetaData struct { type RequestMetaData struct {
Team string Team string
StatusSource StatusSource StatusSource StatusSource
SLOGroup SLOGroup
} }
type SLOGroup string
const (
// SLOGroupHighFast is the default slo group for handlers in Grafana
// Most handlers should respond quickly
SLOGroupHighFast SLOGroup = "high-fast"
// SLOGroupHighMedium is used for handlers that might take some
// time to respond.
SLOGroupHighMedium SLOGroup = "high-medium"
// SLOGroupHighSlow is used by handlers that proxies requests downstream.
// We expect an high successrate but without latency garantess
SLOGroupHighSlow SLOGroup = "high-slow"
// SLOGroupLow should only be used for experimental features
// that might not be stable enough for our normal SLO
SLOGroupLow SLOGroup = "low"
// SLOGroupNone means that errors are expect for this handler and
// it should not be included in the SLO.
SLOGroupNone SLOGroup = "none"
)
type rMDContextKey struct{}
var requestMetaDataContextKey = rMDContextKey{} var requestMetaDataContextKey = rMDContextKey{}
// SetupRequestMetadata injects defaul request metadata values // SetupRequestMetadata injects defaul request metadata values
@ -96,5 +121,14 @@ func defaultRequestMetadata() RequestMetaData {
return RequestMetaData{ return RequestMetaData{
Team: TeamCore, Team: TeamCore,
StatusSource: StatusSourceServer, StatusSource: StatusSourceServer,
SLOGroup: SLOGroupHighFast,
}
}
// SetSLOGroup creates an middleware that sets the SLOGroup for the request
func SetSLOGroup(lvl SLOGroup) web.Handler {
return func(w http.ResponseWriter, r *http.Request) {
v := GetRequestMetaData(r.Context())
v.SLOGroup = lvl
} }
} }

View File

@ -772,5 +772,13 @@ var (
Stage: FeatureStageExperimental, Stage: FeatureStageExperimental,
Owner: grafanaPluginsPlatformSquad, Owner: grafanaPluginsPlatformSquad,
}, },
{
Name: "httpSLOLevels",
Description: "Adds SLO level to http request metrics",
Stage: FeatureStageExperimental,
FrontendOnly: false,
Owner: hostedGrafanaTeam,
RequiresRestart: true,
},
} }
) )

View File

@ -110,3 +110,4 @@ wargamesTesting,experimental,@grafana/hosted-grafana-team,false,false,false,fals
alertingInsights,experimental,@grafana/alerting-squad,false,false,false,true alertingInsights,experimental,@grafana/alerting-squad,false,false,false,true
externalCorePlugins,experimental,@grafana/plugins-platform-backend,false,false,false,false externalCorePlugins,experimental,@grafana/plugins-platform-backend,false,false,false,false
pluginsAPIMetrics,experimental,@grafana/plugins-platform-backend,false,false,false,true pluginsAPIMetrics,experimental,@grafana/plugins-platform-backend,false,false,false,true
httpSLOLevels,experimental,@grafana/hosted-grafana-team,false,false,true,false

1 Name Stage Owner requiresDevMode RequiresLicense RequiresRestart FrontendOnly
110 alertingInsights experimental @grafana/alerting-squad false false false true
111 externalCorePlugins experimental @grafana/plugins-platform-backend false false false false
112 pluginsAPIMetrics experimental @grafana/plugins-platform-backend false false false true
113 httpSLOLevels experimental @grafana/hosted-grafana-team false false true false

View File

@ -450,4 +450,8 @@ const (
// FlagPluginsAPIMetrics // FlagPluginsAPIMetrics
// Sends metrics of public grafana packages usage by plugins // Sends metrics of public grafana packages usage by plugins
FlagPluginsAPIMetrics = "pluginsAPIMetrics" FlagPluginsAPIMetrics = "pluginsAPIMetrics"
// FlagHttpSLOLevels
// Adds SLO level to http request metrics
FlagHttpSLOLevels = "httpSLOLevels"
) )