From 67f50478d95294e723d88460deac97ba69e89c4c Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:41:31 +0200 Subject: [PATCH] Loki: Refactor getting of panel/dashboard title headers as part of decoupling (#106829) * Loki: Refactor getting of panel/dashboard title headers as part of decoupling * Add headers to be passed to api server * Address review comments --- pkg/registry/apis/query/header_utils.go | 30 +++++++++++++------ .../tracing_header_middleware.go | 12 +++++++- pkg/services/query/query.go | 10 ++++--- pkg/tsdb/loki/loki.go | 25 ---------------- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/pkg/registry/apis/query/header_utils.go b/pkg/registry/apis/query/header_utils.go index 1538d8c2a85..97a57f6fe16 100644 --- a/pkg/registry/apis/query/header_utils.go +++ b/pkg/registry/apis/query/header_utils.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/grafana/grafana/pkg/services/ngalert/models" + queryService "github.com/grafana/grafana/pkg/services/query" ) // Set of headers that we want to forward to the datasource api servers. Those are used i.e. for @@ -13,18 +14,29 @@ import ( // The headers related to grafana alerting (x-rule-*), should match the list at // https://github.com/grafana/grafana/blob/f8ae71e4583499dd461ebaed31451966be04220b/pkg/services/pluginsintegration/clientmiddleware/usealertingheaders_middleware.go#L23 // +// The headers related to grafana query should match the list at +// https://github.com/grafana/grafana/blob/f8ae71e4583499dd461ebaed31451966be04220b/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go#L36 +// // The usage of strings.ToLower is because the server would convert `FromAlert` to `Fromalert`. So the make matching // easier, we just match all headers in lower case. var expectedHeaders = map[string]string{ - strings.ToLower(models.FromAlertHeaderName): models.FromAlertHeaderName, - strings.ToLower(models.CacheSkipHeaderName): models.CacheSkipHeaderName, - strings.ToLower("X-Rule-Name"): "X-Rule-Name", - strings.ToLower("X-Rule-Uid"): "X-Rule-Uid", - strings.ToLower("X-Rule-Folder"): "X-Rule-Folder", - strings.ToLower("X-Rule-Source"): "X-Rule-Source", - strings.ToLower("X-Rule-Type"): "X-Rule-Type", - strings.ToLower("X-Rule-Version"): "X-Rule-Version", - strings.ToLower("X-Grafana-Org-Id"): "X-Grafana-Org-Id", + strings.ToLower(models.FromAlertHeaderName): models.FromAlertHeaderName, + strings.ToLower(models.CacheSkipHeaderName): models.CacheSkipHeaderName, + strings.ToLower("X-Rule-Name"): "X-Rule-Name", + strings.ToLower("X-Rule-Uid"): "X-Rule-Uid", + strings.ToLower("X-Rule-Folder"): "X-Rule-Folder", + strings.ToLower("X-Rule-Source"): "X-Rule-Source", + strings.ToLower("X-Rule-Type"): "X-Rule-Type", + strings.ToLower("X-Rule-Version"): "X-Rule-Version", + strings.ToLower("X-Grafana-Org-Id"): "X-Grafana-Org-Id", + strings.ToLower(queryService.HeaderQueryGroupID): queryService.HeaderQueryGroupID, + strings.ToLower(queryService.HeaderPanelID): queryService.HeaderPanelID, + strings.ToLower(queryService.HeaderDashboardUID): queryService.HeaderDashboardUID, + strings.ToLower(queryService.HeaderDatasourceUID): queryService.HeaderDatasourceUID, + strings.ToLower(queryService.HeaderFromExpression): queryService.HeaderFromExpression, + strings.ToLower(queryService.HeaderPanelPluginId): queryService.HeaderPanelPluginId, + strings.ToLower(queryService.HeaderDashboardTitle): queryService.HeaderDashboardTitle, + strings.ToLower(queryService.HeaderPanelTitle): queryService.HeaderPanelTitle, } func ExtractKnownHeaders(header http.Header) map[string]string { diff --git a/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go b/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go index 165c6abc417..ea7237734d8 100644 --- a/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go +++ b/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go @@ -33,7 +33,17 @@ func (m *TracingHeaderMiddleware) applyHeaders(ctx context.Context, req backend. return } - var headersList = []string{query.HeaderQueryGroupID, query.HeaderPanelID, query.HeaderDashboardUID, query.HeaderDatasourceUID, query.HeaderFromExpression, `X-Grafana-Org-Id`, query.HeaderPanelPluginId} + var headersList = []string{ + query.HeaderQueryGroupID, + query.HeaderPanelID, + query.HeaderDashboardUID, + query.HeaderDatasourceUID, + query.HeaderFromExpression, + `X-Grafana-Org-Id`, + query.HeaderPanelPluginId, + query.HeaderDashboardTitle, + query.HeaderPanelTitle, + } for _, headerName := range headersList { gotVal := reqCtx.Req.Header.Get(headerName) diff --git a/pkg/services/query/query.go b/pkg/services/query/query.go index cf436cd1714..43c6505da1d 100644 --- a/pkg/services/query/query.go +++ b/pkg/services/query/query.go @@ -29,10 +29,12 @@ import ( ) const ( - HeaderPluginID = "X-Plugin-Id" // can be used for routing - HeaderDatasourceUID = "X-Datasource-Uid" // can be used for routing/ load balancing - HeaderDashboardUID = "X-Dashboard-Uid" // mainly useful for debugging slow queries - HeaderPanelID = "X-Panel-Id" // mainly useful for debugging slow queries + HeaderPluginID = "X-Plugin-Id" // can be used for routing + HeaderDatasourceUID = "X-Datasource-Uid" // can be used for routing/ load balancing + HeaderDashboardUID = "X-Dashboard-Uid" // mainly useful for debugging slow queries + HeaderPanelID = "X-Panel-Id" // mainly useful for debugging slow queries + HeaderDashboardTitle = "X-Dashboard-Title" // used for identifying the dashboard with heavy query load + HeaderPanelTitle = "X-Panel-Title" // used for identifying the panel with heavy query load HeaderPanelPluginId = "X-Panel-Plugin-Id" HeaderQueryGroupID = "X-Query-Group-Id" // mainly useful for finding related queries with query chunking HeaderFromExpression = "X-Grafana-From-Expr" // used by datasources to identify expression queries diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index c3b56578153..aa0cc4655b0 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -24,7 +24,6 @@ import ( "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/promlib/models" - "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/featuremgmt" ngalertmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery" @@ -56,9 +55,6 @@ var ( stagePrepareRequest = "prepareRequest" stageDatabaseRequest = "databaseRequest" stageParseResponse = "parseResponse" - - dashboardTitleHeader = "X-Dashboard-Title" - panelTitleHeader = "X-Panel-Title" ) type datasourceInfo struct { @@ -184,30 +180,9 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) logsDataplane: isFeatureEnabled(ctx, featuremgmt.FlagLokiLogsDataplane), } - if isFeatureEnabled(ctx, featuremgmt.FlagLokiSendDashboardPanelNames) { - s.applyHeaders(ctx, req) - } - return queryData(ctx, req, dsInfo, responseOpts, s.tracer, logger, isFeatureEnabled(ctx, featuremgmt.FlagLokiRunQueriesInParallel), isFeatureEnabled(ctx, featuremgmt.FlagLokiStructuredMetadata), isFeatureEnabled(ctx, featuremgmt.FlagLogQLScope)) } -func (s *Service) applyHeaders(ctx context.Context, req backend.ForwardHTTPHeaders) { - reqCtx := contexthandler.FromContext(ctx) - if req == nil || reqCtx == nil || reqCtx.Req == nil { - return - } - - var hList = []string{dashboardTitleHeader, panelTitleHeader} - - for _, hName := range hList { - hVal := reqCtx.Req.Header.Get(hName) - if hVal == "" { - continue - } - req.SetHTTPHeader(hName, hVal) - } -} - func queryData(ctx context.Context, req *backend.QueryDataRequest, dsInfo *datasourceInfo, responseOpts ResponseOpts, tracer tracing.Tracer, plog log.Logger, runInParallel bool, requestStructuredMetadata, logQLScopes bool) (*backend.QueryDataResponse, error) { result := backend.NewQueryDataResponse()