diff --git a/CHANGELOG.md b/CHANGELOG.md index 16148eeae6..be8305e728 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## master / unreleased +* [ENHANCEMENT] Query Frontend: Log `X-Grafana-User` header in query stats, slow query, and query request logs when Grafana's `send_user_header` is enabled. #7797 * [FEATURE] Engine: Add `-querier.selector-batch-size` and `-ruler.selector-batch-size` flags to configure series batching in the Thanos promQL engine. 0 disables batching. #7763 * [CHANGE] Querier: Make query time range configurations per-tenant: `query_ingesters_within`, `query_store_after`, and `shuffle_sharding_ingesters_lookback_period`. Uses `model.Duration` instead of `time.Duration` to support serialization but has minimum unit of 1ms (nanoseconds/microseconds not supported). #7160 * [CHANGE] Cache: Setting `-blocks-storage.bucket-store.metadata-cache.bucket-index-content-ttl` to 0 will disable the bucket-index cache. #7446 diff --git a/pkg/frontend/transport/handler.go b/pkg/frontend/transport/handler.go index 432f63c2cd..623c8ae507 100644 --- a/pkg/frontend/transport/handler.go +++ b/pkg/frontend/transport/handler.go @@ -372,13 +372,18 @@ func (f *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func formatGrafanaStatsFields(r *http.Request) []any { // NOTE(GiedriusS): see https://github.com/grafana/grafana/pull/60301 for more info. - fields := make([]any, 0, 4) + fields := make([]any, 0, 6) if dashboardUID := r.Header.Get("X-Dashboard-Uid"); dashboardUID != "" { fields = append(fields, "X-Dashboard-Uid", dashboardUID) } if panelID := r.Header.Get("X-Panel-Id"); panelID != "" { fields = append(fields, "X-Panel-Id", panelID) } + // X-Grafana-User is sent by Grafana when [dataproxy] send_user_header is enabled. + // See https://github.com/grafana/grafana/pull/15998 for more info. + if grafanaUser := r.Header.Get("X-Grafana-User"); grafanaUser != "" { + fields = append(fields, "X-Grafana-User", grafanaUser) + } return fields } diff --git a/pkg/frontend/transport/handler_test.go b/pkg/frontend/transport/handler_test.go index 71dda04280..2a66a7c7b0 100644 --- a/pkg/frontend/transport/handler_test.go +++ b/pkg/frontend/transport/handler_test.go @@ -519,6 +519,11 @@ func TestReportQueryStatsFormat(t *testing.T) { expectedLog: `level=info msg="query stats" component=query-frontend method=GET path=/prometheus/api/v1/query response_time=1s query_wall_time_seconds=0 response_series_count=0 fetched_series_count=0 fetched_chunks_count=0 fetched_samples_count=0 fetched_chunks_bytes=0 fetched_data_bytes=0 split_queries=0 status_code=200 response_size=1000 samples_scanned=0 user_agent=Grafana`, source: requestmeta.SourceAPI, }, + "should include grafana user header": { + header: http.Header{"X-Grafana-User": []string{"admin"}}, + expectedLog: `level=info msg="query stats" component=query-frontend method=GET path=/prometheus/api/v1/query response_time=1s query_wall_time_seconds=0 response_series_count=0 fetched_series_count=0 fetched_chunks_count=0 fetched_samples_count=0 fetched_chunks_bytes=0 fetched_data_bytes=0 split_queries=0 status_code=200 response_size=1000 samples_scanned=0 X-Grafana-User=admin`, + source: requestmeta.SourceAPI, + }, "should include engine type": { header: http.Header{http.CanonicalHeaderKey(engine.TypeHeader): []string{string(engine.Thanos)}}, expectedLog: `level=info msg="query stats" component=query-frontend method=GET path=/prometheus/api/v1/query response_time=1s query_wall_time_seconds=0 response_series_count=0 fetched_series_count=0 fetched_chunks_count=0 fetched_samples_count=0 fetched_chunks_bytes=0 fetched_data_bytes=0 split_queries=0 status_code=200 response_size=1000 samples_scanned=0 engine_type=thanos`, @@ -634,6 +639,15 @@ func TestReportSlowQueryFormat(t *testing.T) { }, expectedLog: `level=info msg="slow query detected" method=GET host=localhost:8080 path=/prometheus/api/v1/query source=api time_taken_ms=1000 X-Dashboard-Uid=dashboard-1 X-Panel-Id=panel-1`, }, + "should include grafana user header": { + source: requestmeta.SourceAPI, + header: http.Header{ + "X-Dashboard-Uid": []string{"dashboard-1"}, + "X-Panel-Id": []string{"panel-1"}, + "X-Grafana-User": []string{"admin"}, + }, + expectedLog: `level=info msg="slow query detected" method=GET host=localhost:8080 path=/prometheus/api/v1/query source=api time_taken_ms=1000 X-Dashboard-Uid=dashboard-1 X-Panel-Id=panel-1 X-Grafana-User=admin`, + }, "should include user agent, engine type and block store type headers": { source: requestmeta.SourceAPI, header: http.Header{