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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c2fbfb3af2fb95f263bbd3e7068b9096bb3fda318142963d90367e0feabfb9d
4
- data.tar.gz: 433928d7153ffce185577c99d82a31a63a25f0720b7c2ea7c27a306425c8abce
3
+ metadata.gz: 4cf2b7d2a17ee4e2474c6a286fe16e1c6dc3f3f6c62c687c21e6e19ff2326cff
4
+ data.tar.gz: cf70471e2647774b1ca4fa34c54cb731eed9adee5a6fb4e3b45203030a0c2843
5
5
  SHA512:
6
- metadata.gz: 9119ba005f1b8be835aa331e50ecf0ab9c52c8dd13e14c2b9bdfa9f5af3c4341937a9c9f1b7c30b8d43c31b7287d1632221e67c82380b882c770a94af7cf2bbf
7
- data.tar.gz: c29c35fffbc7c959cc56e1774338c8717cde744c677d38c98bd308cf96487a8ebe2a57690e82808afec347b5f48497e4ea0536e9067b413c3fa39776f655f266
6
+ metadata.gz: f06a9a21e21cf3c287a0e5b271d15bbd1d8d453bf1168e9a1ef5a37eb3f1390f627b14801a02c668e6ae063ba12bcaf5854ba76ce4288ec4050b2a2e6eea18f1
7
+ data.tar.gz: c862108b20fc6c9da7ec1672baeb037dbbc4ac10fa06d713c8306c0ca1fd58c2e4bafec2b7a935fee2afc6bf7a1bd6741fb3a386b87edd024fa3c91e521c017d
data/.rubocop.yml CHANGED
@@ -3,14 +3,10 @@
3
3
  # See https://rubystyle.guide/ for Ruby style guide
4
4
  # See https://docs.rubocop.org/rubocop/ for all available cops
5
5
 
6
- require:
7
- - rubocop-rspec
8
- - rubocop-rspec_rails
9
-
10
6
  plugins:
11
- - rubocop-capybara
12
- - rubocop-factory_bot
13
7
  - rubocop-performance
8
+ - rubocop-rspec
9
+ - rubocop-rspec_rails
14
10
 
15
11
  AllCops:
16
12
  TargetRubyVersion: 3.2
@@ -28,17 +24,82 @@ Metrics/BlockLength:
28
24
  Exclude:
29
25
  - 'spec/**/*'
30
26
  - 'Rakefile'
27
+ - 'lib/tasks/**/*'
31
28
  - '*.gemspec'
29
+ - 'lib/e11y/reliability/retry_handler.rb'
30
+ - 'lib/e11y/instruments/active_job.rb'
32
31
 
33
32
  Metrics/MethodLength:
34
- Max: 15
33
+ Max: 20
35
34
  Exclude:
36
35
  - 'spec/**/*'
36
+ - 'lib/e11y/adapters/yabeda.rb'
37
+ - 'lib/e11y/middleware/routing.rb'
38
+ - 'lib/e11y/event/base.rb'
39
+ - 'lib/e11y/middleware/rate_limiting.rb'
40
+ - 'lib/e11y/middleware/sampling.rb'
37
41
 
38
42
  Metrics/ClassLength:
39
43
  Max: 100
40
44
  Exclude:
41
45
  - 'spec/**/*'
46
+ - 'lib/e11y/buffers/ephemeral_buffer.rb'
47
+ - 'lib/e11y/registry.rb'
48
+ - 'lib/e11y/adapters/otel_logs.rb'
49
+ - 'lib/e11y/adapters/opentelemetry_collector.rb'
50
+ - 'lib/e11y/opentelemetry/span_creator.rb'
51
+ - 'lib/e11y/configuration.rb'
52
+
53
+ Metrics/CyclomaticComplexity:
54
+ Max: 15
55
+ Exclude:
56
+ - 'lib/e11y/adapters/yabeda.rb'
57
+ - 'lib/e11y/middleware/event_slo.rb'
58
+ - 'lib/e11y/middleware/routing.rb'
59
+ - 'spec/integration/pattern_metrics_integration_spec.rb'
60
+ - 'spec/integration/slo_tracking_integration_spec.rb'
61
+ - 'spec/support/integration_helpers.rb'
62
+ - 'spec/support/integration/pii_helpers.rb'
63
+ - 'spec/support/loki_helpers.rb'
64
+ - 'spec/support/matchers/pii_matchers.rb'
65
+
66
+ Metrics/AbcSize:
67
+ Max: 20
68
+ Exclude:
69
+ - 'lib/e11y/middleware/event_slo.rb'
70
+ - 'lib/e11y/middleware/routing.rb'
71
+ - 'lib/e11y/adapters/yabeda.rb'
72
+ - 'lib/e11y/event/base.rb'
73
+ - 'lib/e11y/middleware/versioning.rb'
74
+ - 'lib/e11y/reliability/retry_handler.rb'
75
+ - 'lib/e11y/adapters/base.rb'
76
+ - 'lib/e11y/adapters/opentelemetry_collector.rb'
77
+ - 'lib/e11y/adapters/otel_logs.rb'
78
+ - 'lib/e11y/current.rb'
79
+ - 'lib/e11y/instruments/active_job.rb'
80
+ - 'lib/e11y/instruments/sidekiq.rb'
81
+ - 'lib/e11y/linters/pii/pii_declaration_linter.rb'
82
+ - 'lib/e11y/linters/slo/config_consistency_linter.rb'
83
+ - 'lib/e11y/logger/bridge.rb'
84
+ - 'lib/e11y/middleware/pii_filter.rb'
85
+ - 'lib/e11y/middleware/rate_limiting.rb'
86
+ - 'lib/e11y/middleware/sampling.rb'
87
+ - 'lib/e11y/opentelemetry/span_creator.rb'
88
+ - 'spec/integration/slo_tracking_integration_spec.rb'
89
+ - 'spec/support/integration_helpers.rb'
90
+ - 'spec/support/integration/pii_helpers.rb'
91
+ - 'spec/support/loki_helpers.rb'
92
+ - 'spec/support/matchers/pii_matchers.rb'
93
+
94
+ Metrics/PerceivedComplexity:
95
+ Max: 15
96
+ Exclude:
97
+ - 'lib/e11y/middleware/event_slo.rb'
98
+ - 'spec/integration/slo_tracking_integration_spec.rb'
99
+ - 'spec/support/integration_helpers.rb'
100
+ - 'spec/support/integration/pii_helpers.rb'
101
+ - 'spec/support/loki_helpers.rb'
102
+ - 'spec/support/matchers/pii_matchers.rb'
42
103
 
43
104
  # Style
44
105
  Style/Documentation:
@@ -52,9 +113,15 @@ Style/StringLiterals:
52
113
  Style/FrozenStringLiteralComment:
53
114
  Enabled: true
54
115
 
116
+ # Layout
117
+ Layout/LineLength:
118
+ Max: 150
119
+
55
120
  # RSpec
56
121
  RSpec/ExampleLength:
57
- Max: 20 # Allow longer examples for integration tests
122
+ Max: 40 # Allow longer examples for integration tests
123
+ Exclude:
124
+ - "spec/integration/**/*"
58
125
 
59
126
  RSpec/MultipleExpectations:
60
127
  Max: 10 # Allow more expectations for integration tests
@@ -64,16 +131,43 @@ RSpec/MultipleMemoizedHelpers:
64
131
 
65
132
  RSpec/NestedGroups:
66
133
  Max: 3
134
+ Exclude:
135
+ - "spec/e11y/current_spec.rb"
136
+ - "spec/e11y/middleware/pii_filtering_spec.rb"
67
137
 
68
138
  # Gem-specific: Development dependencies can be in gemspec
69
139
  Gemspec/DevelopmentDependencies:
70
140
  Enabled: false
71
141
 
142
+ Style/OneClassPerFile:
143
+ Exclude:
144
+ - "spec/dummy/config/application.rb"
145
+ - "spec/support/pipeline_debug.rb"
146
+
72
147
  # Allow integration tests without specific class
73
148
  RSpec/DescribeClass:
74
149
  Exclude:
75
150
  - "spec/zeitwerk_spec.rb"
76
151
  - "spec/integration/**/*"
152
+ - "spec/e11y/module_api_spec.rb"
153
+ - "spec/e11y/configuration/error_handling_config_spec.rb"
154
+
155
+ # File path conventions (generators use spec/generators/e11y/ structure)
156
+ RSpec/SpecFilePathFormat:
157
+ Exclude:
158
+ - "spec/e11y/event/dsl_additions_spec.rb"
159
+ - "spec/e11y/module_api_spec.rb"
160
+ - "spec/generators/e11y/*_spec.rb"
161
+ - "spec/e11y/opentelemetry/semantic_conventions_spec.rb"
162
+ - "spec/e11y/opentelemetry/span_creator_spec.rb"
163
+
164
+ RSpec/DescribeMethod:
165
+ Exclude:
166
+ - "spec/e11y/module_api_spec.rb"
167
+
168
+ RSpec/MultipleDescribes:
169
+ Exclude:
170
+ - "spec/e11y/adapters/null_adapter_spec.rb"
77
171
 
78
172
  # Allow simple doubles for now (will improve in Phase 1)
79
173
  RSpec/VerifiedDoubles:
@@ -85,5 +179,31 @@ RSpec/VerifiedDoubles:
85
179
  RSpec/MessageSpies:
86
180
  Enabled: false
87
181
 
88
- Capybara/RSpec/PredicateMatcher:
89
- Enabled: false
182
+ # RSpec/Output: New cop in rubocop-rspec 3.x flagging puts in specs.
183
+ # We use puts for diagnostic output in integration tests and support files.
184
+ RSpec/Output:
185
+ Enabled: false
186
+
187
+ RSpec/RepeatedExample:
188
+ Exclude:
189
+ - "spec/e11y/instruments/rails_instrumentation_spec.rb"
190
+ - "spec/e11y/versioning/version_extractor_spec.rb"
191
+
192
+ RSpec/StubbedMock:
193
+ Exclude:
194
+ - "spec/e11y/module_api_spec.rb"
195
+ - "spec/e11y/slo/config_loader_spec.rb"
196
+
197
+ Metrics/ParameterLists:
198
+ Exclude:
199
+ - "lib/e11y/adapters/opentelemetry_collector.rb"
200
+ - "lib/e11y/adapters/otel_logs.rb"
201
+
202
+ Style/SafeNavigationChainLength:
203
+ Exclude:
204
+ - "lib/e11y/linters/pii/pii_declaration_linter.rb"
205
+
206
+ Performance/CollectionLiteralInLoop:
207
+ Exclude:
208
+ - "lib/e11y/middleware/pii_filter.rb"
209
+
data/CHANGELOG.md CHANGED
@@ -19,6 +19,85 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
19
19
 
20
20
  ### Security
21
21
 
22
+ ## [1.1.0] - 2026-03-23
23
+
24
+ ### Added
25
+
26
+ - Sidekiq and Active Job: propagate **`user_id`** into **`e11y_baggage`** (and restore **`E11y::Current.user_id`** when the job runs). Key **`user_id`** is included in default baggage allowlist.
27
+
28
+ ### Changed
29
+
30
+ ### Fixed
31
+
32
+ - **Rails Railtie:** `config.enabled` is defaulted with `!Rails.env.test?` **only when still `nil`**, so an explicit `true`/`false` from `E11y.configure` in `config/application.rb` (or any code that runs before `before_initialize`) is no longer overwritten.
33
+
34
+ ### Deprecated
35
+
36
+ ### Removed
37
+
38
+ - **`E11y.track`** — removed. Call **`YourEvent.track(...)`** on the event class only.
39
+
40
+ ### Security
41
+
42
+ ## [1.0.0] - 2026-03-20
43
+
44
+ ### BREAKING: Configuration — Flat config API
45
+
46
+ **Nested config objects removed.** All configuration options are now flat accessors on `config`.
47
+
48
+ **Key migrations:**
49
+ - `config.rails_instrumentation.enabled` → `config.rails_instrumentation_enabled`
50
+ - `config.logger_bridge.track_severities` → `config.logger_bridge_track_severities`
51
+ - `config.rate_limiting { }` removed → use `config.rate_limiting_enabled`, `config.add_rate_limit_per_event(...)`
52
+ - `config.slo { }` removed → use `config.slo_tracking_enabled`, `config.add_slo_controller(...)`
53
+
54
+ **Full mapping:** See `docs/plans/2026-03-13-configuration-design.md`
55
+
56
+ ### BREAKING: Middleware order changed (ADR-015 compliance)
57
+
58
+ **Per ADR-015 and ADR-006:**
59
+ - **Versioning** moved to last (before Routing) — Validation, PII, RateLimiting, Sampling now use original class names
60
+ - **AuditSigning** before PIIFilter — audit events signed with original data (GDPR Art. 30 non-repudiation)
61
+ - **RateLimiting** before Sampling — matches ADR #4, #5
62
+
63
+ **New order:** TraceContext → Validation → AuditSigning → PIIFilter → RateLimiting → Sampling → Versioning → Routing → EventSlo
64
+
65
+ **Migration:** If you custom-configured pipeline order, ensure Versioning is last before Routing. Audit events now receive unfiltered payload at signing.
66
+
67
+ ### BREAKING: Registry.all_events → Registry.event_classes
68
+
69
+ **Renamed for clarity:** Method returns event classes, not event instances or names.
70
+
71
+ **Migration:** `E11y::Registry.all_events` → `E11y::Registry.event_classes`
72
+
73
+ ### BREAKING: RequestScopedBuffer → EphemeralBuffer
74
+
75
+ **Renamed for accuracy:** The buffer works for both HTTP requests and background jobs. "Ephemeral" reflects its temporary lifecycle.
76
+
77
+ **Migration:**
78
+ - `E11y::Buffers::RequestScopedBuffer` → `E11y::Buffers::EphemeralBuffer`
79
+ - `config.request_buffer` → `config.ephemeral_buffer`
80
+ - `Thread.current[:e11y_request_buffer]` → `Thread.current[:e11y_ephemeral_buffer]`
81
+ - Yabeda metric `e11y_request_buffer_total` → `e11y_ephemeral_buffer_total`
82
+
83
+ **Search and replace:** `RequestScopedBuffer` → `EphemeralBuffer`, `request_buffer` → `ephemeral_buffer`
84
+
85
+ ### Added
86
+
87
+ - Monorepo release tooling: `rake release:build_gems` and `rake release:gem_push` build/publish **e11y** and **e11y-devtools**; optional `release:rubygems:push_core` / `push_devtools`; GitHub Release workflow attaches both `.gem` files.
88
+
89
+ ### Changed
90
+
91
+ - **e11y-devtools** 0.1.1 — depends on **e11y** `~> 1.0` (`CORE_VERSION`); README Gemfile example updated.
92
+
93
+ ### Fixed
94
+
95
+ ### Deprecated
96
+
97
+ ### Removed
98
+
99
+ ### Security
100
+
22
101
  ## [0.2.0] - 2026-01-26
23
102
 
24
103
  ### Added
@@ -135,7 +214,7 @@ Initial release of E11y - Event-driven observability for Rails applications.
135
214
  - Audit log (encrypted storage)
136
215
 
137
216
  - **Advanced Features**
138
- - Pattern-based metrics extraction
217
+ - Event-level metrics (metrics DSL)
139
218
  - PII filtering with configurable rules
140
219
  - Stratified sampling
141
220
  - Rate limiting
data/CLAUDE.md ADDED
@@ -0,0 +1,168 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ E11y ("easy telemetry") is a Ruby gem providing observability for Rails apps. Its key differentiator is **request-scoped debug buffering**: debug logs accumulate in memory during a request and flush to storage only if the request fails, cutting noise by ~90%.
8
+
9
+ - **Ruby**: 3.2+, **Rails**: 7.0–8.0 (8.1 excluded due to a sqlite3 bug)
10
+ - **Gem version**: 0.2.0, current branch: `feat/integration-testing`
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ # Run all tests
16
+ rake spec:all
17
+
18
+ # Run unit tests only (fast, no Rails required)
19
+ rake spec:unit
20
+
21
+ # Run integration tests (requires --with integration bundle group)
22
+ rake spec:integration
23
+
24
+ # Integration tests for Loki/OTel adapters require services — start with docker compose:
25
+ docker compose up -d loki otel-collector
26
+ INTEGRATION=true bundle exec rspec spec/integration/critical_adapters_integration_spec.rb
27
+
28
+ # Run a single spec file
29
+ bundle exec rspec spec/e11y/adapters/loki_adapter_spec.rb
30
+
31
+ # Run a single example by line number
32
+ bundle exec rspec spec/e11y/adapters/loki_adapter_spec.rb:42
33
+
34
+ # Lint
35
+ bundle exec rubocop
36
+
37
+ # Lint with autocorrect
38
+ bundle exec rubocop -a
39
+
40
+ # Install integration dependencies (needed before rake spec:integration)
41
+ bundle install --with integration
42
+
43
+ # Open a console with the gem loaded
44
+ rake console
45
+
46
+ # Run benchmarks
47
+ rake spec:benchmark
48
+
49
+ # Run Cucumber acceptance tests
50
+ rake cucumber
51
+ # Or: bundle exec cucumber features/
52
+
53
+ # Cucumber with Loki (adapter_configurations.feature): start Loki + OTel first
54
+ docker compose up -d loki otel-collector
55
+ rake cucumber
56
+
57
+ # Run TUI (interactive log viewer)
58
+ bundle exec e11y
59
+
60
+ # Start MCP server (for Cursor / Claude Code)
61
+ bundle exec e11y mcp
62
+
63
+ # Stream events to stdout
64
+ bundle exec e11y tail
65
+ ```
66
+
67
+ ## Architecture
68
+
69
+ ### Event Processing Pipeline
70
+
71
+ Every event flows through a middleware pipeline before reaching an adapter:
72
+
73
+ ```
74
+ Event.track(data)
75
+ → Validation (dry-schema)
76
+ → Sampling (adaptive: error-spike, load, value-based)
77
+ → PII Filtering (mask/hash sensitive fields)
78
+ → Trace Context (attach OTel span/trace IDs)
79
+ → Routing (direct to adapters by severity/type)
80
+ → Rate Limiting
81
+ → Audit Signing
82
+ → Adapter(s): Loki | Sentry | OpenTelemetry | Yabeda | File | Stdout | InMemory
83
+ ```
84
+
85
+ Pipeline is built in `lib/e11y/pipeline/builder.rb`. Middleware order matters — see ADR-015.
86
+
87
+ ### Key Modules
88
+
89
+ | Path | Role |
90
+ |------|------|
91
+ | `lib/e11y.rb` | Public API, `E11y.configure`, `E11y.configuration`, `E11y.logger` |
92
+ | `lib/e11y/event/base.rb` | Base event class; all user events inherit from this |
93
+ | `lib/e11y/adapters/` | Backend adapters (Loki, Sentry, OTel, Yabeda, File, Stdout, InMemory) |
94
+ | `lib/e11y/middleware/` | 11 pipeline stages (validation, sampling, PII, routing, etc.) |
95
+ | `lib/e11y/buffers/` | Request-scoped buffer + adaptive buffer implementations |
96
+ | `lib/e11y/pipeline/builder.rb` | Assembles middleware chain from configuration |
97
+ | `lib/e11y/railtie.rb` | Rails integration entry point |
98
+ | `lib/e11y/pii/` | PII detection patterns and masking/hashing strategies |
99
+ | `lib/e11y/sampling/` | Error-spike, load-based, value-based sampling strategies |
100
+ | `lib/e11y/reliability/` | Circuit breaker, DLQ (dead letter queue), retry logic |
101
+ | `lib/e11y/slo/` | Event-driven SLO tracking |
102
+ | `lib/e11y/metrics/` | Prometheus metrics registry with cardinality protection |
103
+ | `gems/e11y-devtools/` | Developer tools gem (TUI, Browser Overlay, MCP) — dev-only |
104
+ | `gems/e11y-devtools/lib/e11y/devtools/tui/` | ratatui_ruby TUI — interaction-centric log viewer |
105
+ | `gems/e11y-devtools/lib/e11y/devtools/overlay/` | Rails Engine — floating badge + slide-in panel |
106
+ | `gems/e11y-devtools/lib/e11y/devtools/mcp/` | MCP Server — AI integration for Cursor/Claude Code |
107
+ | `lib/e11y/adapters/dev_log.rb` | DevLog adapter — JSONL write+read, shared by all viewers |
108
+
109
+ ### Event Definition Pattern
110
+
111
+ Events are defined as classes inheriting from `E11y::Event::Base`:
112
+
113
+ ```ruby
114
+ class Events::OrderCreated < E11y::Event::Base
115
+ schema do
116
+ required(:order_id).filled(:string)
117
+ required(:amount).filled(:float)
118
+ optional(:user_id).maybe(:string)
119
+ end
120
+
121
+ metrics do
122
+ counter :orders_created_total, "Orders created"
123
+ histogram :order_amount, "Order amount in USD", buckets: [10, 50, 100, 500]
124
+ end
125
+ end
126
+
127
+ # Usage
128
+ Events::OrderCreated.track(order_id: order.id, amount: order.total)
129
+ ```
130
+
131
+ ### Adapter Routing
132
+
133
+ Adapters are registered in configuration and events route to them by severity:
134
+ - `error`/`fatal` → errors tracker (e.g., Sentry)
135
+ - other severities → logs (e.g., Loki)
136
+ - metrics always → Yabeda/Prometheus
137
+
138
+ ### Request-Scoped Buffering
139
+
140
+ The buffer middleware captures debug-level events in a `Concurrent::Array` per request (stored in `Thread.current`). On request success: buffer discarded. On request failure: buffer flushed to configured adapters. Controlled by `config.ephemeral_buffer_enabled`.
141
+
142
+ ## Test Structure
143
+
144
+ - `spec/e11y/` — Unit tests (86 files, ~1672 examples, fast)
145
+ - `spec/integration/` — Integration tests against a real Rails app (~36 examples)
146
+ - `spec/dummy/` — Minimal Rails app used by integration tests
147
+ - `spec/dummy/app/events/events/` — Event class definitions for test fixtures
148
+ - `spec/support/matchers/` — Custom RSpec matchers including PII matchers
149
+ - `spec/fixtures/pii_samples.yml` — PII test data
150
+
151
+ Integration tests use `DatabaseCleaner` and require `--with integration` bundle group.
152
+
153
+ ## Code Conventions
154
+
155
+ - Frozen string literals everywhere (`# frozen_string_literal: true`)
156
+ - Double-quoted strings (enforced by RuboCop)
157
+ - Events use class-level `.track` (not instantiation) — zero-allocation design; data stored in plain Hashes
158
+ - Adapters inherit from `E11y::Adapters::Base` and implement `#deliver(event_data)`
159
+ - Middleware inherits from `E11y::Middleware::Base` and implements `#call(event, pipeline)`
160
+
161
+ ## Architecture Decision Records
162
+
163
+ The `docs/architecture/ADR-*.md` files document design decisions. Key ones:
164
+ - **ADR-004**: Adapter architecture
165
+ - **ADR-011**: Testing strategy
166
+ - **ADR-013**: Reliability and error handling
167
+ - **ADR-015**: Middleware ordering (critical — changing order breaks the pipeline)
168
+ - **ADR-017**: Multi-Rails compatibility approach