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
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
3. [Correct Order](#3-correct-order)
|
|
15
15
|
- 3.1. Pipeline Flow
|
|
16
16
|
- 3.2. Why Each Middleware Needs Original Class Name
|
|
17
|
-
- 3.3. Audit
|
|
17
|
+
- 3.3. Audit Events in Single Pipeline (C01 Resolution) ⚠️ CRITICAL
|
|
18
18
|
- 3.3.1. The Problem: PII Filtering Breaks Audit Trail
|
|
19
19
|
- 3.3.2. Decision: Two Pipeline Configurations
|
|
20
20
|
- 3.3.3. Declaring Audit Events
|
|
@@ -71,16 +71,18 @@
|
|
|
71
71
|
```ruby
|
|
72
72
|
# config/initializers/e11y.rb
|
|
73
73
|
E11y.configure do |config|
|
|
74
|
-
config.
|
|
75
|
-
config.
|
|
76
|
-
config.
|
|
77
|
-
config.
|
|
78
|
-
config.
|
|
79
|
-
config.
|
|
80
|
-
config.
|
|
74
|
+
config.pipeline.use E11y::Middleware::TraceContext # 1
|
|
75
|
+
config.pipeline.use E11y::Middleware::Validation # 2
|
|
76
|
+
config.pipeline.use E11y::Middleware::PIIFilter # 3
|
|
77
|
+
config.pipeline.use E11y::Middleware::RateLimiting # 4
|
|
78
|
+
config.pipeline.use E11y::Middleware::Sampling # 5
|
|
79
|
+
config.pipeline.use E11y::Middleware::Versioning # 6 ← LAST!
|
|
80
|
+
config.pipeline.use E11y::Middleware::Routing # 7
|
|
81
81
|
end
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
The default stack in `lib/e11y/configuration.rb` also includes `TrackLatency`, `BaggageProtection`, `AuditSigning`, `EventSlo`, and `SelfMonitoringEmit` after routing; the snippet is the ordering slice that matters for **versioning before routing**.
|
|
85
|
+
|
|
84
86
|
---
|
|
85
87
|
|
|
86
88
|
## 3. Correct Order
|
|
@@ -123,7 +125,7 @@ Adapters → Receive normalized name
|
|
|
123
125
|
|------------|----------------|------|
|
|
124
126
|
| **TraceContext** | No | Just adds trace_id, doesn't care about class |
|
|
125
127
|
| **Validation** | ✅ Yes | Schema is attached to specific class (V2 ≠ V1) |
|
|
126
|
-
| **
|
|
128
|
+
| **PIIFilter** | ✅ Yes | PII rules may differ between V1 and V2 |
|
|
127
129
|
| **RateLimiting** | ✅ Yes | Rate limits may differ between V1 and V2 |
|
|
128
130
|
| **Sampling** | ✅ Yes | Sample rates may differ between V1 and V2 |
|
|
129
131
|
| **Versioning** | No | Normalizes for adapters (cosmetic change) |
|
|
@@ -138,11 +140,11 @@ Adapters → Receive normalized name
|
|
|
138
140
|
|
|
139
141
|
```ruby
|
|
140
142
|
# ❌ WRONG ORDER!
|
|
141
|
-
config.
|
|
142
|
-
config.
|
|
143
|
-
config.
|
|
144
|
-
config.
|
|
145
|
-
config.
|
|
143
|
+
config.pipeline.use E11y::Middleware::Versioning # 1 ← Too early!
|
|
144
|
+
config.pipeline.use E11y::Middleware::Validation # 2
|
|
145
|
+
config.pipeline.use E11y::Middleware::PIIFilter # 3
|
|
146
|
+
config.pipeline.use E11y::Middleware::RateLimiting # 4
|
|
147
|
+
config.pipeline.use E11y::Middleware::Sampling # 5
|
|
146
148
|
```
|
|
147
149
|
|
|
148
150
|
### 4.2. What Breaks
|
|
@@ -244,17 +246,17 @@ Loki receives:
|
|
|
244
246
|
- [ ] PII rules are configured **per original class** (if differ)
|
|
245
247
|
- [ ] Sampling rules are configured **per original class** (if differ)
|
|
246
248
|
- [ ] Metrics track **both** normalized name and version
|
|
247
|
-
- [ ] Audit events
|
|
249
|
+
- [ ] Audit events skip PII filtering via conditional logic (C01 - see §3.3, single pipeline)
|
|
248
250
|
- [ ] Audit events stored in encrypted adapter (C01 requirement)
|
|
249
251
|
|
|
250
252
|
---
|
|
251
253
|
|
|
252
|
-
## 3.3. Audit
|
|
254
|
+
## 3.3. Audit Events in Single Pipeline (C01 Resolution)
|
|
253
255
|
|
|
254
256
|
> **⚠️ CRITICAL: C01 Conflict Resolution - PII Filtering × Audit Trail Signing**
|
|
255
257
|
> **See:** [CONFLICT-ANALYSIS.md C01](researches/CONFLICT-ANALYSIS.md#c01-pii-filtering--audit-trail-signing) for detailed analysis
|
|
256
258
|
> **Problem:** PII filtering before signing breaks non-repudiation (auditors can't verify original event)
|
|
257
|
-
> **Solution:**
|
|
259
|
+
> **Solution:** Single pipeline for all events. Audit events get conditional skip in PIIFilter via `contains_pii false` in AuditEvent preset (:no_pii = pass-through). No separate pipeline — no need.
|
|
258
260
|
|
|
259
261
|
### 3.3.1. The Problem: PII Filtering Breaks Audit Trail
|
|
260
262
|
|
|
@@ -278,39 +280,29 @@ Storage
|
|
|
278
280
|
- **Audit trail:** Must maintain cryptographic chain of custody
|
|
279
281
|
- **Forensics:** Must be able to reconstruct exact event that occurred
|
|
280
282
|
|
|
281
|
-
### 3.3.2. Decision:
|
|
283
|
+
### 3.3.2. Decision: One Pipeline with Conditional Skip
|
|
284
|
+
|
|
285
|
+
**All events go through a single pipeline.** Audit events get conditional skip in middleware:
|
|
282
286
|
|
|
283
|
-
**Standard Events (Non-Audit):**
|
|
284
287
|
```
|
|
285
288
|
1. TraceContext → Add trace_id, span_id, timestamp
|
|
286
289
|
2. Validation → Schema validation (original class)
|
|
287
|
-
3.
|
|
288
|
-
4. RateLimiting →
|
|
289
|
-
5. Sampling →
|
|
290
|
+
3. PIIFilter → Audit: skip (contains_pii false → :no_pii). Standard: filter PII ✅
|
|
291
|
+
4. RateLimiting → Audit: can skip (event_data[:audit_event]). Standard: rate limit
|
|
292
|
+
5. Sampling → Audit: sample_rate 1.0 (preset). Standard: adaptive
|
|
290
293
|
6. Versioning → Normalize event_name (LAST)
|
|
291
|
-
7. Routing → Route to buffer
|
|
294
|
+
7. Routing → Route to buffer / audit buffer
|
|
292
295
|
```
|
|
293
296
|
|
|
294
|
-
**
|
|
295
|
-
```
|
|
296
|
-
1. TraceContext → Add trace_id, span_id, timestamp
|
|
297
|
-
2. Validation → Schema validation (original class)
|
|
298
|
-
3. AuditSigning → Sign ORIGINAL data (includes PII!) ✅
|
|
299
|
-
4. Versioning → Normalize event_name (LAST)
|
|
300
|
-
5. Routing → Route to audit buffer
|
|
301
|
-
|
|
302
|
-
❌ NO PII filtering for audit events!
|
|
303
|
-
❌ NO rate limiting for audit events!
|
|
304
|
-
❌ NO sampling for audit events!
|
|
305
|
-
```
|
|
297
|
+
**AuditEvent preset:** `contains_pii false` → PIIFilter :no_pii = pass-through, original data preserved for signing.
|
|
306
298
|
|
|
307
299
|
### 3.3.3. Declaring Audit Events
|
|
308
300
|
|
|
309
301
|
**Event Class Flag:**
|
|
310
302
|
```ruby
|
|
311
|
-
# Audit event -
|
|
303
|
+
# Audit event - conditional skip in pipeline
|
|
312
304
|
class Events::PermissionChanged < E11y::Event::Base
|
|
313
|
-
|
|
305
|
+
include E11y::Presets::AuditEvent # audit_event true, contains_pii false
|
|
314
306
|
# Auto-set: retention = E11y.config.audit_retention (configurable!)
|
|
315
307
|
# rate_limiting = false (LOCKED!)
|
|
316
308
|
# sampling = false (LOCKED!)
|
|
@@ -330,9 +322,9 @@ class Events::PermissionChanged < E11y::Event::Base
|
|
|
330
322
|
version 1
|
|
331
323
|
end
|
|
332
324
|
|
|
333
|
-
# Standard event -
|
|
325
|
+
# Standard event - full pipeline
|
|
334
326
|
class Events::PageView < E11y::Event::Base
|
|
335
|
-
audit_event false
|
|
327
|
+
# audit_event false (default)
|
|
336
328
|
|
|
337
329
|
schema do
|
|
338
330
|
required(:user_id).filled(:string)
|
|
@@ -355,21 +347,15 @@ end
|
|
|
355
347
|
```ruby
|
|
356
348
|
# config/initializers/e11y.rb
|
|
357
349
|
E11y.configure do |config|
|
|
358
|
-
#
|
|
350
|
+
# Single pipeline for all events (audit and standard)
|
|
359
351
|
config.pipeline.use E11y::Middleware::TraceContext # 1
|
|
360
352
|
config.pipeline.use E11y::Middleware::Validation # 2
|
|
361
|
-
config.pipeline.use E11y::Middleware::
|
|
353
|
+
config.pipeline.use E11y::Middleware::PIIFilter # 3 # Audit: skip (contains_pii false)
|
|
362
354
|
config.pipeline.use E11y::Middleware::RateLimiting # 4
|
|
363
355
|
config.pipeline.use E11y::Middleware::Sampling # 5
|
|
364
|
-
config.pipeline.use E11y::Middleware::
|
|
365
|
-
config.pipeline.use E11y::Middleware::
|
|
366
|
-
|
|
367
|
-
# Audit pipeline override (for audit_event: true)
|
|
368
|
-
config.audit_pipeline.use E11y::Middleware::TraceContext # 1
|
|
369
|
-
config.audit_pipeline.use E11y::Middleware::Validation # 2
|
|
370
|
-
config.audit_pipeline.use E11y::Middleware::AuditSigning # 3 (NEW!)
|
|
371
|
-
config.audit_pipeline.use E11y::Middleware::Versioning # 4
|
|
372
|
-
config.audit_pipeline.use E11y::Middleware::AuditRouting # 5
|
|
356
|
+
config.pipeline.use E11y::Middleware::AuditSigning # 6 # Pass-through for non-audit
|
|
357
|
+
config.pipeline.use E11y::Middleware::Versioning # 7 # Last before Routing
|
|
358
|
+
config.pipeline.use E11y::Middleware::Routing # 8
|
|
373
359
|
|
|
374
360
|
# Audit event configuration
|
|
375
361
|
config.audit_events do
|
|
@@ -610,7 +596,7 @@ end
|
|
|
610
596
|
| Aspect | Pro | Con | Mitigation |
|
|
611
597
|
|--------|-----|-----|------------|
|
|
612
598
|
| **Non-repudiation** | ✅ Signature on original data | ⚠️ PII in audit events | Use encrypted storage adapter |
|
|
613
|
-
| **Legal compliance** | ✅ Meets audit requirements | ⚠️
|
|
599
|
+
| **Legal compliance** | ✅ Meets audit requirements | ⚠️ Conditional logic in middleware | Clear documentation |
|
|
614
600
|
| **PII protection** | ✅ Standard events filtered | ⚠️ Audit events not filtered | Restrict access to audit logs |
|
|
615
601
|
| **Performance** | ✅ No PII filter overhead | ⚠️ Signing + encryption overhead | Audit events are rare (<1%) |
|
|
616
602
|
|
|
@@ -682,7 +668,7 @@ class CustomEnrichmentMiddleware
|
|
|
682
668
|
end
|
|
683
669
|
|
|
684
670
|
# Pipeline execution:
|
|
685
|
-
# 1.
|
|
671
|
+
# 1. PIIFilter → Removes :email field ✅
|
|
686
672
|
# 2. CustomEnrichment → Adds :user_email field ❌ PII bypass!
|
|
687
673
|
# 3. Adapters → Receive event with unfiltered PII!
|
|
688
674
|
```
|
|
@@ -771,7 +757,7 @@ E11y.configure do |config|
|
|
|
771
757
|
|
|
772
758
|
# ZONE 2: Security (CRITICAL - PII handled here!)
|
|
773
759
|
config.pipeline.zone(:security) do
|
|
774
|
-
use E11y::Middleware::
|
|
760
|
+
use E11y::Middleware::PIIFilter # ← LAST PII touchpoint!
|
|
775
761
|
end
|
|
776
762
|
|
|
777
763
|
# ZONE 3: Routing (read-only decision making)
|
|
@@ -956,7 +942,7 @@ class UnsafeMiddleware < E11y::Middleware
|
|
|
956
942
|
end
|
|
957
943
|
end
|
|
958
944
|
|
|
959
|
-
# If placed after
|
|
945
|
+
# If placed after PIIFilter middleware:
|
|
960
946
|
# → PII bypass! Email not filtered!
|
|
961
947
|
# → GDPR violation!
|
|
962
948
|
```
|
|
@@ -971,7 +957,7 @@ class SafeEnrichmentMiddleware < E11y::Middleware
|
|
|
971
957
|
event_data[:payload][:request_path] = Current.request.path
|
|
972
958
|
event_data[:payload][:user_agent] = Current.request.user_agent
|
|
973
959
|
|
|
974
|
-
# These fields will be filtered by
|
|
960
|
+
# These fields will be filtered by PIIFilter middleware if needed
|
|
975
961
|
@app.call(event_data)
|
|
976
962
|
end
|
|
977
963
|
end
|
|
@@ -1014,7 +1000,7 @@ end
|
|
|
1014
1000
|
|
|
1015
1001
|
2. **Security Zone (PII filtering):**
|
|
1016
1002
|
- ❌ DO NOT add custom middleware here
|
|
1017
|
-
- ⚠️ Only E11y::Middleware::
|
|
1003
|
+
- ⚠️ Only E11y::Middleware::PIIFilter should run
|
|
1018
1004
|
- ⚠️ Treat this zone as read-only (no custom code)
|
|
1019
1005
|
|
|
1020
1006
|
3. **Post-Processing Zone (after PII filtering):**
|
|
@@ -1041,7 +1027,7 @@ end
|
|
|
1041
1027
|
```
|
|
1042
1028
|
|
|
1043
1029
|
**Related Conflicts:**
|
|
1044
|
-
- **C01:** Audit events skip PII filtering (see §3.3)
|
|
1030
|
+
- **C01:** Audit events skip PII filtering via contains_pii false (see §3.3)
|
|
1045
1031
|
- **C08:** Baggage PII protection (see ADR-007)
|
|
1046
1032
|
|
|
1047
1033
|
---
|
|
@@ -1053,8 +1039,6 @@ end
|
|
|
1053
1039
|
- **ADR-012: Event Evolution & Versioning** - Full versioning design
|
|
1054
1040
|
- **ADR-013: Reliability & Error Handling** - DLQ replay considerations
|
|
1055
1041
|
- **UC-012: Audit Trail** - Audit event use cases
|
|
1056
|
-
- **COMPREHENSIVE-CONFIGURATION.md** - Complete configuration examples
|
|
1057
|
-
- **CONFLICT-ANALYSIS.md** - Complete conflict analysis
|
|
1058
1042
|
|
|
1059
1043
|
---
|
|
1060
1044
|
|