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.
Files changed (288) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +130 -10
  3. data/CHANGELOG.md +80 -1
  4. data/CLAUDE.md +168 -0
  5. data/CONTRIBUTING.md +640 -0
  6. data/README.md +165 -701
  7. data/RELEASE.md +41 -12
  8. data/Rakefile +249 -57
  9. data/config/README.md +1 -1
  10. data/config/loki-local-config.yaml +12 -0
  11. data/config/otel-collector-config.yaml +44 -0
  12. data/cucumber.yml +1 -0
  13. data/docker-compose.yml +18 -2
  14. data/docs/ADAPTERS.md +76 -0
  15. data/docs/ADAPTIVE_SAMPLING.md +59 -0
  16. data/docs/COMPARISON.md +104 -0
  17. data/docs/CONFIGURATION.md +52 -0
  18. data/docs/DISTRIBUTED_TRACING.md +44 -0
  19. data/docs/LIMITATIONS.md +13 -0
  20. data/docs/METRICS_DSL.md +84 -0
  21. data/docs/PERFORMANCE.md +60 -0
  22. data/docs/PII_FILTERING.md +40 -0
  23. data/docs/PRESETS.md +65 -0
  24. data/docs/QUICK-START.md +546 -587
  25. data/docs/RAILS_INTEGRATION.md +79 -0
  26. data/docs/SCHEMA_VALIDATION.md +63 -0
  27. data/docs/SLO-PROMQL-ALERTS.md +161 -0
  28. data/docs/TESTING.md +69 -0
  29. data/docs/{ADR-001-architecture.md → architecture/ADR-001-architecture.md} +36 -65
  30. data/docs/{ADR-002-metrics-yabeda.md → architecture/ADR-002-metrics-yabeda.md} +62 -236
  31. data/docs/architecture/ADR-003-slo-observability.md +1402 -0
  32. data/docs/{ADR-004-adapter-architecture.md → architecture/ADR-004-adapter-architecture.md} +163 -146
  33. data/docs/{ADR-005-tracing-context.md → architecture/ADR-005-tracing-context.md} +10 -9
  34. data/docs/{ADR-006-security-compliance.md → architecture/ADR-006-security-compliance.md} +184 -191
  35. data/docs/{ADR-007-opentelemetry-integration.md → architecture/ADR-007-opentelemetry-integration.md} +3 -21
  36. data/docs/{ADR-008-rails-integration.md → architecture/ADR-008-rails-integration.md} +182 -743
  37. data/docs/{ADR-009-cost-optimization.md → architecture/ADR-009-cost-optimization.md} +45 -54
  38. data/docs/architecture/ADR-010-developer-experience.md +522 -0
  39. data/docs/{ADR-011-testing-strategy.md → architecture/ADR-011-testing-strategy.md} +44 -86
  40. data/docs/{ADR-012-event-evolution.md → architecture/ADR-012-event-evolution.md} +11 -11
  41. data/docs/{ADR-013-reliability-error-handling.md → architecture/ADR-013-reliability-error-handling.md} +37 -12
  42. data/docs/{ADR-014-event-driven-slo.md → architecture/ADR-014-event-driven-slo.md} +12 -24
  43. data/docs/{ADR-015-middleware-order.md → architecture/ADR-015-middleware-order.md} +43 -59
  44. data/docs/{ADR-016-self-monitoring-slo.md → architecture/ADR-016-self-monitoring-slo.md} +58 -355
  45. data/docs/{ADR-017-multi-rails-compatibility.md → architecture/ADR-017-multi-rails-compatibility.md} +4 -11
  46. data/docs/architecture/ADR-018-memory-optimization.md +366 -0
  47. data/docs/{ADR-INDEX.md → architecture/ADR-INDEX.md} +11 -6
  48. data/docs/plans/2026-03-20-browser-overlay-svelte.md +281 -0
  49. data/docs/{00-ICP-AND-TIMELINE.md → prd/00-ICP-AND-TIMELINE.md} +6 -6
  50. data/docs/{01-SCALE-REQUIREMENTS.md → prd/01-SCALE-REQUIREMENTS.md} +6 -6
  51. data/docs/prd/01-overview-vision.md +19 -14
  52. data/docs/use_cases/README.md +22 -23
  53. data/docs/use_cases/UC-001-request-scoped-debug-buffering.md +50 -44
  54. data/docs/use_cases/UC-002-business-event-tracking.md +26 -95
  55. data/docs/use_cases/UC-003-event-metrics.md +66 -0
  56. data/docs/use_cases/UC-004-zero-config-slo-tracking.md +33 -684
  57. data/docs/use_cases/UC-005-sentry-integration.md +13 -15
  58. data/docs/use_cases/UC-006-trace-context-management.md +30 -28
  59. data/docs/use_cases/UC-007-pii-filtering.md +35 -87
  60. data/docs/use_cases/UC-008-opentelemetry-integration.md +51 -89
  61. data/docs/use_cases/UC-009-multi-service-tracing.md +30 -178
  62. data/docs/use_cases/UC-010-background-job-tracking.md +24 -91
  63. data/docs/use_cases/UC-011-rate-limiting.md +95 -168
  64. data/docs/use_cases/UC-012-audit-trail.md +21 -46
  65. data/docs/use_cases/UC-013-high-cardinality-protection.md +29 -167
  66. data/docs/use_cases/UC-014-adaptive-sampling.md +2 -2
  67. data/docs/use_cases/UC-015-cost-optimization.md +46 -99
  68. data/docs/use_cases/UC-016-rails-logger-migration.md +39 -213
  69. data/docs/use_cases/UC-017-local-development.md +203 -777
  70. data/docs/use_cases/UC-018-testing-events.md +3 -3
  71. data/docs/use_cases/UC-019-retention-based-routing.md +53 -106
  72. data/docs/use_cases/UC-020-event-versioning.md +8 -9
  73. data/docs/use_cases/UC-021-error-handling-retry-dlq.md +18 -22
  74. data/docs/use_cases/UC-022-event-registry.md +15 -21
  75. data/docs/use_cases/backlog.md +119 -87
  76. data/e11y.gemspec +2 -2
  77. data/gems/e11y-devtools/README.md +158 -0
  78. data/gems/e11y-devtools/config/routes.rb +15 -0
  79. data/gems/e11y-devtools/e11y-devtools.gemspec +25 -0
  80. data/gems/e11y-devtools/exe/e11y +34 -0
  81. data/gems/e11y-devtools/frontend/.gitignore +24 -0
  82. data/gems/e11y-devtools/frontend/README.md +51 -0
  83. data/gems/e11y-devtools/frontend/index.html +14 -0
  84. data/gems/e11y-devtools/frontend/package-lock.json +3707 -0
  85. data/gems/e11y-devtools/frontend/package.json +28 -0
  86. data/gems/e11y-devtools/frontend/public/mocks/v1/events/recent.json +4205 -0
  87. data/gems/e11y-devtools/frontend/public/mocks/v1/interactions.json +194 -0
  88. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0a2e04027cfa22d014bc22e8b27cd913/events.json +86 -0
  89. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0e1543af6a630fb3af6b52283154b3e0/events.json +169 -0
  90. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/1838b691faa49564f97db8592ff3978d/events.json +78 -0
  91. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/29f198f6588dacffb687777eb5f8f118/events.json +197 -0
  92. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/34bc3c9c0097de28a7a6f99b90a8e7bc/events.json +194 -0
  93. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/3ba6c20d068ab9cee00e51b180e66444/events.json +184 -0
  94. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/435bfd8f17b9009146a79812d7c3726d/events.json +144 -0
  95. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/4c7676e3fe668e99edb2b94d7d5678a9/events.json +222 -0
  96. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/6daf0d47974bedfc55d5de7004a3ea9f/events.json +194 -0
  97. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8a81ada42834d15f287bb40010043605/events.json +194 -0
  98. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8c0a98900edaae105469df8daedccf02/events.json +198 -0
  99. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8e4f645180f8a7d1dce426b07380466b/events.json +222 -0
  100. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/93db346fa5d44a032605a13b627f4b80/events.json +128 -0
  101. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/98ff6146faf7bd9be8bd03a8275817ba/events.json +223 -0
  102. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/9997ddd0247bc7e25f2ca7a5c415c93d/events.json +197 -0
  103. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/99e35f8ef3baedd798cc4fd085980ad9/events.json +194 -0
  104. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b4f3095c1909924cbc98889a86c83d6d/events.json +131 -0
  105. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b54b7fc32b7575a7110de809d11ccda0/events.json +128 -0
  106. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c0b48033fa06746bcc5886745e053cff/events.json +169 -0
  107. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c44649ac76701b4558927cd2305ab535/events.json +169 -0
  108. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/d601ae3320057580a39dbdac2edfdf4a/events.json +248 -0
  109. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e67e724bab422d2b52eeb49635e512e1/events.json +194 -0
  110. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e6c72765a28f158a8485b35fa63f73da/events.json +194 -0
  111. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/f541b87405c9a54819b18ebe529f6419/events.json +194 -0
  112. data/gems/e11y-devtools/frontend/scripts/generate_mocks.rb +397 -0
  113. data/gems/e11y-devtools/frontend/src/App.svelte +827 -0
  114. data/gems/e11y-devtools/frontend/src/components/Fab.svelte +19 -0
  115. data/gems/e11y-devtools/frontend/src/components/FilterBar.svelte +38 -0
  116. data/gems/e11y-devtools/frontend/src/components/FullscreenPanel.svelte +82 -0
  117. data/gems/e11y-devtools/frontend/src/components/InteractionsTimeline.svelte +264 -0
  118. data/gems/e11y-devtools/frontend/src/components/RecentHistogram.svelte +354 -0
  119. data/gems/e11y-devtools/frontend/src/lib/api.ts +37 -0
  120. data/gems/e11y-devtools/frontend/src/lib/eventIdentity.ts +12 -0
  121. data/gems/e11y-devtools/frontend/src/lib/format.ts +37 -0
  122. data/gems/e11y-devtools/frontend/src/lib/listFilter.ts +43 -0
  123. data/gems/e11y-devtools/frontend/src/lib/recentVolume.ts +80 -0
  124. data/gems/e11y-devtools/frontend/src/lib/router.ts +12 -0
  125. data/gems/e11y-devtools/frontend/src/lib/transitions.ts +34 -0
  126. data/gems/e11y-devtools/frontend/src/lib/viewportOrigin.ts +25 -0
  127. data/gems/e11y-devtools/frontend/src/main.ts +8 -0
  128. data/gems/e11y-devtools/frontend/src/overlay-entry.ts +24 -0
  129. data/gems/e11y-devtools/frontend/src/overlay.css +1080 -0
  130. data/gems/e11y-devtools/frontend/svelte.config.js +2 -0
  131. data/gems/e11y-devtools/frontend/test_puppeteer.js +41 -0
  132. data/gems/e11y-devtools/frontend/test_scale.js +3 -0
  133. data/gems/e11y-devtools/frontend/tsconfig.app.json +21 -0
  134. data/gems/e11y-devtools/frontend/tsconfig.json +7 -0
  135. data/gems/e11y-devtools/frontend/tsconfig.node.json +26 -0
  136. data/gems/e11y-devtools/frontend/vite.config.ts +36 -0
  137. data/gems/e11y-devtools/lib/e11y/devtools/mcp/server.rb +96 -0
  138. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tool_base.rb +25 -0
  139. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/clear.rb +31 -0
  140. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/errors.rb +35 -0
  141. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/event_detail.rb +33 -0
  142. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/events_by_trace.rb +33 -0
  143. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/interactions.rb +40 -0
  144. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/recent_events.rb +34 -0
  145. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/search.rb +34 -0
  146. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/stats.rb +30 -0
  147. data/gems/e11y-devtools/lib/e11y/devtools/overlay/assets/overlay.js +20 -0
  148. data/gems/e11y-devtools/lib/e11y/devtools/overlay/controller.rb +94 -0
  149. data/gems/e11y-devtools/lib/e11y/devtools/overlay/engine.rb +26 -0
  150. data/gems/e11y-devtools/lib/e11y/devtools/overlay/middleware.rb +80 -0
  151. data/gems/e11y-devtools/lib/e11y/devtools/overlay/rails_controller.rb +67 -0
  152. data/gems/e11y-devtools/lib/e11y/devtools/tui/app.rb +262 -0
  153. data/gems/e11y-devtools/lib/e11y/devtools/tui/grouping.rb +66 -0
  154. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_detail.rb +62 -0
  155. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_list.rb +70 -0
  156. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/interaction_list.rb +47 -0
  157. data/gems/e11y-devtools/lib/e11y/devtools/version.rb +8 -0
  158. data/gems/e11y-devtools/lib/e11y/devtools.rb +13 -0
  159. data/gems/e11y-devtools/spec/e11y/devtools/mcp/tools_spec.rb +107 -0
  160. data/gems/e11y-devtools/spec/e11y/devtools/overlay/controller_spec.rb +91 -0
  161. data/gems/e11y-devtools/spec/e11y/devtools/overlay/middleware_spec.rb +46 -0
  162. data/gems/e11y-devtools/spec/e11y/devtools/tui/app_spec.rb +85 -0
  163. data/gems/e11y-devtools/spec/e11y/devtools/tui/grouping_spec.rb +64 -0
  164. data/gems/e11y-devtools/spec/spec_helper.rb +5 -0
  165. data/gems/e11y-devtools/spec/tui/widgets/event_list_spec.rb +44 -0
  166. data/gems/e11y-devtools/spec/tui/widgets/interaction_list_spec.rb +62 -0
  167. data/lib/e11y/adapters/audit_encrypted.rb +53 -11
  168. data/lib/e11y/adapters/base.rb +33 -34
  169. data/lib/e11y/adapters/dev_log/file_store.rb +143 -0
  170. data/lib/e11y/adapters/dev_log/query.rb +219 -0
  171. data/lib/e11y/adapters/dev_log.rb +118 -0
  172. data/lib/e11y/adapters/file.rb +3 -6
  173. data/lib/e11y/adapters/in_memory.rb +52 -5
  174. data/lib/e11y/adapters/in_memory_test.rb +29 -0
  175. data/lib/e11y/adapters/loki.rb +58 -23
  176. data/lib/e11y/adapters/null.rb +82 -0
  177. data/lib/e11y/adapters/opentelemetry_collector.rb +183 -0
  178. data/lib/e11y/adapters/otel_logs.rb +136 -23
  179. data/lib/e11y/adapters/sentry.rb +4 -7
  180. data/lib/e11y/adapters/stdout.rb +73 -7
  181. data/lib/e11y/adapters/yabeda.rb +153 -29
  182. data/lib/e11y/buffers/adaptive_buffer.rb +3 -17
  183. data/lib/e11y/buffers/{request_scoped_buffer.rb → ephemeral_buffer.rb} +72 -58
  184. data/lib/e11y/buffers/ring_buffer.rb +3 -16
  185. data/lib/e11y/configuration.rb +272 -0
  186. data/lib/e11y/console.rb +10 -17
  187. data/lib/e11y/current.rb +53 -1
  188. data/lib/e11y/debug/pipeline_inspector.rb +96 -0
  189. data/lib/e11y/documentation/generator.rb +48 -0
  190. data/lib/e11y/event/base.rb +176 -82
  191. data/lib/e11y/event/value_sampling_config.rb +1 -5
  192. data/lib/e11y/events/rails/database/query.rb +1 -4
  193. data/lib/e11y/events/rails/job/failed.rb +2 -0
  194. data/lib/e11y/instruments/active_job.rb +44 -12
  195. data/lib/e11y/instruments/rails_instrumentation.rb +49 -24
  196. data/lib/e11y/instruments/sidekiq.rb +135 -31
  197. data/lib/e11y/linters/base.rb +11 -0
  198. data/lib/e11y/linters/pii/pii_declaration_linter.rb +120 -0
  199. data/lib/e11y/linters/slo/config_consistency_linter.rb +76 -0
  200. data/lib/e11y/linters/slo/explicit_declaration_linter.rb +36 -0
  201. data/lib/e11y/linters/slo/slo_status_from_linter.rb +41 -0
  202. data/lib/e11y/logger/bridge.rb +26 -7
  203. data/lib/e11y/metrics/cardinality_protection.rb +10 -15
  204. data/lib/e11y/metrics/cardinality_tracker.rb +16 -6
  205. data/lib/e11y/metrics/registry.rb +3 -5
  206. data/lib/e11y/metrics/test_backend.rb +62 -0
  207. data/lib/e11y/metrics.rb +56 -10
  208. data/lib/e11y/middleware/adapter_resolver.rb +40 -0
  209. data/lib/e11y/middleware/audit_signing.rb +43 -6
  210. data/lib/e11y/middleware/baggage_protection.rb +75 -0
  211. data/lib/e11y/middleware/dev_log_source.rb +24 -0
  212. data/lib/e11y/middleware/event_slo.rb +23 -9
  213. data/lib/e11y/middleware/otel_span.rb +23 -0
  214. data/lib/e11y/middleware/pii_filter.rb +104 -75
  215. data/lib/e11y/middleware/rate_limiting.rb +54 -27
  216. data/lib/e11y/middleware/request.rb +70 -23
  217. data/lib/e11y/middleware/routing.rb +78 -21
  218. data/lib/e11y/middleware/sampling.rb +66 -17
  219. data/lib/e11y/middleware/self_monitoring_emit.rb +39 -0
  220. data/lib/e11y/middleware/trace_context.rb +45 -10
  221. data/lib/e11y/middleware/track_latency.rb +34 -0
  222. data/lib/e11y/middleware/validation.rb +7 -16
  223. data/lib/e11y/middleware/versioning.rb +26 -22
  224. data/lib/e11y/opentelemetry/semantic_conventions.rb +109 -0
  225. data/lib/e11y/opentelemetry/span_creator.rb +142 -0
  226. data/lib/e11y/pii/patterns.rb +12 -1
  227. data/lib/e11y/pipeline/builder.rb +4 -4
  228. data/lib/e11y/presets/audit_event.rb +13 -2
  229. data/lib/e11y/railtie.rb +52 -14
  230. data/lib/e11y/registry.rb +306 -0
  231. data/lib/e11y/reliability/circuit_breaker.rb +19 -21
  232. data/lib/e11y/reliability/dlq/base.rb +71 -0
  233. data/lib/e11y/reliability/dlq/file_adapter.rb +301 -0
  234. data/lib/e11y/reliability/dlq/file_storage.rb +63 -34
  235. data/lib/e11y/reliability/dlq/filter.rb +37 -54
  236. data/lib/e11y/reliability/retry_handler.rb +26 -29
  237. data/lib/e11y/reliability/retry_rate_limiter.rb +3 -11
  238. data/lib/e11y/sampling/error_spike_detector.rb +0 -2
  239. data/lib/e11y/sampling/load_monitor.rb +5 -9
  240. data/lib/e11y/sampling/stratified_tracker.rb +18 -0
  241. data/lib/e11y/self_monitoring/buffer_monitor.rb +2 -0
  242. data/lib/e11y/self_monitoring/performance_monitor.rb +19 -61
  243. data/lib/e11y/self_monitoring/reliability_monitor.rb +4 -74
  244. data/lib/e11y/slo/config_loader.rb +40 -0
  245. data/lib/e11y/slo/config_validator.rb +58 -0
  246. data/lib/e11y/slo/dashboard_generator.rb +122 -0
  247. data/lib/e11y/slo/event_driven.rb +8 -0
  248. data/lib/e11y/slo/tracker.rb +31 -4
  249. data/lib/e11y/testing/have_tracked_event_matcher.rb +190 -0
  250. data/lib/e11y/testing/rspec_matchers.rb +21 -0
  251. data/lib/e11y/testing/snapshot_matcher.rb +86 -0
  252. data/lib/e11y/trace_context/sampler.rb +35 -0
  253. data/lib/e11y/tracing/faraday_middleware.rb +31 -0
  254. data/lib/e11y/tracing/net_http_patch.rb +33 -0
  255. data/lib/e11y/tracing/propagator.rb +144 -0
  256. data/lib/e11y/tracing.rb +47 -0
  257. data/lib/e11y/version.rb +1 -1
  258. data/lib/e11y/versioning/version_extractor.rb +32 -0
  259. data/lib/e11y.rb +123 -266
  260. data/lib/generators/e11y/event/event_generator.rb +22 -0
  261. data/lib/generators/e11y/event/templates/event.rb.tt +16 -0
  262. data/lib/generators/e11y/grafana_dashboard/grafana_dashboard_generator.rb +30 -0
  263. data/lib/generators/e11y/grafana_dashboard/templates/e11y_dashboard.json +81 -0
  264. data/lib/generators/e11y/install/install_generator.rb +34 -0
  265. data/lib/generators/e11y/install/templates/e11y.rb +239 -0
  266. data/lib/generators/e11y/prometheus_alerts/prometheus_alerts_generator.rb +29 -0
  267. data/lib/generators/e11y/prometheus_alerts/templates/e11y_alerts.yml +28 -0
  268. data/lib/tasks/e11y_docs.rake +30 -0
  269. data/lib/tasks/e11y_events.rake +71 -0
  270. data/lib/tasks/e11y_lint.rake +91 -0
  271. data/lib/tasks/e11y_slo.rake +29 -0
  272. metadata +186 -39
  273. data/docs/ADR-003-slo-observability.md +0 -3337
  274. data/docs/ADR-010-developer-experience.md +0 -2166
  275. data/docs/API-REFERENCE-L28.md +0 -914
  276. data/docs/COMPREHENSIVE-CONFIGURATION.md +0 -2366
  277. data/docs/CONTRIBUTING.md +0 -312
  278. data/docs/IMPLEMENTATION_NOTES.md +0 -2804
  279. data/docs/IMPLEMENTATION_PLAN.md +0 -1971
  280. data/docs/IMPLEMENTATION_PLAN_ARCHITECTURE.md +0 -586
  281. data/docs/PLAN.md +0 -148
  282. data/docs/README.md +0 -296
  283. data/docs/design/00-memory-optimization.md +0 -593
  284. data/docs/guides/MIGRATION-L27-L28.md +0 -692
  285. data/docs/guides/PERFORMANCE-BENCHMARKS.md +0 -434
  286. data/docs/guides/README.md +0 -44
  287. data/docs/use_cases/UC-003-pattern-based-metrics.md +0 -1627
  288. 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
- # Register Sentry adapter
83
- E11y::Adapters::Registry.register(
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
- # Register adapter
703
- E11y::Adapters::Registry.register(
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 - PRESERVED!)
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"} → Shows COMPLETE request timeline across services
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/integrations/sidekiq.rb (built-in)
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 Integrations
117
- class SidekiqMiddleware
118
- def call(worker, job, queue)
119
- # Extract trace_id from job payload
120
- trace_id = job['trace_id']
121
-
122
- # Set thread-local trace_id
123
- E11y::TraceId.with_trace_id(trace_id) do
124
- yield # Execute job
125
- end
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 (trace_id automatically passed)
154
+ # Enqueue job (C17: parent_trace_id + e11y_sampled propagated)
153
155
  SendOrderConfirmationJob.perform_later(order.id)
154
- # → Job payload includes: { 'trace_id' => 'abc-123' }
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 - PRESERVED!)
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 is automatically restored!
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 = 'abc-123' (same as original request!)
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 = 'abc-123' (still same!)
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 [abc-123] email.sending (job, 3 seconds later)
180
- # 10:00:03.200 [abc-123] email.sent (job)
181
- # → Complete trace across HTTP request + background job!
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 (Configuration Duplication):**
16
+ **Current Approach (Manual per-event):**
15
17
  ```ruby
16
- # config/application.rb
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
- # - Configuration duplication
30
- # - Easy to forget updating both places
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. Extended Configuration (Optional)
84
+ ### 2. Event-Level DSL + Inheritance
96
85
 
97
- **Add more filters beyond Rails:**
86
+ **Define per-event; use inheritance for shared rules:**
98
87
  ```ruby
99
- # config/initializers/e11y.rb
100
- E11y.configure do |config|
101
- config.pii_filter do
102
- # 1. USE RAILS FILTERS (default: true)
103
- use_rails_filter_parameters true
104
-
105
- # 2. ADD MORE FIELDS (Rails-compatible syntax)
106
- filter_parameters :api_key, :token, :auth_token, :secret_key
107
-
108
- # 3. REGEX FILTERS (like Rails)
109
- filter_parameters /token/i # Matches: auth_token, api_token, etc.
110
- filter_parameters /secret/i # Matches: client_secret, api_secret, etc.
111
-
112
- # 4. WHITELIST (don't filter these, even if in Rails.filter_parameters)
113
- allow_parameters :user_id, :order_id, :transaction_id
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
- **Advanced regex patterns for content scanning:**
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 (Tier 1 - Skip Filtering)**
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
- # - Tier 1 filtering (0ms overhead)
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 (Tier 2 - Rails Filters Only)**
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 → Tier 2 (Rails filters applied)
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 (Tier 3 - Deep Filtering)**
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 **Tier 2** (Rails filters only):
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
- # → Tier 2: Rails filters applied automatically
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