# Logging Field Standardization ADR: Dynamic Runtime Linting
## Context
GitLab is implementing a [logging field standardization initiative](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/observability_field_standardisation/) to ensure logs are queryable and actionable across all systems. We need a mechanism to identify and track deprecated or non-standard logging fields across multiple codebases.
### Requirements
The solution must:
1. Detect deprecated fields at the point of emission (runtime).
1. Provide immediate feedback to developers (shift-left).
1. Prevent new violations without blocking existing work.
1. Support gradual migration from deprecated to standard fields.
1. Never affect production performance.
1. Provide clear guidance on standard field replacements.
### The problem with static analysis
We initially considered RuboCop (static linting), but this approach is inadequate due to Ruby's [dynamic and complex field construction](https://gitlab.com/gitlab-org/gitlab/-/blob/cfd4fb97968d1f7d30f39f89740e414e9437063a/lib/bulk_imports/logger.rb#L46).
Static analysis can't reliably detect:
- Fields merged from hash arguments.
- Dynamically constructed field names.
- Fields passed through multiple abstraction layers.
- Conditional field inclusion based on runtime state.
## Decision
Implement dynamic runtime linting to validate logging fields as they're emitted during development and testing, rather than using static analysis.
The validator will:
- Intercept logging calls at runtime to detect deprecated fields.
- Compare detected violations against a frozen baseline of known violations.
- Raise an error on new violations while ignoring tracked existing tracked violations.
- Provide immediate feedback to developers during local development.
- Never affect production performance.
## Consequences
### Benefits
-**Shift-left feedback**: Developers discover violations during local development, not in code review.
-**Comprehensive detection**: Captures violations from all code execution paths (tests, Rake tasks, console, development environments).
-**Regression prevention**: CI fails on new violations, preventing deprecated fields from reappearing.
-**Clear guidance**: Exact replacement field suggested for each violation.
-**Zero production impact**: Validation only runs in development and test environments.
### Trade-offs
-**Execution path dependency**: Only detects violations in code paths that execute during the process.
-**Runtime overhead**: Adds interception to all non-production processes.
-**At-exit reporting**: Violations not visible until process completes.
-**Baseline maintenance**: YAML files require updates when violations are fixed or added.
-**Learning curve**: Developers must understand baseline management.
-**File-level scoping**: Multiple violations in the same file are tracked together, making partial fixes during test runs challenging.
### Risks and mitigations
| Risk | Mitigation |
|------|------------|
| Limited code path coverage misses violations | Use Kibana to identify fields in production logs, run comprehensive test suites, use development server testing |
| Baseline drift across branches | Clear documentation, automated baseline regeneration support |
| At-exit reporting missed if process crashes | Violations still prevented in CI where processes complete successfully |
## Alternatives
### Alternative 1: Static analysis with RuboCop
Use custom RuboCop cops to detect deprecated field usage.
Rejected because:
- Can't handle fields merged from hash variables.
- Would produce many false negatives.
- Complex pattern matching still misses dynamic cases.
- Poor developer experience with unclear violations.
### Alternative 2: Manual tracking
Track violations in spreadsheets or GitLab issues.
Rejected because:
- No automated enforcement or detection.
- Manual process becomes stale quickly.
- No shift-left feedback to developers.
- Can't prevent regressions.
### Alternative 3: Grep-based CI checks
Search source code for deprecated field strings in CI.
Rejected because:
- High false positive rate (matches in comments, strings, tests).
- Can't distinguish field usage from definitions.
- No stable tracking across refactoring.
- Poor user experience with unclear error messages.
### Alternative 4: Production log analysis only
Rely solely on Kibana analysis to find deprecated fields.
Rejected because:
- No prevention, only reactive detection.
- Violations already in production when discovered.
- No developer feedback during development.
- Difficult to trace back to specific code locations.
-[Observability Field Standardisation](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/observability_field_standardisation/)