mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 11:20:27 -06:00
3c8cea0764
Signed-off-by: bergquist <carl.bergquist@gmail.com>
135 lines
3.5 KiB
Go
135 lines
3.5 KiB
Go
package requestmeta
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/grafana/grafana/pkg/web"
|
|
)
|
|
|
|
const (
|
|
TeamAlerting = "alerting"
|
|
TeamAuth = "auth"
|
|
TeamBackend = "backend"
|
|
)
|
|
|
|
type StatusSource string
|
|
|
|
const (
|
|
StatusSourceServer StatusSource = "server"
|
|
StatusSourceDownstream StatusSource = "downstream"
|
|
)
|
|
|
|
type RequestMetaData struct {
|
|
Team string
|
|
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{}
|
|
|
|
// SetupRequestMetadata injects defaul request metadata values
|
|
// on the request context.
|
|
func SetupRequestMetadata() web.Middleware {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
rmd := defaultRequestMetadata()
|
|
ctx := SetRequestMetaData(r.Context(), rmd)
|
|
*r = *r.WithContext(ctx)
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|
|
|
|
// GetRequestMetaData returns the request metadata for the context.
|
|
// if request metadata is missing it will return the default values.
|
|
func GetRequestMetaData(ctx context.Context) *RequestMetaData {
|
|
val := ctx.Value(requestMetaDataContextKey)
|
|
|
|
value, ok := val.(*RequestMetaData)
|
|
if ok {
|
|
return value
|
|
}
|
|
|
|
rmd := defaultRequestMetadata()
|
|
return &rmd
|
|
}
|
|
|
|
// SetRequestMetaData sets the request metadata for the context.
|
|
func SetRequestMetaData(ctx context.Context, rmd RequestMetaData) context.Context {
|
|
return context.WithValue(ctx, requestMetaDataContextKey, &rmd)
|
|
}
|
|
|
|
// SetOwner returns an `web.Handler` that sets the team name for an request.
|
|
func SetOwner(team string) web.Handler {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
v := GetRequestMetaData(r.Context())
|
|
v.Team = team
|
|
}
|
|
}
|
|
|
|
// WithDownstreamStatusSource sets the StatusSource field of the [RequestMetaData] for the
|
|
// context to [StatusSourceDownstream].
|
|
func WithDownstreamStatusSource(ctx context.Context) {
|
|
v := GetRequestMetaData(ctx)
|
|
v.StatusSource = StatusSourceDownstream
|
|
}
|
|
|
|
// WithStatusSource sets the StatusSource field of the [RequestMetaData] for the
|
|
// context based on the provided statusCode.
|
|
// If statusCode >= 500 then [StatusSourceDownstream].
|
|
// If statusCode < 500 then [StatusSourceServer].
|
|
func WithStatusSource(ctx context.Context, statusCode int) {
|
|
v := GetRequestMetaData(ctx)
|
|
|
|
if statusCode >= 500 {
|
|
v.StatusSource = StatusSourceDownstream
|
|
return
|
|
}
|
|
|
|
v.StatusSource = StatusSourceServer
|
|
}
|
|
|
|
func defaultRequestMetadata() RequestMetaData {
|
|
return RequestMetaData{
|
|
Team: TeamBackend,
|
|
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
|
|
}
|
|
}
|