Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions esignet-service/data/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion esignet-service/internal/config/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 49 additions & 0 deletions esignet-service/internal/config/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "")
}
Expand Down Expand Up @@ -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) {
Expand Down
23 changes: 23 additions & 0 deletions performance-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading