From 1c78223d9bfbd92397b227da24d333c2ddf5ed5d Mon Sep 17 00:00:00 2001 From: Erwin Kroon <123574+ekroon@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:33:51 +0100 Subject: [PATCH] router: add enable_art toggle for ART --- router/core/graph_server.go | 1 + router/core/graphql_prehandler.go | 7 +++++++ router/core/router.go | 8 ++++++++ router/core/router_config.go | 2 ++ router/core/supervisor_instance.go | 1 + router/pkg/config/config.go | 1 + router/pkg/config/config.schema.json | 5 +++++ router/pkg/config/testdata/config_defaults.json | 1 + router/pkg/config/testdata/config_full.json | 1 + 9 files changed, 27 insertions(+) diff --git a/router/core/graph_server.go b/router/core/graph_server.go index 325ec74c25..191836f97b 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -1510,6 +1510,7 @@ func (s *graphServer) buildGraphMux( RouterPublicKey: s.publicKey, EnableRequestTracing: s.engineExecutionConfiguration.EnableRequestTracing, DevelopmentMode: s.developmentMode, + EnableArt: s.enableArt, TracerProvider: s.tracerProvider, FlushTelemetryAfterResponse: s.awsLambda, TraceExportVariables: s.traceConfig.ExportGraphQLVariables.Enabled, diff --git a/router/core/graphql_prehandler.go b/router/core/graphql_prehandler.go index ee9eb10fc5..ead6eadc46 100644 --- a/router/core/graphql_prehandler.go +++ b/router/core/graphql_prehandler.go @@ -57,6 +57,7 @@ type PreHandlerOptions struct { FileUploadEnabled bool TraceExportVariables bool DevelopmentMode bool + EnableArt bool EnableRequestTracing bool AlwaysIncludeQueryPlan bool AlwaysSkipLoader bool @@ -88,6 +89,7 @@ type PreHandler struct { operationBlocker *OperationBlocker headerPropagation *HeaderPropagation developmentMode bool + enableArt bool alwaysIncludeQueryPlan bool alwaysSkipLoader bool queryPlansEnabled bool // queryPlansEnabled is a flag to enable query plans output in the extensions @@ -148,6 +150,7 @@ func NewPreHandler(opts *PreHandlerOptions) *PreHandler { operationBlocker: opts.OperationBlocker, routerPublicKey: opts.RouterPublicKey, developmentMode: opts.DevelopmentMode, + enableArt: opts.EnableArt, enableRequestTracing: opts.EnableRequestTracing, flushTelemetryAfterResponse: opts.FlushTelemetryAfterResponse, tracerProvider: opts.TracerProvider, @@ -1258,6 +1261,10 @@ func (h *PreHandler) internalParseRequestOptions(r *http.Request, clientInfo *Cl if h.developmentMode { return h.parseRequestExecutionOptions(r), h.parseRequestTraceOptions(r), nil } + // enable_art allows ART without dev_mode or a controlplane token + if h.enableArt { + return h.parseRequestExecutionOptions(r), h.parseRequestTraceOptions(r), nil + } // If the client has a valid request token, and we have a public key from the controlplane if clientInfo.WGRequestToken != "" && h.routerPublicKey != nil { _, err := jwt.Parse(clientInfo.WGRequestToken, func(token *jwt.Token) (interface{}, error) { diff --git a/router/core/router.go b/router/core/router.go index aea15aefde..e3ffdb4f93 100644 --- a/router/core/router.go +++ b/router/core/router.go @@ -2092,6 +2092,14 @@ func WithDevelopmentMode(enabled bool) Option { } } +// WithEnableArt enables Advanced Request Tracing (ART) and query plan headers +// without requiring dev_mode or a Cosmo Cloud JWT token. +func WithEnableArt(enabled bool) Option { + return func(r *Router) { + r.enableArt = enabled + } +} + func WithClusterName(name string) Option { return func(r *Router) { r.clusterName = name diff --git a/router/core/router_config.go b/router/core/router_config.go index bdb126614f..50559f7849 100644 --- a/router/core/router_config.go +++ b/router/core/router_config.go @@ -112,6 +112,7 @@ type Config struct { connectRPCServer *connectrpc.Server processStartTime time.Time developmentMode bool + enableArt bool healthcheck health.Checker accessLogsConfig *AccessLogsConfig // If connecting to localhost inside Docker fails, fallback to the docker internal address for the host @@ -251,6 +252,7 @@ func (c *Config) Usage() map[string]any { usage["access_controller"] = c.accessController != nil usage["retry_options"] = c.retryOptions.Enabled usage["development_mode"] = c.developmentMode + usage["enable_art"] = c.enableArt usage["access_logs"] = c.accessLogsConfig != nil usage["localhost_fallback_inside_docker"] = c.localhostFallbackInsideDocker usage["tls_server"] = c.tlsServerConfig != nil diff --git a/router/core/supervisor_instance.go b/router/core/supervisor_instance.go index 2f9f6fcbfb..7672426bc8 100644 --- a/router/core/supervisor_instance.go +++ b/router/core/supervisor_instance.go @@ -252,6 +252,7 @@ func optionsFromResources(logger *zap.Logger, config *config.Config, reloadPersi }, }), WithDevelopmentMode(config.DevelopmentMode), + WithEnableArt(config.EnableArt), WithTracing(TraceConfigFromTelemetry(&config.Telemetry)), WithMetrics(MetricConfigFromTelemetry(&config.Telemetry)), WithTelemetryAttributes(config.Telemetry.Attributes), diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index 79adc0972d..bee70633c9 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -1143,6 +1143,7 @@ type Config struct { LocalhostFallbackInsideDocker bool `yaml:"localhost_fallback_inside_docker" envDefault:"true" env:"LOCALHOST_FALLBACK_INSIDE_DOCKER"` CDN CDNConfiguration `yaml:"cdn,omitempty"` DevelopmentMode bool `yaml:"dev_mode" envDefault:"false" env:"DEV_MODE"` + EnableArt bool `yaml:"enable_art" envDefault:"false" env:"ENABLE_ART"` Events EventsConfiguration `yaml:"events,omitempty"` CacheWarmup CacheWarmupConfiguration `yaml:"cache_warmup,omitempty"` diff --git a/router/pkg/config/config.schema.json b/router/pkg/config/config.schema.json index 167cb875bd..547ad58482 100644 --- a/router/pkg/config/config.schema.json +++ b/router/pkg/config/config.schema.json @@ -383,6 +383,11 @@ "default": false, "description": "Enable the development mode. The development mode is used to enable the development features like ART (Advanced Request Tracing) and pretty logs." }, + "enable_art": { + "type": "boolean", + "default": false, + "description": "Enable Advanced Request Tracing (ART) and query plan headers without requiring dev_mode or a Cosmo Cloud JWT token." + }, "tls": { "type": "object", "additionalProperties": false, diff --git a/router/pkg/config/testdata/config_defaults.json b/router/pkg/config/testdata/config_defaults.json index 710630ae04..a53cfba718 100644 --- a/router/pkg/config/testdata/config_defaults.json +++ b/router/pkg/config/testdata/config_defaults.json @@ -323,6 +323,7 @@ "CacheSize": 100000000 }, "DevelopmentMode": false, + "EnableArt": false, "Events": { "Providers": { "Nats": null, diff --git a/router/pkg/config/testdata/config_full.json b/router/pkg/config/testdata/config_full.json index fa60cb18e8..5aea54ba13 100644 --- a/router/pkg/config/testdata/config_full.json +++ b/router/pkg/config/testdata/config_full.json @@ -641,6 +641,7 @@ "CacheSize": 100000000 }, "DevelopmentMode": false, + "EnableArt": false, "Events": { "Providers": { "Nats": [