From e6faf72b77a9a0c4a441768be19185c29d2f452b Mon Sep 17 00:00:00 2001 From: "mdhumair.kankudti" Date: Wed, 2 Sep 2026 17:37:17 +0530 Subject: [PATCH] Confirm OTLP observability config for load runs Signed-off-by: mdhumair.kankudti --- esignet-service/data/deployment.yaml | 12 +++++ esignet-service/internal/config/app.go | 2 +- esignet-service/internal/config/app_test.go | 49 +++++++++++++++++++++ performance-test/README.md | 23 ++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/esignet-service/data/deployment.yaml b/esignet-service/data/deployment.yaml index 752e8ab76..74cc0980b 100644 --- a/esignet-service/data/deployment.yaml +++ b/esignet-service/data/deployment.yaml @@ -114,6 +114,18 @@ gate_client: login_path: /signin error_path: /error +# Toggles the ThunderID observability event pipeline. +# Override with MOSIP_ESIGNET_OBSERVABILITY_ENABLED. +# NOTE: as of this engine version the embedded engine does not read this +# setting (it never reaches the engine's runtime config), and the OpenTelemetry +# SDK and OTLP exporter are not linked into the esignet binary at all, so no +# traces are exported regardless of this value. Kept explicit so the toggle +# already exists if the engine starts honoring it, and so load runs have a +# documented place to turn the pipeline off. See performance-test/README.md. +# An omitted block is indistinguishable from `false`, so keep this explicit. +observability: + enabled: true + jwt: preferred_key_id: "${MOSIP_ESIGNET_SIGNING_KEY_REF_ID}" validity_period: 120 # override via MOSIP_ESIGNET_JWT_VALIDITY_PERIOD diff --git a/esignet-service/internal/config/app.go b/esignet-service/internal/config/app.go index cec39f85a..f2a96123a 100644 --- a/esignet-service/internal/config/app.go +++ b/esignet-service/internal/config/app.go @@ -339,7 +339,7 @@ func applyDefaults(cfg *AppConfig) { cfg.JWT.ValidityPeriod = int64(envIntOrConfigOrDefault("MOSIP_ESIGNET_JWT_VALIDITY_PERIOD", int(cfg.JWT.ValidityPeriod), 120)) cfg.JWT.Leeway = int64(envIntOrConfigOrDefault("MOSIP_ESIGNET_JWT_LEEWAY", int(cfg.JWT.Leeway), 10)) - cfg.Observability.Enabled = true + cfg.Observability.Enabled = envBoolOrConfig("MOSIP_ESIGNET_OBSERVABILITY_ENABLED", cfg.Observability.Enabled) // GateClient env overrides (MOSIP_ESIGNET_OIDC_UI_*) are applied afterwards // by ApplyEnvOverrides, so only the yaml-value/compiled-default fallback is diff --git a/esignet-service/internal/config/app_test.go b/esignet-service/internal/config/app_test.go index 2bdf9e05a..6b8ee4dcc 100644 --- a/esignet-service/internal/config/app_test.go +++ b/esignet-service/internal/config/app_test.go @@ -63,6 +63,7 @@ func (ts *AppConfigTestSuite) SetupTest() { "MOSIP_ESIGNET_JWT_VALIDITY_PERIOD", "MOSIP_ESIGNET_JWT_LEEWAY", "MOSIP_ESIGNET_DPOP_LEEWAY", + "MOSIP_ESIGNET_OBSERVABILITY_ENABLED", } { t.Setenv(key, "") } @@ -539,6 +540,54 @@ func (ts *AppConfigTestSuite) TestApplyDefaultsAllowedOriginRegex() { }) } +// TestApplyDefaultsObservabilityEnabled covers the observability toggle, which +// applyDefaults previously hard-set to true and so silently discarded whatever +// deployment.yaml asked for. Note that the embedded engine does not currently +// read this field (and no OTel SDK/OTLP exporter is linked into the binary), so +// these cases pin the config resolution rather than any tracing behavior — see +// performance-test/README.md. +func (ts *AppConfigTestSuite) TestApplyDefaultsObservabilityEnabled() { + t := ts.T() + + t.Run("yaml false is respected", func(t *testing.T) { + cfg := &AppConfig{} + cfg.Observability.Enabled = false + applyDefaults(cfg) + require.False(t, cfg.Observability.Enabled) + }) + + t.Run("yaml true is respected", func(t *testing.T) { + cfg := &AppConfig{} + cfg.Observability.Enabled = true + applyDefaults(cfg) + require.True(t, cfg.Observability.Enabled) + }) + + t.Run("env var disables when yaml enables", func(t *testing.T) { + t.Setenv("MOSIP_ESIGNET_OBSERVABILITY_ENABLED", "false") + cfg := &AppConfig{} + cfg.Observability.Enabled = true + applyDefaults(cfg) + require.False(t, cfg.Observability.Enabled) + }) + + t.Run("env var enables when yaml disables", func(t *testing.T) { + t.Setenv("MOSIP_ESIGNET_OBSERVABILITY_ENABLED", "true") + cfg := &AppConfig{} + cfg.Observability.Enabled = false + applyDefaults(cfg) + require.True(t, cfg.Observability.Enabled) + }) + + t.Run("unrecognized env value keeps the yaml value", func(t *testing.T) { + t.Setenv("MOSIP_ESIGNET_OBSERVABILITY_ENABLED", "garbage") + cfg := &AppConfig{} + cfg.Observability.Enabled = true + applyDefaults(cfg) + require.True(t, cfg.Observability.Enabled) + }) +} + func (ts *AppConfigTestSuite) TestApplyDefaultsCacheType() { t := ts.T() t.Run("defaults to inmemory", func(_ *testing.T) { diff --git a/performance-test/README.md b/performance-test/README.md index d787d35a8..f8b62e343 100644 --- a/performance-test/README.md +++ b/performance-test/README.md @@ -64,6 +64,29 @@ This module describes how to conduct load test of the eSignet OIDC(FAPI2.0) flow * Note: as shipped, this script has only "S01 OTP Authentication" and "S02 Biometric Authentication" are enabled by default; "A00", "A01" and "A02" are disabled. Enable each Thread Group deliberately per the validation steps above rather than assuming all groups are active. +# Observability / tracing overhead + +**No observability action is required before a load run. eSignet Go exports no OpenTelemetry traces, so tracing contributes zero overhead and no OTLP collector needs to be reachable from the perf environment.** + +This was verified for [issue #2497](https://github.com/mosip/esignet/issues/2497). Three independent reasons, any one of which is sufficient: + +1. **The tracing code is not in the binary.** Neither the OTel SDK (`go.opentelemetry.io/otel/sdk/trace`) nor the OTLP gRPC exporter (`.../exporters/otlp/otlptrace/otlptracegrpc`) is linked into `cmd/esignet`. Only OTel *API* packages are present, pulled in transitively by `go-redis`. With no SDK registered, `otel.GetTracerProvider()` returns the noop provider, so no spans are created and nothing is exported. +2. **Config never reaches the tracing subscriber.** The embedded ThunderID engine builds its runtime config with only the gate-client, crypto, and attribute-cache sections; the `Observability` section is never populated, so the OTel subscriber's enable-check always reads the zero value. +3. **The observability service is never constructed.** The engine has no call site that instantiates it, and the `WithObservabilityConfig(...)` option writes a field nothing reads. + +eSignet's audit trail does not depend on any of the above: it runs through its own observability *provider* (MOSIP audit-manager, or a logging no-op for the `mock`/`sunbird` providers), which is unaffected by these settings. + +Re-verify at any time, from `esignet-service/`: + +```bash +go list -deps ./cmd/esignet | grep -E 'otel/sdk|otlptracegrpc' || echo "confirmed: no OTel SDK/OTLP exporter linked" +``` + +**Chosen configuration.** `data/deployment.yaml` sets `observability.enabled: true` explicitly, overridable with `MOSIP_ESIGNET_OBSERVABILITY_ENABLED`. The value has no effect today; it is kept explicit so the toggle already exists if the engine starts honoring this field, and so load runs have a documented place to turn the pipeline off. Because an omitted YAML block cannot be distinguished from `false`, leave the key in place rather than deleting it. + +**Regression risk.** This conclusion expires if a future ThunderID bump both populates the engine's `Observability` runtime config and links the OTel SDK. If the `go list` check above ever prints matching packages, re-evaluate #2497: at that point a reachable collector and a `sample_rate` of `<= 0.01` (an unset or `0` rate is coerced to `1.0`, i.e. trace *everything*) become necessary, and the safest load-run setting is `observability.enabled: false`. + + # Script execution steps: 01. A00 Auth Token Generation (Preparation) - In this thread group we are creating the authorization token - Using User Id which will be saved to a file within user defined path - "runTimeFilePath". The authorization token has expiration time which is controlled by MOSIP settings. Ensure the tokens remain valid throughout the duration of the test execution.