Skip to content

Commit cd7b4f9

Browse files
Merge pull request #36 from simonpasquier/rework-status-api
Add `--metrics.status.endpoint` argument
2 parents d7c2073 + ade50c5 commit cd7b4f9

2 files changed

Lines changed: 53 additions & 34 deletions

File tree

api/metrics/v1/http.go

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ type handlerConfiguration struct {
5757
statusMiddlewares []func(http.Handler) http.Handler
5858
writeMiddlewares []func(http.Handler) http.Handler
5959
alertmanagerMiddleware alertmanagerMiddleware
60-
enableStatusEndpoints bool
6160
}
6261

6362
// HandlerOption modifies the handler's configuration.
@@ -165,13 +164,6 @@ func WithGlobalMiddleware(m ...func(http.Handler) http.Handler) HandlerOption {
165164
}
166165
}
167166

168-
// WithStatusEndpoints enables/disables the /status/* endpoints.
169-
func WithStatusEndpoints(enabled bool) HandlerOption {
170-
return func(h *handlerConfiguration) {
171-
h.enableStatusEndpoints = enabled
172-
}
173-
}
174-
175167
type handlerInstrumenter interface {
176168
NewHandler(labels prometheus.Labels, handler http.Handler) http.HandlerFunc
177169
}
@@ -187,6 +179,7 @@ type Endpoints struct {
187179
WriteEndpoint *url.URL
188180
RulesEndpoint *url.URL
189181
AlertmanagerEndpoint *url.URL
182+
StatusEndpoint *url.URL
190183
}
191184

192185
// NewHandler creates the new metrics v1 handler.
@@ -352,25 +345,6 @@ func NewHandler(endpoints Endpoints, tlsOptions *tls.UpstreamOptions, opts ...Ha
352345
)
353346
})
354347

355-
if c.enableStatusEndpoints {
356-
r.Group(func(r chi.Router) {
357-
r.Use(func(handler http.Handler) http.Handler {
358-
return server.InjectLabelsCtx(
359-
prometheus.Labels{"group": "metricsv1", "handler": "status"},
360-
handler,
361-
)
362-
})
363-
r.Use(c.statusMiddlewares...)
364-
r.Use(server.StripTenantPrefix("/api/metrics/v1"))
365-
r.Handle(TSDBStatusRoute,
366-
otelhttp.WithRouteTag(
367-
c.spanRoutePrefix+TSDBStatusRoute,
368-
proxyRead,
369-
),
370-
)
371-
})
372-
}
373-
374348
var uiProxy http.Handler
375349
{
376350
middlewares := proxy.Middlewares(
@@ -491,6 +465,40 @@ func NewHandler(endpoints Endpoints, tlsOptions *tls.UpstreamOptions, opts ...Ha
491465
})
492466
}
493467

468+
if endpoints.StatusEndpoint != nil {
469+
middlewares := proxy.Middlewares(
470+
proxy.MiddlewareSetUpstream(endpoints.ReadEndpoint),
471+
proxy.MiddlewareSetPrefixHeader(),
472+
proxy.MiddlewareLogger(c.logger),
473+
proxy.MiddlewareMetrics(c.registry, prometheus.Labels{"proxy": "metricsv1-ui"}),
474+
)
475+
476+
t := http.DefaultTransport.(*http.Transport)
477+
t.TLSClientConfig = tlsOptions.NewClientConfig()
478+
479+
statusProxy := &httputil.ReverseProxy{
480+
Director: middlewares,
481+
Transport: otelhttp.NewTransport(http.DefaultTransport),
482+
}
483+
484+
r.Group(func(r chi.Router) {
485+
r.Use(func(handler http.Handler) http.Handler {
486+
return server.InjectLabelsCtx(
487+
prometheus.Labels{"group": "metricsv1", "handler": "status"},
488+
handler,
489+
)
490+
})
491+
r.Use(c.statusMiddlewares...)
492+
r.Use(server.StripTenantPrefix("/api/metrics/v1"))
493+
r.Handle(TSDBStatusRoute,
494+
otelhttp.WithRouteTag(
495+
c.spanRoutePrefix+TSDBStatusRoute,
496+
statusProxy,
497+
),
498+
)
499+
})
500+
}
501+
494502
if endpoints.AlertmanagerEndpoint != nil {
495503
var proxyAlertmanager http.Handler
496504
{

main.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,16 @@ type metricsConfig struct {
146146
writeEndpoint *url.URL
147147
rulesEndpoint *url.URL
148148
alertmanagerEndpoint *url.URL
149+
statusEndpoint *url.URL
149150
upstreamWriteTimeout time.Duration
150151
upstreamCAFile string
151152
upstreamCertFile string
152153
upstreamKeyFile string
153154
tenantHeader string
154155
tenantLabel string
155156
// enable metrics if at least one {read|write}Endpoint} is provided.
156-
enabled bool
157-
enableCertWatcher bool
158-
enableStatusEndpoints bool
157+
enabled bool
158+
enableCertWatcher bool
159159
}
160160

161161
type logsConfig struct {
@@ -646,6 +646,7 @@ func main() {
646646
WriteEndpoint: cfg.metrics.writeEndpoint,
647647
RulesEndpoint: cfg.metrics.rulesEndpoint,
648648
AlertmanagerEndpoint: cfg.metrics.alertmanagerEndpoint,
649+
StatusEndpoint: cfg.metrics.statusEndpoint,
649650
}
650651

651652
rateLimitMiddleware := ratelimit.WithLocalRateLimiter(rateLimits...)
@@ -734,7 +735,6 @@ func main() {
734735
}
735736

736737
const matchParamName = "match[]"
737-
level.Info(logger).Log("msg", "status API", "enabled", cfg.metrics.enableStatusEndpoints)
738738
r.Mount("/api/metrics/v1/{tenant}", metricsv1.NewHandler(
739739
eps,
740740
metricsUpstreamClientOptions,
@@ -751,7 +751,6 @@ func main() {
751751
metricsv1.WithReadMiddleware(authorization.WithAuthorizers(authorizers, rbac.Read, "metrics")),
752752
metricsv1.WithReadMiddleware(metricsv1.WithEnforceTenancyOnQuery(cfg.metrics.tenantLabel, matchParamName)),
753753
metricsv1.WithReadMiddleware(metricsv1.WithEnforceAuthorizationLabels()),
754-
metricsv1.WithStatusEndpoints(cfg.metrics.enableStatusEndpoints),
755754
metricsv1.WithStatusMiddleware(authorization.WithAuthorizers(authorizers, rbac.Read, "metrics")),
756755
metricsv1.WithUIMiddleware(authorization.WithAuthorizers(authorizers, rbac.Read, "metrics")),
757756
metricsv1.WithAlertmanagerAlertsReadMiddleware(
@@ -1113,6 +1112,7 @@ func parseFlags() (config, error) {
11131112
rawMetricsWriteEndpoint string
11141113
rawMetricsRulesEndpoint string
11151114
rawMetricsAlertmanagerEndpoint string
1115+
rawMetricsStatusEndpoint string
11161116
rawLogsReadEndpoint string
11171117
rawLogsRulesEndpoint string
11181118
rawLogsTailEndpoint string
@@ -1191,14 +1191,14 @@ func parseFlags() (config, error) {
11911191
"Comma-separated list of stream selectors that should be extracted from queries and sent to OPA during authorization.")
11921192
flag.StringVar(&rawMetricsReadEndpoint, "metrics.read.endpoint", "",
11931193
"The endpoint against which to send read requests for metrics. It used as a fallback to 'query.endpoint' and 'query-range.endpoint'.")
1194-
flag.BoolVar(&cfg.metrics.enableStatusEndpoints, "metrics.read.enable-status-endpoints", false,
1195-
"Enable the metric status endpoints")
11961194
flag.StringVar(&rawMetricsWriteEndpoint, "metrics.write.endpoint", "",
11971195
"The endpoint against which to make write requests for metrics.")
11981196
flag.StringVar(&rawMetricsRulesEndpoint, "metrics.rules.endpoint", "",
11991197
"The endpoint against which to make get requests for listing recording/alerting rules and put requests for creating/updating recording/alerting rules.")
12001198
flag.StringVar(&rawMetricsAlertmanagerEndpoint, "metrics.alertmanager.endpoint", "",
12011199
"The endpoint against which to make requests for alerts and silences")
1200+
flag.StringVar(&rawMetricsStatusEndpoint, "metrics.status.endpoint", "",
1201+
"The endpoint against which to make requests for status information about metrics (e.g. '/api/v1/status/tsdb').")
12021202
flag.DurationVar(&cfg.metrics.upstreamWriteTimeout, "metrics.write-timeout", metricsMiddlewareTimeout,
12031203
"The HTTP write timeout for proxied requests to the metrics endpoint.")
12041204
flag.StringVar(&cfg.metrics.upstreamCAFile, "metrics.tls.ca-file", "",
@@ -1345,6 +1345,17 @@ func parseFlags() (config, error) {
13451345
cfg.metrics.alertmanagerEndpoint = alertmanagerEndpoint
13461346
}
13471347

1348+
if rawMetricsStatusEndpoint != "" {
1349+
cfg.metrics.enabled = true
1350+
1351+
statusEndpoint, err := url.ParseRequestURI(rawMetricsStatusEndpoint)
1352+
if err != nil {
1353+
return cfg, fmt.Errorf("--metrics.status.endpoint %q is invalid: %w", rawMetricsStatusEndpoint, err)
1354+
}
1355+
1356+
cfg.metrics.statusEndpoint = statusEndpoint
1357+
}
1358+
13481359
if rawLogsReadEndpoint != "" {
13491360
cfg.logs.enabled = true
13501361

0 commit comments

Comments
 (0)