feat(processors): configurable root fields via ECSCTX_ROOT_FIELDS#14
Conversation
A consuming service can promote additional keys to root (instead of extra.*) without ecsctx hardcoding its domain schema. Mirrors the masking-exemption pattern: configure_root_fields() > Django ECSCTX_ROOT_FIELDS setting (lazy bridge at log time) > env var (CSV). ROOT_ALLOWLIST is only ever extended, never reduced.
|
@claude review |
|
Claude finished @jab3z's task in 2m 35s —— View job Code Review
|

What
Lets a consuming service promote additional log keys to root level (instead of
extra.*) without ecsctx hardcoding the service's domain schema.Came out of the deltabulk log verification for ottuco/core_backend#145:
customer.*lands underextra.customerbecauseROOT_ALLOWLISTis a hardcoded frozenset. That placement is fine for now, but the consuming service should own that decision.How
Mirrors the proven
ECSCTX_MASK_EXEMPT_PATHSthree-level pattern exactly (precedence: explicit call > Django setting > env var):configure_root_fields(extra_fields=[...])/configure_root_fields_from_env()inprocessors.py;reshape_log_eventresolvesROOT_ALLOWLIST | customlazily_auto_configure_root_fields()reads theECSCTX_ROOT_FIELDSsetting at log time fromcontextvars_injector(not insetup_logging, per 97e42cf)ECSCTX_ROOT_FIELDSenv var (CSV) as framework-agnostic fallbackROOT_ALLOWLISTis only ever extended, never reducedTests
TestRootFieldsConfig(core: default, configured, env, explicit-beats-env)TestRootFieldsSettingsBridge(Django: setting via auto-configure + via first processor call, absent-setting noop, explicit-beats-setting, settings-not-ready retry)Release
No version bump in this PR — dispatch the Release workflow with
patchafter merge → v0.5.5 on PyPI. ottuco/core_backend will then bump toecsctx[django]>=0.5.5.