e11y 0.2.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +130 -10
- data/CHANGELOG.md +80 -1
- data/CLAUDE.md +168 -0
- data/CONTRIBUTING.md +640 -0
- data/README.md +165 -701
- data/RELEASE.md +41 -12
- data/Rakefile +249 -57
- data/config/README.md +1 -1
- data/config/loki-local-config.yaml +12 -0
- data/config/otel-collector-config.yaml +44 -0
- data/cucumber.yml +1 -0
- data/docker-compose.yml +18 -2
- data/docs/ADAPTERS.md +76 -0
- data/docs/ADAPTIVE_SAMPLING.md +59 -0
- data/docs/COMPARISON.md +104 -0
- data/docs/CONFIGURATION.md +52 -0
- data/docs/DISTRIBUTED_TRACING.md +44 -0
- data/docs/LIMITATIONS.md +13 -0
- data/docs/METRICS_DSL.md +84 -0
- data/docs/PERFORMANCE.md +60 -0
- data/docs/PII_FILTERING.md +40 -0
- data/docs/PRESETS.md +65 -0
- data/docs/QUICK-START.md +546 -587
- data/docs/RAILS_INTEGRATION.md +79 -0
- data/docs/SCHEMA_VALIDATION.md +63 -0
- data/docs/SLO-PROMQL-ALERTS.md +161 -0
- data/docs/TESTING.md +69 -0
- data/docs/{ADR-001-architecture.md → architecture/ADR-001-architecture.md} +36 -65
- data/docs/{ADR-002-metrics-yabeda.md → architecture/ADR-002-metrics-yabeda.md} +62 -236
- data/docs/architecture/ADR-003-slo-observability.md +1402 -0
- data/docs/{ADR-004-adapter-architecture.md → architecture/ADR-004-adapter-architecture.md} +163 -146
- data/docs/{ADR-005-tracing-context.md → architecture/ADR-005-tracing-context.md} +10 -9
- data/docs/{ADR-006-security-compliance.md → architecture/ADR-006-security-compliance.md} +184 -191
- data/docs/{ADR-007-opentelemetry-integration.md → architecture/ADR-007-opentelemetry-integration.md} +3 -21
- data/docs/{ADR-008-rails-integration.md → architecture/ADR-008-rails-integration.md} +182 -743
- data/docs/{ADR-009-cost-optimization.md → architecture/ADR-009-cost-optimization.md} +45 -54
- data/docs/architecture/ADR-010-developer-experience.md +522 -0
- data/docs/{ADR-011-testing-strategy.md → architecture/ADR-011-testing-strategy.md} +44 -86
- data/docs/{ADR-012-event-evolution.md → architecture/ADR-012-event-evolution.md} +11 -11
- data/docs/{ADR-013-reliability-error-handling.md → architecture/ADR-013-reliability-error-handling.md} +37 -12
- data/docs/{ADR-014-event-driven-slo.md → architecture/ADR-014-event-driven-slo.md} +12 -24
- data/docs/{ADR-015-middleware-order.md → architecture/ADR-015-middleware-order.md} +43 -59
- data/docs/{ADR-016-self-monitoring-slo.md → architecture/ADR-016-self-monitoring-slo.md} +58 -355
- data/docs/{ADR-017-multi-rails-compatibility.md → architecture/ADR-017-multi-rails-compatibility.md} +4 -11
- data/docs/architecture/ADR-018-memory-optimization.md +366 -0
- data/docs/{ADR-INDEX.md → architecture/ADR-INDEX.md} +11 -6
- data/docs/plans/2026-03-20-browser-overlay-svelte.md +281 -0
- data/docs/{00-ICP-AND-TIMELINE.md → prd/00-ICP-AND-TIMELINE.md} +6 -6
- data/docs/{01-SCALE-REQUIREMENTS.md → prd/01-SCALE-REQUIREMENTS.md} +6 -6
- data/docs/prd/01-overview-vision.md +19 -14
- data/docs/use_cases/README.md +22 -23
- data/docs/use_cases/UC-001-request-scoped-debug-buffering.md +50 -44
- data/docs/use_cases/UC-002-business-event-tracking.md +26 -95
- data/docs/use_cases/UC-003-event-metrics.md +66 -0
- data/docs/use_cases/UC-004-zero-config-slo-tracking.md +33 -684
- data/docs/use_cases/UC-005-sentry-integration.md +13 -15
- data/docs/use_cases/UC-006-trace-context-management.md +30 -28
- data/docs/use_cases/UC-007-pii-filtering.md +35 -87
- data/docs/use_cases/UC-008-opentelemetry-integration.md +51 -89
- data/docs/use_cases/UC-009-multi-service-tracing.md +30 -178
- data/docs/use_cases/UC-010-background-job-tracking.md +24 -91
- data/docs/use_cases/UC-011-rate-limiting.md +95 -168
- data/docs/use_cases/UC-012-audit-trail.md +21 -46
- data/docs/use_cases/UC-013-high-cardinality-protection.md +29 -167
- data/docs/use_cases/UC-014-adaptive-sampling.md +2 -2
- data/docs/use_cases/UC-015-cost-optimization.md +46 -99
- data/docs/use_cases/UC-016-rails-logger-migration.md +39 -213
- data/docs/use_cases/UC-017-local-development.md +203 -777
- data/docs/use_cases/UC-018-testing-events.md +3 -3
- data/docs/use_cases/UC-019-retention-based-routing.md +53 -106
- data/docs/use_cases/UC-020-event-versioning.md +8 -9
- data/docs/use_cases/UC-021-error-handling-retry-dlq.md +18 -22
- data/docs/use_cases/UC-022-event-registry.md +15 -21
- data/docs/use_cases/backlog.md +119 -87
- data/e11y.gemspec +2 -2
- data/gems/e11y-devtools/README.md +158 -0
- data/gems/e11y-devtools/config/routes.rb +15 -0
- data/gems/e11y-devtools/e11y-devtools.gemspec +25 -0
- data/gems/e11y-devtools/exe/e11y +34 -0
- data/gems/e11y-devtools/frontend/.gitignore +24 -0
- data/gems/e11y-devtools/frontend/README.md +51 -0
- data/gems/e11y-devtools/frontend/index.html +14 -0
- data/gems/e11y-devtools/frontend/package-lock.json +3707 -0
- data/gems/e11y-devtools/frontend/package.json +28 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/events/recent.json +4205 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/interactions.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0a2e04027cfa22d014bc22e8b27cd913/events.json +86 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0e1543af6a630fb3af6b52283154b3e0/events.json +169 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/1838b691faa49564f97db8592ff3978d/events.json +78 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/29f198f6588dacffb687777eb5f8f118/events.json +197 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/34bc3c9c0097de28a7a6f99b90a8e7bc/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/3ba6c20d068ab9cee00e51b180e66444/events.json +184 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/435bfd8f17b9009146a79812d7c3726d/events.json +144 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/4c7676e3fe668e99edb2b94d7d5678a9/events.json +222 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/6daf0d47974bedfc55d5de7004a3ea9f/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8a81ada42834d15f287bb40010043605/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8c0a98900edaae105469df8daedccf02/events.json +198 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8e4f645180f8a7d1dce426b07380466b/events.json +222 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/93db346fa5d44a032605a13b627f4b80/events.json +128 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/98ff6146faf7bd9be8bd03a8275817ba/events.json +223 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/9997ddd0247bc7e25f2ca7a5c415c93d/events.json +197 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/99e35f8ef3baedd798cc4fd085980ad9/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b4f3095c1909924cbc98889a86c83d6d/events.json +131 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b54b7fc32b7575a7110de809d11ccda0/events.json +128 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c0b48033fa06746bcc5886745e053cff/events.json +169 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c44649ac76701b4558927cd2305ab535/events.json +169 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/d601ae3320057580a39dbdac2edfdf4a/events.json +248 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e67e724bab422d2b52eeb49635e512e1/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e6c72765a28f158a8485b35fa63f73da/events.json +194 -0
- data/gems/e11y-devtools/frontend/public/mocks/v1/traces/f541b87405c9a54819b18ebe529f6419/events.json +194 -0
- data/gems/e11y-devtools/frontend/scripts/generate_mocks.rb +397 -0
- data/gems/e11y-devtools/frontend/src/App.svelte +827 -0
- data/gems/e11y-devtools/frontend/src/components/Fab.svelte +19 -0
- data/gems/e11y-devtools/frontend/src/components/FilterBar.svelte +38 -0
- data/gems/e11y-devtools/frontend/src/components/FullscreenPanel.svelte +82 -0
- data/gems/e11y-devtools/frontend/src/components/InteractionsTimeline.svelte +264 -0
- data/gems/e11y-devtools/frontend/src/components/RecentHistogram.svelte +354 -0
- data/gems/e11y-devtools/frontend/src/lib/api.ts +37 -0
- data/gems/e11y-devtools/frontend/src/lib/eventIdentity.ts +12 -0
- data/gems/e11y-devtools/frontend/src/lib/format.ts +37 -0
- data/gems/e11y-devtools/frontend/src/lib/listFilter.ts +43 -0
- data/gems/e11y-devtools/frontend/src/lib/recentVolume.ts +80 -0
- data/gems/e11y-devtools/frontend/src/lib/router.ts +12 -0
- data/gems/e11y-devtools/frontend/src/lib/transitions.ts +34 -0
- data/gems/e11y-devtools/frontend/src/lib/viewportOrigin.ts +25 -0
- data/gems/e11y-devtools/frontend/src/main.ts +8 -0
- data/gems/e11y-devtools/frontend/src/overlay-entry.ts +24 -0
- data/gems/e11y-devtools/frontend/src/overlay.css +1080 -0
- data/gems/e11y-devtools/frontend/svelte.config.js +2 -0
- data/gems/e11y-devtools/frontend/test_puppeteer.js +41 -0
- data/gems/e11y-devtools/frontend/test_scale.js +3 -0
- data/gems/e11y-devtools/frontend/tsconfig.app.json +21 -0
- data/gems/e11y-devtools/frontend/tsconfig.json +7 -0
- data/gems/e11y-devtools/frontend/tsconfig.node.json +26 -0
- data/gems/e11y-devtools/frontend/vite.config.ts +36 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/server.rb +96 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tool_base.rb +25 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/clear.rb +31 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/errors.rb +35 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/event_detail.rb +33 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/events_by_trace.rb +33 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/interactions.rb +40 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/recent_events.rb +34 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/search.rb +34 -0
- data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/stats.rb +30 -0
- data/gems/e11y-devtools/lib/e11y/devtools/overlay/assets/overlay.js +20 -0
- data/gems/e11y-devtools/lib/e11y/devtools/overlay/controller.rb +94 -0
- data/gems/e11y-devtools/lib/e11y/devtools/overlay/engine.rb +26 -0
- data/gems/e11y-devtools/lib/e11y/devtools/overlay/middleware.rb +80 -0
- data/gems/e11y-devtools/lib/e11y/devtools/overlay/rails_controller.rb +67 -0
- data/gems/e11y-devtools/lib/e11y/devtools/tui/app.rb +262 -0
- data/gems/e11y-devtools/lib/e11y/devtools/tui/grouping.rb +66 -0
- data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_detail.rb +62 -0
- data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_list.rb +70 -0
- data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/interaction_list.rb +47 -0
- data/gems/e11y-devtools/lib/e11y/devtools/version.rb +8 -0
- data/gems/e11y-devtools/lib/e11y/devtools.rb +13 -0
- data/gems/e11y-devtools/spec/e11y/devtools/mcp/tools_spec.rb +107 -0
- data/gems/e11y-devtools/spec/e11y/devtools/overlay/controller_spec.rb +91 -0
- data/gems/e11y-devtools/spec/e11y/devtools/overlay/middleware_spec.rb +46 -0
- data/gems/e11y-devtools/spec/e11y/devtools/tui/app_spec.rb +85 -0
- data/gems/e11y-devtools/spec/e11y/devtools/tui/grouping_spec.rb +64 -0
- data/gems/e11y-devtools/spec/spec_helper.rb +5 -0
- data/gems/e11y-devtools/spec/tui/widgets/event_list_spec.rb +44 -0
- data/gems/e11y-devtools/spec/tui/widgets/interaction_list_spec.rb +62 -0
- data/lib/e11y/adapters/audit_encrypted.rb +53 -11
- data/lib/e11y/adapters/base.rb +33 -34
- data/lib/e11y/adapters/dev_log/file_store.rb +143 -0
- data/lib/e11y/adapters/dev_log/query.rb +219 -0
- data/lib/e11y/adapters/dev_log.rb +118 -0
- data/lib/e11y/adapters/file.rb +3 -6
- data/lib/e11y/adapters/in_memory.rb +52 -5
- data/lib/e11y/adapters/in_memory_test.rb +29 -0
- data/lib/e11y/adapters/loki.rb +58 -23
- data/lib/e11y/adapters/null.rb +82 -0
- data/lib/e11y/adapters/opentelemetry_collector.rb +183 -0
- data/lib/e11y/adapters/otel_logs.rb +136 -23
- data/lib/e11y/adapters/sentry.rb +4 -7
- data/lib/e11y/adapters/stdout.rb +73 -7
- data/lib/e11y/adapters/yabeda.rb +153 -29
- data/lib/e11y/buffers/adaptive_buffer.rb +3 -17
- data/lib/e11y/buffers/{request_scoped_buffer.rb → ephemeral_buffer.rb} +72 -58
- data/lib/e11y/buffers/ring_buffer.rb +3 -16
- data/lib/e11y/configuration.rb +272 -0
- data/lib/e11y/console.rb +10 -17
- data/lib/e11y/current.rb +53 -1
- data/lib/e11y/debug/pipeline_inspector.rb +96 -0
- data/lib/e11y/documentation/generator.rb +48 -0
- data/lib/e11y/event/base.rb +176 -82
- data/lib/e11y/event/value_sampling_config.rb +1 -5
- data/lib/e11y/events/rails/database/query.rb +1 -4
- data/lib/e11y/events/rails/job/failed.rb +2 -0
- data/lib/e11y/instruments/active_job.rb +44 -12
- data/lib/e11y/instruments/rails_instrumentation.rb +49 -24
- data/lib/e11y/instruments/sidekiq.rb +135 -31
- data/lib/e11y/linters/base.rb +11 -0
- data/lib/e11y/linters/pii/pii_declaration_linter.rb +120 -0
- data/lib/e11y/linters/slo/config_consistency_linter.rb +76 -0
- data/lib/e11y/linters/slo/explicit_declaration_linter.rb +36 -0
- data/lib/e11y/linters/slo/slo_status_from_linter.rb +41 -0
- data/lib/e11y/logger/bridge.rb +26 -7
- data/lib/e11y/metrics/cardinality_protection.rb +10 -15
- data/lib/e11y/metrics/cardinality_tracker.rb +16 -6
- data/lib/e11y/metrics/registry.rb +3 -5
- data/lib/e11y/metrics/test_backend.rb +62 -0
- data/lib/e11y/metrics.rb +56 -10
- data/lib/e11y/middleware/adapter_resolver.rb +40 -0
- data/lib/e11y/middleware/audit_signing.rb +43 -6
- data/lib/e11y/middleware/baggage_protection.rb +75 -0
- data/lib/e11y/middleware/dev_log_source.rb +24 -0
- data/lib/e11y/middleware/event_slo.rb +23 -9
- data/lib/e11y/middleware/otel_span.rb +23 -0
- data/lib/e11y/middleware/pii_filter.rb +104 -75
- data/lib/e11y/middleware/rate_limiting.rb +54 -27
- data/lib/e11y/middleware/request.rb +70 -23
- data/lib/e11y/middleware/routing.rb +78 -21
- data/lib/e11y/middleware/sampling.rb +66 -17
- data/lib/e11y/middleware/self_monitoring_emit.rb +39 -0
- data/lib/e11y/middleware/trace_context.rb +45 -10
- data/lib/e11y/middleware/track_latency.rb +34 -0
- data/lib/e11y/middleware/validation.rb +7 -16
- data/lib/e11y/middleware/versioning.rb +26 -22
- data/lib/e11y/opentelemetry/semantic_conventions.rb +109 -0
- data/lib/e11y/opentelemetry/span_creator.rb +142 -0
- data/lib/e11y/pii/patterns.rb +12 -1
- data/lib/e11y/pipeline/builder.rb +4 -4
- data/lib/e11y/presets/audit_event.rb +13 -2
- data/lib/e11y/railtie.rb +52 -14
- data/lib/e11y/registry.rb +306 -0
- data/lib/e11y/reliability/circuit_breaker.rb +19 -21
- data/lib/e11y/reliability/dlq/base.rb +71 -0
- data/lib/e11y/reliability/dlq/file_adapter.rb +301 -0
- data/lib/e11y/reliability/dlq/file_storage.rb +63 -34
- data/lib/e11y/reliability/dlq/filter.rb +37 -54
- data/lib/e11y/reliability/retry_handler.rb +26 -29
- data/lib/e11y/reliability/retry_rate_limiter.rb +3 -11
- data/lib/e11y/sampling/error_spike_detector.rb +0 -2
- data/lib/e11y/sampling/load_monitor.rb +5 -9
- data/lib/e11y/sampling/stratified_tracker.rb +18 -0
- data/lib/e11y/self_monitoring/buffer_monitor.rb +2 -0
- data/lib/e11y/self_monitoring/performance_monitor.rb +19 -61
- data/lib/e11y/self_monitoring/reliability_monitor.rb +4 -74
- data/lib/e11y/slo/config_loader.rb +40 -0
- data/lib/e11y/slo/config_validator.rb +58 -0
- data/lib/e11y/slo/dashboard_generator.rb +122 -0
- data/lib/e11y/slo/event_driven.rb +8 -0
- data/lib/e11y/slo/tracker.rb +31 -4
- data/lib/e11y/testing/have_tracked_event_matcher.rb +190 -0
- data/lib/e11y/testing/rspec_matchers.rb +21 -0
- data/lib/e11y/testing/snapshot_matcher.rb +86 -0
- data/lib/e11y/trace_context/sampler.rb +35 -0
- data/lib/e11y/tracing/faraday_middleware.rb +31 -0
- data/lib/e11y/tracing/net_http_patch.rb +33 -0
- data/lib/e11y/tracing/propagator.rb +144 -0
- data/lib/e11y/tracing.rb +47 -0
- data/lib/e11y/version.rb +1 -1
- data/lib/e11y/versioning/version_extractor.rb +32 -0
- data/lib/e11y.rb +123 -266
- data/lib/generators/e11y/event/event_generator.rb +22 -0
- data/lib/generators/e11y/event/templates/event.rb.tt +16 -0
- data/lib/generators/e11y/grafana_dashboard/grafana_dashboard_generator.rb +30 -0
- data/lib/generators/e11y/grafana_dashboard/templates/e11y_dashboard.json +81 -0
- data/lib/generators/e11y/install/install_generator.rb +34 -0
- data/lib/generators/e11y/install/templates/e11y.rb +239 -0
- data/lib/generators/e11y/prometheus_alerts/prometheus_alerts_generator.rb +29 -0
- data/lib/generators/e11y/prometheus_alerts/templates/e11y_alerts.yml +28 -0
- data/lib/tasks/e11y_docs.rake +30 -0
- data/lib/tasks/e11y_events.rake +71 -0
- data/lib/tasks/e11y_lint.rake +91 -0
- data/lib/tasks/e11y_slo.rake +29 -0
- metadata +186 -39
- data/docs/ADR-003-slo-observability.md +0 -3337
- data/docs/ADR-010-developer-experience.md +0 -2166
- data/docs/API-REFERENCE-L28.md +0 -914
- data/docs/COMPREHENSIVE-CONFIGURATION.md +0 -2366
- data/docs/CONTRIBUTING.md +0 -312
- data/docs/IMPLEMENTATION_NOTES.md +0 -2804
- data/docs/IMPLEMENTATION_PLAN.md +0 -1971
- data/docs/IMPLEMENTATION_PLAN_ARCHITECTURE.md +0 -586
- data/docs/PLAN.md +0 -148
- data/docs/README.md +0 -296
- data/docs/design/00-memory-optimization.md +0 -593
- data/docs/guides/MIGRATION-L27-L28.md +0 -692
- data/docs/guides/PERFORMANCE-BENCHMARKS.md +0 -434
- data/docs/guides/README.md +0 -44
- data/docs/use_cases/UC-003-pattern-based-metrics.md +0 -1627
- data/lib/e11y/adapters/registry.rb +0 -141
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- ✅ Trace context propagation (trace_id, span_id)
|
|
13
13
|
- ✅ User context support
|
|
14
14
|
- ✅ 39 comprehensive tests
|
|
15
|
-
- 📖 See [ADR-004 §4.4](../ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details
|
|
15
|
+
- 📖 See [ADR-004 §4.4](../architecture/ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -72,23 +72,22 @@ end
|
|
|
72
72
|
|
|
73
73
|
### 1. Automatic Exception Capture
|
|
74
74
|
|
|
75
|
-
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
75
|
+
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../architecture/ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
76
76
|
|
|
77
77
|
**Configuration (2026-01-19 - Actual Implementation):**
|
|
78
78
|
```ruby
|
|
79
79
|
# config/initializers/e11y.rb
|
|
80
80
|
require 'e11y'
|
|
81
81
|
|
|
82
|
-
#
|
|
83
|
-
E11y
|
|
84
|
-
:sentry
|
|
85
|
-
E11y::Adapters::Sentry.new(
|
|
82
|
+
# Configure Sentry adapter
|
|
83
|
+
E11y.configure do |config|
|
|
84
|
+
config.adapters[:sentry] = E11y::Adapters::Sentry.new(
|
|
86
85
|
dsn: ENV['SENTRY_DSN'],
|
|
87
86
|
environment: Rails.env,
|
|
88
87
|
severity_threshold: :warn, # Send :warn, :error, :fatal to Sentry
|
|
89
88
|
breadcrumbs: true # Track all events as breadcrumbs
|
|
90
89
|
)
|
|
91
|
-
|
|
90
|
+
end
|
|
92
91
|
|
|
93
92
|
# Use in events
|
|
94
93
|
class Events::PaymentFailed < E11y::Event::Base
|
|
@@ -185,7 +184,7 @@ Events::PaymentFailed.track(
|
|
|
185
184
|
|
|
186
185
|
### 4. Custom Fingerprinting
|
|
187
186
|
|
|
188
|
-
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
187
|
+
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../architecture/ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
189
188
|
|
|
190
189
|
**Group similar errors in Sentry:**
|
|
191
190
|
```ruby
|
|
@@ -218,7 +217,7 @@ end
|
|
|
218
217
|
|
|
219
218
|
### 5. Sampling Control
|
|
220
219
|
|
|
221
|
-
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
220
|
+
> **Implementation:** See [ADR-004 Section 4.4: Sentry Adapter](../architecture/ADR-004-adapter-architecture.md#44-sentry-adapter) for technical details.
|
|
222
221
|
|
|
223
222
|
**Avoid Sentry quota exhaustion:**
|
|
224
223
|
```ruby
|
|
@@ -699,16 +698,15 @@ The implemented `E11y::Adapters::Sentry` provides:
|
|
|
699
698
|
|
|
700
699
|
**Usage Example:**
|
|
701
700
|
```ruby
|
|
702
|
-
#
|
|
703
|
-
E11y
|
|
704
|
-
:sentry
|
|
705
|
-
E11y::Adapters::Sentry.new(
|
|
701
|
+
# Configure adapter
|
|
702
|
+
E11y.configure do |config|
|
|
703
|
+
config.adapters[:sentry] = E11y::Adapters::Sentry.new(
|
|
706
704
|
dsn: ENV['SENTRY_DSN'],
|
|
707
705
|
environment: 'production',
|
|
708
706
|
severity_threshold: :warn,
|
|
709
707
|
breadcrumbs: true
|
|
710
708
|
)
|
|
711
|
-
|
|
709
|
+
end
|
|
712
710
|
|
|
713
711
|
# Track error event
|
|
714
712
|
Events::PaymentFailed.track(
|
|
@@ -750,7 +748,7 @@ end
|
|
|
750
748
|
**See Also:**
|
|
751
749
|
- Implementation: `lib/e11y/adapters/sentry.rb` (211 lines)
|
|
752
750
|
- Tests: `spec/e11y/adapters/sentry_spec.rb` (39 tests)
|
|
753
|
-
- ADR: [ADR-004 §4.4](../ADR-004-adapter-architecture.md#44-sentry-adapter)
|
|
751
|
+
- ADR: [ADR-004 §4.4](../architecture/ADR-004-adapter-architecture.md#44-sentry-adapter)
|
|
754
752
|
|
|
755
753
|
---
|
|
756
754
|
|
|
@@ -42,19 +42,20 @@ Events::PaymentProcessed.track(order_id: '123', amount: 99)
|
|
|
42
42
|
Events::OrderCreated.track(order_id: '456')
|
|
43
43
|
# → { trace_id: 'def-456', event: 'order.created' }
|
|
44
44
|
|
|
45
|
-
# Request 1 background job (trace_id: abc-123
|
|
45
|
+
# Request 1 background job (C17 Hybrid: NEW trace_id xyz-789, parent_trace_id: abc-123)
|
|
46
46
|
Events::EmailSent.track(order_id: '123')
|
|
47
|
-
# → { trace_id: 'abc-123', event: 'email.sent' }
|
|
47
|
+
# → { trace_id: 'xyz-789', parent_trace_id: 'abc-123', event: 'email.sent' }
|
|
48
48
|
|
|
49
49
|
# In Grafana/Loki:
|
|
50
|
-
# {trace_id="abc-123"} →
|
|
50
|
+
# {trace_id="abc-123"} → Request timeline
|
|
51
|
+
# {trace_id="xyz-789"} or {parent_trace_id="abc-123"} → Job timeline (linked to request)
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
---
|
|
54
55
|
|
|
55
56
|
## 🎯 Features
|
|
56
57
|
|
|
57
|
-
> **Implementation:** See [ADR-005: Tracing Context](../ADR-005-tracing-context.md) for complete architecture, including [Section 3: Current (Thread-Local Storage)](../ADR-005-tracing-context.md#3-current-thread-local-storage), [Section 4: Trace ID Generation](../ADR-005-tracing-context.md#4-trace-id-generation-idgenerator), and [Section 5: W3C Trace Context](../ADR-005-tracing-context.md#5-w3c-trace-context).
|
|
58
|
+
> **Implementation:** See [ADR-005: Tracing Context](../architecture/ADR-005-tracing-context.md) for complete architecture, including [Section 3: Current (Thread-Local Storage)](../architecture/ADR-005-tracing-context.md#3-current-thread-local-storage), [Section 4: Trace ID Generation](../architecture/ADR-005-tracing-context.md#4-trace-id-generation-idgenerator), and [Section 5: W3C Trace Context](../architecture/ADR-005-tracing-context.md#5-w3c-trace-context).
|
|
58
59
|
|
|
59
60
|
### 1. Automatic Trace ID Propagation
|
|
60
61
|
|
|
@@ -104,25 +105,26 @@ end
|
|
|
104
105
|
|
|
105
106
|
### 2. Background Job Propagation
|
|
106
107
|
|
|
107
|
-
> **Implementation:** See [ADR-005 Section 6.2: Job Propagator](../ADR-005-tracing-context.md#62-job-propagator-sidekiqactivejob) for Sidekiq/ActiveJob integration details.
|
|
108
|
+
> **Implementation:** See [ADR-005 Section 6.2: Job Propagator](../architecture/ADR-005-tracing-context.md#62-job-propagator-sidekiqactivejob) for Sidekiq/ActiveJob integration details.
|
|
108
109
|
|
|
109
110
|
**Problem:** Background jobs lose trace_id context
|
|
110
111
|
|
|
111
112
|
**Solution:** Automatic propagation via Sidekiq middleware
|
|
112
113
|
|
|
113
114
|
```ruby
|
|
114
|
-
# lib/e11y/
|
|
115
|
+
# lib/e11y/instruments/sidekiq.rb (built-in)
|
|
116
|
+
# C17 Hybrid: Job gets NEW trace_id; parent_trace_id links to enqueuing request
|
|
115
117
|
module E11y
|
|
116
|
-
module
|
|
117
|
-
class
|
|
118
|
-
def
|
|
119
|
-
# Extract
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
E11y::
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
module Instruments
|
|
119
|
+
class Sidekiq::ServerMiddleware
|
|
120
|
+
def setup_job_context(job, queue)
|
|
121
|
+
# Extract parent from job payload
|
|
122
|
+
parent_trace_id = job['e11y_parent_trace_id']
|
|
123
|
+
# Generate NEW trace_id for this job
|
|
124
|
+
E11y::Current.trace_id = generate_trace_id
|
|
125
|
+
E11y::Current.parent_trace_id = parent_trace_id
|
|
126
|
+
E11y::Current.sampled = job['e11y_sampled'] # Propagate sampling decision
|
|
127
|
+
# ...
|
|
126
128
|
end
|
|
127
129
|
end
|
|
128
130
|
end
|
|
@@ -149,43 +151,43 @@ class OrdersController < ApplicationController
|
|
|
149
151
|
def create
|
|
150
152
|
order = Order.create!(params)
|
|
151
153
|
|
|
152
|
-
# Enqueue job (
|
|
154
|
+
# Enqueue job (C17: parent_trace_id + e11y_sampled propagated)
|
|
153
155
|
SendOrderConfirmationJob.perform_later(order.id)
|
|
154
|
-
# → Job payload includes: { '
|
|
156
|
+
# → Job payload includes: { 'e11y_parent_trace_id' => 'abc-123', 'e11y_sampled' => true }
|
|
155
157
|
|
|
156
158
|
render json: order
|
|
157
159
|
end
|
|
158
160
|
end
|
|
159
161
|
|
|
160
|
-
# In job (trace_id: abc-123
|
|
162
|
+
# In job (C17 Hybrid: NEW trace_id xyz-789, parent_trace_id: abc-123)
|
|
161
163
|
class SendOrderConfirmationJob < ApplicationJob
|
|
162
164
|
def perform(order_id)
|
|
163
165
|
order = Order.find(order_id)
|
|
164
166
|
|
|
165
|
-
# trace_id
|
|
167
|
+
# Job gets NEW trace_id; parent_trace_id links to originating request
|
|
166
168
|
Events::EmailSending.track(order_id: order.id)
|
|
167
|
-
# → trace_id = '
|
|
169
|
+
# → trace_id = 'xyz-789', parent_trace_id = 'abc-123'
|
|
168
170
|
|
|
169
171
|
UserMailer.order_confirmation(order).deliver_now
|
|
170
172
|
|
|
171
173
|
Events::EmailSent.track(order_id: order.id)
|
|
172
|
-
# → trace_id = '
|
|
174
|
+
# → trace_id = 'xyz-789' (same job trace)
|
|
173
175
|
end
|
|
174
176
|
end
|
|
175
177
|
|
|
176
|
-
# Timeline in Grafana:
|
|
178
|
+
# Timeline in Grafana (C17 Hybrid):
|
|
177
179
|
# 10:00:00.000 [abc-123] order.created (controller)
|
|
178
180
|
# 10:00:00.050 [abc-123] payment.processed (controller)
|
|
179
|
-
# 10:00:00.100 [
|
|
180
|
-
# 10:00:03.200 [
|
|
181
|
-
# →
|
|
181
|
+
# 10:00:00.100 [xyz-789] email.sending (job, parent: abc-123)
|
|
182
|
+
# 10:00:03.200 [xyz-789] email.sent (job)
|
|
183
|
+
# → Query by parent_trace_id to link job trace to request trace
|
|
182
184
|
```
|
|
183
185
|
|
|
184
186
|
---
|
|
185
187
|
|
|
186
188
|
### 3. Cross-Service Propagation
|
|
187
189
|
|
|
188
|
-
> **Implementation:** See [ADR-005 Section 6.1: HTTP Propagator](../ADR-005-tracing-context.md#61-http-propagator-outgoing-requests) for outgoing request integration (Faraday, HTTP.rb).
|
|
190
|
+
> **Implementation:** See [ADR-005 Section 6.1: HTTP Propagator](../architecture/ADR-005-tracing-context.md#61-http-propagator-outgoing-requests) for outgoing request integration (Faraday, HTTP.rb).
|
|
189
191
|
|
|
190
192
|
**Microservices scenario:**
|
|
191
193
|
```ruby
|
|
@@ -507,7 +509,7 @@ end
|
|
|
507
509
|
|
|
508
510
|
### 6. Trace-Consistent Sampling Integration
|
|
509
511
|
|
|
510
|
-
> **Implementation:** See [ADR-005 Section 7: Sampling Decisions](../ADR-005-tracing-context.md#7-sampling-decisions-trace-consistent-sampling) for trace-consistent sampling architecture.
|
|
512
|
+
> **Implementation:** See [ADR-005 Section 7: Sampling Decisions](../architecture/ADR-005-tracing-context.md#7-sampling-decisions-trace-consistent-sampling) for trace-consistent sampling architecture.
|
|
511
513
|
|
|
512
514
|
**Critical Feature:** Sampling decisions must be consistent across trace boundaries
|
|
513
515
|
|
|
@@ -5,31 +5,20 @@
|
|
|
5
5
|
**Setup Time:** 20-30 minutes
|
|
6
6
|
**Target Users:** All developers, Security teams, Compliance teams
|
|
7
7
|
|
|
8
|
+
> **Approach:** Event-level `pii_filtering do` in event classes. Use inheritance for shared rules (e.g. `BaseUserEvent`). No global `config.pii_filter`.
|
|
9
|
+
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
## 📋 Overview
|
|
11
13
|
|
|
12
14
|
### Problem Statement
|
|
13
15
|
|
|
14
|
-
**Current Approach (
|
|
16
|
+
**Current Approach (Manual per-event):**
|
|
15
17
|
```ruby
|
|
16
|
-
#
|
|
17
|
-
# Rails already has PII filtering
|
|
18
|
-
config.filter_parameters += [:password, :email, :ssn, :credit_card]
|
|
19
|
-
|
|
20
|
-
# config/initializers/e11y.rb
|
|
21
|
-
# Do we need to duplicate for E11y?
|
|
22
|
-
E11y.configure do |config|
|
|
23
|
-
config.pii_filter do
|
|
24
|
-
mask_fields :password, :email, :ssn, :credit_card # ← Duplication! 😞
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
18
|
+
# Each event class needs its own PII rules — duplication across similar events
|
|
28
19
|
# Problems:
|
|
29
|
-
# -
|
|
30
|
-
# - Easy to forget
|
|
31
|
-
# - Inconsistency risk
|
|
32
|
-
# - More maintenance burden
|
|
20
|
+
# - Duplication across UserRegistered, UserLogin, PaymentCreated, etc.
|
|
21
|
+
# - Easy to forget or be inconsistent
|
|
33
22
|
```
|
|
34
23
|
|
|
35
24
|
### E11y Solution
|
|
@@ -92,31 +81,25 @@ Events::UserCreated.track(
|
|
|
92
81
|
|
|
93
82
|
---
|
|
94
83
|
|
|
95
|
-
### 2.
|
|
84
|
+
### 2. Event-Level DSL + Inheritance
|
|
96
85
|
|
|
97
|
-
**
|
|
86
|
+
**Define per-event; use inheritance for shared rules:**
|
|
98
87
|
```ruby
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
# 5. CUSTOM REPLACEMENT (default: '[FILTERED]')
|
|
116
|
-
replacement '[REDACTED]'
|
|
117
|
-
|
|
118
|
-
# 6. KEEP PARTIAL DATA (for debugging)
|
|
119
|
-
keep_partial_data true # 'em***@ex***' instead of '[FILTERED]'
|
|
88
|
+
# Base class — common rules for all user events
|
|
89
|
+
class BaseUserEvent < E11y::Event::Base
|
|
90
|
+
contains_pii true
|
|
91
|
+
pii_filtering do
|
|
92
|
+
masks :password, :api_key, :token
|
|
93
|
+
hashes :email
|
|
94
|
+
partials :phone
|
|
95
|
+
allows :user_id, :order_id
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Child — inherits + adds payment-specific fields
|
|
100
|
+
class Events::PaymentCreated < BaseUserEvent
|
|
101
|
+
pii_filtering do
|
|
102
|
+
masks :card_number, :cvv
|
|
120
103
|
end
|
|
121
104
|
end
|
|
122
105
|
```
|
|
@@ -125,42 +108,7 @@ end
|
|
|
125
108
|
|
|
126
109
|
### 3. Pattern-Based Filtering (Beyond Rails)
|
|
127
110
|
|
|
128
|
-
**
|
|
129
|
-
```ruby
|
|
130
|
-
E11y.configure do |config|
|
|
131
|
-
config.pii_filter do
|
|
132
|
-
# EMAIL ADDRESSES (scan content, not just keys)
|
|
133
|
-
filter_pattern /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i,
|
|
134
|
-
replacement: '[EMAIL]'
|
|
135
|
-
|
|
136
|
-
# CREDIT CARDS
|
|
137
|
-
filter_pattern /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/,
|
|
138
|
-
replacement: '[CARD]'
|
|
139
|
-
|
|
140
|
-
# SOCIAL SECURITY NUMBERS
|
|
141
|
-
filter_pattern /\b\d{3}-\d{2}-\d{4}\b/,
|
|
142
|
-
replacement: '[SSN]'
|
|
143
|
-
|
|
144
|
-
# PHONE NUMBERS (US/International)
|
|
145
|
-
filter_pattern /\b(\+\d{1,2}\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}\b/,
|
|
146
|
-
replacement: '[PHONE]'
|
|
147
|
-
|
|
148
|
-
# IP ADDRESSES
|
|
149
|
-
filter_pattern /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/,
|
|
150
|
-
replacement: '[IP]'
|
|
151
|
-
|
|
152
|
-
# API KEYS (common formats)
|
|
153
|
-
filter_pattern /[A-Za-z0-9_]{32,}/, # Long alphanumeric strings
|
|
154
|
-
replacement: '[API_KEY]'
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
# Usage:
|
|
159
|
-
Events::EmailSent.track(
|
|
160
|
-
subject: 'Hello user@example.com!', # → 'Hello [EMAIL]!'
|
|
161
|
-
body: 'Your card 4111-1111-1111-1111 was charged' # → 'Your card [CARD] was charged'
|
|
162
|
-
)
|
|
163
|
-
```
|
|
111
|
+
**:explicit_pii events** (`contains_pii true`) apply `E11y::PII::Patterns::VALUE_PATTERNS` to string values (email, SSN, credit card regexes). Field-level strategies (masks, hashes, partials) are defined in `pii_filtering do`. Per-adapter overrides use `exclude_adapters`; PIIFilter produces `payload_rewrites`, Routing merges per adapter.
|
|
164
112
|
|
|
165
113
|
---
|
|
166
114
|
|
|
@@ -493,7 +441,7 @@ end
|
|
|
493
441
|
|
|
494
442
|
## 🔐 Explicit PII Declaration
|
|
495
443
|
|
|
496
|
-
> **Implementation:** See [ADR-006 Section 3.0.3: Explicit PII Declaration](../ADR-006-security-compliance.md#303-explicit-pii-declaration) for detailed architecture.
|
|
444
|
+
> **Implementation:** See [ADR-006 Section 3.0.3: Explicit PII Declaration](../architecture/ADR-006-security-compliance.md#303-explicit-pii-declaration) for detailed architecture.
|
|
497
445
|
|
|
498
446
|
**Critical Design Principle:** Event classes MUST explicitly declare whether they contain PII. This enables E11y to apply the appropriate filtering tier (see Performance Tiers below) and allows linter validation.
|
|
499
447
|
|
|
@@ -510,7 +458,7 @@ end
|
|
|
510
458
|
|
|
511
459
|
### Declaration Syntax: `contains_pii`
|
|
512
460
|
|
|
513
|
-
**Option 1: No PII (
|
|
461
|
+
**Option 1: No PII (:no_pii — Skip Filtering)**
|
|
514
462
|
|
|
515
463
|
```ruby
|
|
516
464
|
class Events::HealthCheck < E11y::Event::Base
|
|
@@ -523,13 +471,13 @@ class Events::HealthCheck < E11y::Event::Base
|
|
|
523
471
|
contains_pii false
|
|
524
472
|
|
|
525
473
|
# Result:
|
|
526
|
-
# -
|
|
474
|
+
# - :no_pii filtering (0ms overhead)
|
|
527
475
|
# - All fields logged as-is
|
|
528
476
|
# - No pattern scanning
|
|
529
477
|
end
|
|
530
478
|
```
|
|
531
479
|
|
|
532
|
-
**Option 2: Default (
|
|
480
|
+
**Option 2: Default (:rails_filters — Rails Filters Only)**
|
|
533
481
|
|
|
534
482
|
```ruby
|
|
535
483
|
class Events::OrderCreated < E11y::Event::Base
|
|
@@ -539,12 +487,12 @@ class Events::OrderCreated < E11y::Event::Base
|
|
|
539
487
|
optional(:api_key).filled(:string) # Rails will filter this
|
|
540
488
|
end
|
|
541
489
|
|
|
542
|
-
# No declaration →
|
|
490
|
+
# No declaration → :rails_filters (Rails filters applied)
|
|
543
491
|
# Keys like :password, :token, :api_key automatically filtered
|
|
544
492
|
end
|
|
545
493
|
```
|
|
546
494
|
|
|
547
|
-
**Option 3: Explicit PII (
|
|
495
|
+
**Option 3: Explicit PII (:explicit_pii — Deep Filtering)**
|
|
548
496
|
|
|
549
497
|
```ruby
|
|
550
498
|
class Events::UserRegistered < E11y::Event::Base
|
|
@@ -751,7 +699,7 @@ end
|
|
|
751
699
|
|
|
752
700
|
### Default Behavior (No Declaration)
|
|
753
701
|
|
|
754
|
-
If `contains_pii` is not specified, E11y defaults to **
|
|
702
|
+
If `contains_pii` is not specified, E11y defaults to **:rails_filters** (Rails filters only):
|
|
755
703
|
|
|
756
704
|
```ruby
|
|
757
705
|
class Events::OrderPaid < E11y::Event::Base
|
|
@@ -761,7 +709,7 @@ class Events::OrderPaid < E11y::Event::Base
|
|
|
761
709
|
end
|
|
762
710
|
|
|
763
711
|
# No contains_pii declaration
|
|
764
|
-
# →
|
|
712
|
+
# → :rails_filters: Rails filters applied automatically
|
|
765
713
|
# → Keys like :password, :token, :api_key filtered
|
|
766
714
|
# → No linter validation
|
|
767
715
|
end
|
|
@@ -970,7 +918,7 @@ end
|
|
|
970
918
|
|
|
971
919
|
## ⚡ DSL Shortcuts (Rails-Style)
|
|
972
920
|
|
|
973
|
-
> **Implementation:** See [ADR-006 Section 3.4.4: Configuration API (Rails-Style DSL)](../ADR-006-security-compliance.md#344-configuration-api-rails-style-dsl) for detailed architecture.
|
|
921
|
+
> **Implementation:** See [ADR-006 Section 3.4.4: Configuration API (Rails-Style DSL)](../architecture/ADR-006-security-compliance.md#344-configuration-api-rails-style-dsl) for detailed architecture.
|
|
974
922
|
|
|
975
923
|
E11y provides **Rails-style DSL shortcuts** to simplify PII declarations. Instead of verbose `field` blocks, use one-liner shortcuts like `masks`, `hashes`, `skips` – similar to Rails validations.
|
|
976
924
|
|
|
@@ -1398,7 +1346,7 @@ masks :password, :token
|
|
|
1398
1346
|
|
|
1399
1347
|
## 🔍 Linter Enforcement
|
|
1400
1348
|
|
|
1401
|
-
> **Implementation:** See [ADR-006 Section 3.0.5: PII Declaration Linter](../ADR-006-security-compliance.md#305-pii-declaration-linter) for detailed architecture.
|
|
1349
|
+
> **Implementation:** See [ADR-006 Section 3.0.5: PII Declaration Linter](../architecture/ADR-006-security-compliance.md#305-pii-declaration-linter) for detailed architecture.
|
|
1402
1350
|
|
|
1403
1351
|
E11y includes a **PII Declaration Linter** that validates PII handling at boot time and in CI. This catches missing declarations, typos, and incomplete coverage BEFORE code reaches production.
|
|
1404
1352
|
|
|
@@ -1770,7 +1718,7 @@ end
|
|
|
1770
1718
|
|
|
1771
1719
|
## ⚡ Performance Tiers
|
|
1772
1720
|
|
|
1773
|
-
> **Implementation:** See [ADR-006 Section 3.0: PII Filtering Strategy](../ADR-006-security-compliance.md#30-pii-filtering-strategy) for detailed architecture.
|
|
1721
|
+
> **Implementation:** See [ADR-006 Section 3.0: PII Filtering Strategy](../architecture/ADR-006-security-compliance.md#30-pii-filtering-strategy) for detailed architecture.
|
|
1774
1722
|
|
|
1775
1723
|
E11y uses a **3-tier filtering strategy** to balance security and performance. Filtering ALL events by default would create massive overhead (1M events × 0.2ms = 200 seconds CPU/day). Instead, events are categorized into 3 tiers based on PII content.
|
|
1776
1724
|
|