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
|
@@ -251,8 +251,6 @@
|
|
|
251
251
|
10. [Trade-offs](#10-trade-offs)
|
|
252
252
|
11. [Complete Configuration Example](#11-complete-configuration-example)
|
|
253
253
|
12. [Backlog (Future Enhancements)](#12-backlog-future-enhancements)
|
|
254
|
-
- [12.1. Quick Start Presets](#121-quick-start-presets)
|
|
255
|
-
- [12.2. Sampling Budget](#122-sampling-budget)
|
|
256
254
|
|
|
257
255
|
---
|
|
258
256
|
|
|
@@ -341,13 +339,13 @@ C4Context
|
|
|
341
339
|
|
|
342
340
|
System_Ext(loki, "Loki", "$10K/year")
|
|
343
341
|
System_Ext(sentry, "Sentry", "$3.6K/year")
|
|
344
|
-
System_Ext(
|
|
342
|
+
System_Ext(archive, "Archive", "$100/year")
|
|
345
343
|
|
|
346
344
|
Rel(dev, e11y, "Configures", "Sampling rules")
|
|
347
345
|
Rel(rails_app, e11y, "Tracks events", "100% volume")
|
|
348
346
|
Rel(e11y, loki, "20% sampled + compressed", "80% cost savings")
|
|
349
347
|
Rel(e11y, sentry, "Errors only", "50% cost savings")
|
|
350
|
-
Rel(e11y,
|
|
348
|
+
Rel(e11y, archive, "Cold storage", "Long-term archive")
|
|
351
349
|
```
|
|
352
350
|
|
|
353
351
|
### 2.2. Component Architecture
|
|
@@ -373,7 +371,7 @@ graph TB
|
|
|
373
371
|
subgraph "Smart Routing"
|
|
374
372
|
Compressor --> Router[Smart Router]
|
|
375
373
|
Router --> CriticalPath[Critical → Loki]
|
|
376
|
-
Router --> ArchivePath[Archive
|
|
374
|
+
Router --> ArchivePath[Archive]
|
|
377
375
|
Router --> DebugPath[Debug → /dev/null]
|
|
378
376
|
end
|
|
379
377
|
|
|
@@ -406,7 +404,7 @@ sequenceDiagram
|
|
|
406
404
|
participant Compress as Compressor
|
|
407
405
|
participant Router as Smart Router
|
|
408
406
|
participant Loki as Loki (Expensive)
|
|
409
|
-
participant
|
|
407
|
+
participant Archive as Archive (Cheap)
|
|
410
408
|
|
|
411
409
|
App->>Sampler: Track event (100%)
|
|
412
410
|
|
|
@@ -426,13 +424,13 @@ sequenceDiagram
|
|
|
426
424
|
alt Critical event
|
|
427
425
|
Router->>Loki: Send to Loki (2.8% of original)
|
|
428
426
|
else Archive-worthy
|
|
429
|
-
Router->>
|
|
427
|
+
Router->>Archive: Send to archive (17.2% of original)
|
|
430
428
|
end
|
|
431
429
|
else Sample decision: DROP
|
|
432
430
|
Note over Sampler: 80% dropped
|
|
433
431
|
end
|
|
434
432
|
|
|
435
|
-
Note over Loki,
|
|
433
|
+
Note over Loki,Archive: Final cost: 80% reduction
|
|
436
434
|
```
|
|
437
435
|
|
|
438
436
|
---
|
|
@@ -1562,7 +1560,7 @@ end
|
|
|
1562
1560
|
|
|
1563
1561
|
### 3.7.5. Configuration
|
|
1564
1562
|
|
|
1565
|
-
|
|
1563
|
+
**Option 1: Single simple config (recommended) 🎯**
|
|
1566
1564
|
|
|
1567
1565
|
```ruby
|
|
1568
1566
|
# config/initializers/e11y.rb
|
|
@@ -1572,38 +1570,38 @@ E11y.configure do |config|
|
|
|
1572
1570
|
# ✅ Stratified sampling - smart sampling for accurate SLO
|
|
1573
1571
|
strategy :stratified_adaptive
|
|
1574
1572
|
|
|
1575
|
-
# Cost budget (
|
|
1573
|
+
# Cost budget (as before)
|
|
1576
1574
|
cost_budget 100_000 # events/month
|
|
1577
1575
|
|
|
1578
|
-
# 🎯
|
|
1576
|
+
# 🎯 SINGLE config: sample_rate by severity (default: never drop errors!)
|
|
1579
1577
|
stratified_rates do
|
|
1580
|
-
error 1.0 # 100% - keep all errors (
|
|
1578
|
+
error 1.0 # 100% - keep all errors (critical for SLO!)
|
|
1581
1579
|
warn 0.5 # 50% - medium priority
|
|
1582
|
-
info 0.1 # 10% - low priority (
|
|
1583
|
-
debug 0.05 # 5% -
|
|
1580
|
+
info 0.1 # 10% - low priority (successful requests)
|
|
1581
|
+
debug 0.05 # 5% - very low priority
|
|
1584
1582
|
end
|
|
1585
1583
|
end
|
|
1586
1584
|
end
|
|
1587
1585
|
|
|
1588
|
-
# SLO tracking
|
|
1586
|
+
# SLO tracking with automatic correction (enabled by default!)
|
|
1589
1587
|
config.slo do
|
|
1590
1588
|
enable_sampling_correction true # ✅ Automatic correction in SLO calculations
|
|
1591
1589
|
end
|
|
1592
1590
|
end
|
|
1593
1591
|
```
|
|
1594
1592
|
|
|
1595
|
-
|
|
1596
|
-
- `error`/`fatal` severity → sample_rate **1.0** (100%,
|
|
1593
|
+
**How it works:**
|
|
1594
|
+
- `error`/`fatal` severity → sample_rate **1.0** (100%, never drop!)
|
|
1597
1595
|
- `warn` severity → sample_rate **0.5** (50%)
|
|
1598
1596
|
- `info`/`success` severity → sample_rate **0.1** (10%)
|
|
1599
1597
|
- `debug` severity → sample_rate **0.05** (5%)
|
|
1600
1598
|
|
|
1601
|
-
**SLO
|
|
1599
|
+
**SLO correction is automatic:**
|
|
1602
1600
|
```ruby
|
|
1603
|
-
#
|
|
1604
|
-
E11y::SLO.error_rate # ✅
|
|
1601
|
+
# User writes as before:
|
|
1602
|
+
E11y::SLO.error_rate # ✅ Automatically corrected!
|
|
1605
1603
|
|
|
1606
|
-
#
|
|
1604
|
+
# Internally:
|
|
1607
1605
|
observed_errors = 50
|
|
1608
1606
|
corrected_errors = observed_errors / error_sample_rate # 50 / 1.0 = 50
|
|
1609
1607
|
|
|
@@ -1616,9 +1614,9 @@ corrected_error_rate = corrected_errors / (corrected_errors + corrected_success)
|
|
|
1616
1614
|
|
|
1617
1615
|
---
|
|
1618
1616
|
|
|
1619
|
-
|
|
1617
|
+
**Option 2: Advanced config (for complex cases)**
|
|
1620
1618
|
|
|
1621
|
-
|
|
1619
|
+
If you need flexibility (e.g., different sample_rate for HTTP 4xx vs 5xx):
|
|
1622
1620
|
|
|
1623
1621
|
```ruby
|
|
1624
1622
|
E11y.configure do |config|
|
|
@@ -1627,7 +1625,7 @@ E11y.configure do |config|
|
|
|
1627
1625
|
strategy :stratified_adaptive
|
|
1628
1626
|
cost_budget 100_000
|
|
1629
1627
|
|
|
1630
|
-
#
|
|
1628
|
+
# Advanced stratification by severities + http_statuses
|
|
1631
1629
|
stratification do
|
|
1632
1630
|
stratum :critical_errors do
|
|
1633
1631
|
severities [:error, :fatal]
|
|
@@ -1638,7 +1636,7 @@ E11y.configure do |config|
|
|
|
1638
1636
|
stratum :client_errors do
|
|
1639
1637
|
severities [:warn]
|
|
1640
1638
|
http_statuses (400..499).to_a
|
|
1641
|
-
sample_rate 0.3 # 30% (
|
|
1639
|
+
sample_rate 0.3 # 30% (less than warn, since 4xx is less critical)
|
|
1642
1640
|
end
|
|
1643
1641
|
|
|
1644
1642
|
stratum :success do
|
|
@@ -2005,8 +2003,8 @@ E11y.configure do |config|
|
|
|
2005
2003
|
event[:severity] == :debug
|
|
2006
2004
|
end
|
|
2007
2005
|
|
|
2008
|
-
# Rule 3: Archive events →
|
|
2009
|
-
rule 'archive_events', adapters: [:
|
|
2006
|
+
# Rule 3: Archive events → archive adapter
|
|
2007
|
+
rule 'archive_events', adapters: [:archive] do |event|
|
|
2010
2008
|
event[:payload][:archive] == true
|
|
2011
2009
|
end
|
|
2012
2010
|
|
|
@@ -2079,7 +2077,7 @@ E11y.configure do |config|
|
|
|
2079
2077
|
# Rule 2: Long retention → cold storage
|
|
2080
2078
|
->(event) {
|
|
2081
2079
|
days = (Time.parse(event[:retention_until]) - Time.now) / 86400
|
|
2082
|
-
:
|
|
2080
|
+
:archive if days > 90
|
|
2083
2081
|
},
|
|
2084
2082
|
|
|
2085
2083
|
# Rule 3: Short retention → hot storage
|
|
@@ -2194,7 +2192,7 @@ E11y.configure do |config|
|
|
|
2194
2192
|
case days
|
|
2195
2193
|
when 0..30 then :loki # Hot storage
|
|
2196
2194
|
when 31..90 then :s3_standard # Warm storage
|
|
2197
|
-
else :
|
|
2195
|
+
else :archive # Cold storage
|
|
2198
2196
|
end
|
|
2199
2197
|
}
|
|
2200
2198
|
]
|
|
@@ -2225,7 +2223,7 @@ E11y.configure do |config|
|
|
|
2225
2223
|
# Priority 4: Retention-based routing
|
|
2226
2224
|
->(event) {
|
|
2227
2225
|
days = (Time.parse(event[:retention_until]) - Time.now) / 86400
|
|
2228
|
-
days > 90 ? :
|
|
2226
|
+
days > 90 ? :archive : :loki
|
|
2229
2227
|
}
|
|
2230
2228
|
]
|
|
2231
2229
|
end
|
|
@@ -2237,12 +2235,12 @@ end
|
|
|
2237
2235
|
|----------|----------------|----------------|---------|
|
|
2238
2236
|
| **Debug logs (7d retention)** | Loki (30d): $500/mo | stdout: $0/mo | **100%** |
|
|
2239
2237
|
| **Business events (30d)** | Loki: $100/mo | Loki: $100/mo | 0% |
|
|
2240
|
-
| **Audit (7y retention)** | Loki: $5000/mo |
|
|
2238
|
+
| **Audit (7y retention)** | Loki: $5000/mo | Cold tier: $50/mo | **99%** |
|
|
2241
2239
|
| **Total** | $5,600/mo | $150/mo | **97.3%** |
|
|
2242
2240
|
|
|
2243
2241
|
**Key Savings:**
|
|
2244
2242
|
- ✅ Debug logs → stdout (free)
|
|
2245
|
-
- ✅ Audit logs →
|
|
2243
|
+
- ✅ Audit logs → cold tier ($0.004/GB vs $0.15/GB in Loki; archival filters by `retention_until`)
|
|
2246
2244
|
- ✅ Automatic tiering → no manual intervention
|
|
2247
2245
|
|
|
2248
2246
|
### 6.7. Advantages over TieredStorage Adapter
|
|
@@ -2267,7 +2265,7 @@ limits_config:
|
|
|
2267
2265
|
retention_period: 720h # 30 days
|
|
2268
2266
|
```
|
|
2269
2267
|
|
|
2270
|
-
**
|
|
2268
|
+
**Warm tier (90 days):**
|
|
2271
2269
|
```json
|
|
2272
2270
|
{
|
|
2273
2271
|
"Rules": [{
|
|
@@ -2281,7 +2279,7 @@ limits_config:
|
|
|
2281
2279
|
}
|
|
2282
2280
|
```
|
|
2283
2281
|
|
|
2284
|
-
**
|
|
2282
|
+
**Cold tier (7 years):**
|
|
2285
2283
|
```json
|
|
2286
2284
|
{
|
|
2287
2285
|
"Rules": [{
|
|
@@ -2294,7 +2292,7 @@ limits_config:
|
|
|
2294
2292
|
}
|
|
2295
2293
|
```
|
|
2296
2294
|
|
|
2297
|
-
**Key Point:** E11y
|
|
2295
|
+
**Key Point:** E11y adds `retention_until` to events. Downstream systems (Loki, archival jobs) filter by it for tier migration. No S3 adapter in E11y — archival is external.
|
|
2298
2296
|
|
|
2299
2297
|
---
|
|
2300
2298
|
|
|
@@ -3064,32 +3062,26 @@ E11y.configure do |config|
|
|
|
3064
3062
|
end
|
|
3065
3063
|
end
|
|
3066
3064
|
|
|
3067
|
-
# Tiered storage
|
|
3068
|
-
tiered_storage do
|
|
3069
|
-
retention_rule(2555) { |e| e[:event_name].start_with?('audit.') }
|
|
3070
|
-
retention_rule(90) { |e| e[:severity] >= :error }
|
|
3071
|
-
retention_rule(7) { |e| e[:severity] == :debug }
|
|
3072
|
-
default_retention 30
|
|
3073
|
-
end
|
|
3074
|
-
|
|
3075
|
-
# Payload minimization
|
|
3076
|
-
payload_minimization do
|
|
3077
|
-
enabled true
|
|
3078
|
-
remove_nulls true
|
|
3079
|
-
truncate_strings_at 1000
|
|
3080
|
-
truncate_arrays_at 100
|
|
3081
|
-
end
|
|
3082
|
-
|
|
3083
3065
|
# Cost tracking
|
|
3084
3066
|
cost_tracking do
|
|
3085
3067
|
enabled true
|
|
3086
3068
|
adapter_costs do
|
|
3087
3069
|
loki 0.50
|
|
3088
3070
|
sentry 10.00
|
|
3089
|
-
|
|
3071
|
+
archive 0.02
|
|
3090
3072
|
end
|
|
3091
3073
|
end
|
|
3092
3074
|
end
|
|
3075
|
+
|
|
3076
|
+
# Routing by retention_until (replaces tiered_storage)
|
|
3077
|
+
config.routing_rules = [
|
|
3078
|
+
->(e) { [:audit_encrypted, :loki] if e[:event_name].to_s.start_with?('audit.') },
|
|
3079
|
+
->(e) {
|
|
3080
|
+
return nil unless e[:retention_until]
|
|
3081
|
+
days = (Time.parse(e[:retention_until]) - Time.now) / 86400
|
|
3082
|
+
days <= 7 ? :file : :loki
|
|
3083
|
+
}
|
|
3084
|
+
]
|
|
3093
3085
|
end
|
|
3094
3086
|
```
|
|
3095
3087
|
|
|
@@ -3097,8 +3089,7 @@ end
|
|
|
3097
3089
|
|
|
3098
3090
|
## 12. Future Enhancements
|
|
3099
3091
|
|
|
3100
|
-
See [Backlog](use_cases/backlog.md) for future enhancement ideas including:
|
|
3101
|
-
- Quick Start Presets (v1.1)
|
|
3092
|
+
See [Backlog](../use_cases/backlog.md) for future enhancement ideas including:
|
|
3102
3093
|
- Sampling Budget (v1.2+)
|
|
3103
3094
|
|
|
3104
3095
|
---
|