railwatch 0.9.3 → 1.0.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/AGENTS.md +37 -33
- data/CHANGELOG.md +66 -0
- data/README.md +51 -60
- data/config/routes.rb +0 -59
- data/docs/ai-and-mcp.md +9 -8
- data/docs/configuration.md +57 -71
- data/docs/faq.md +17 -25
- data/docs/getting-started.md +105 -117
- data/docs/replacing-nightwatch.md +8 -7
- data/docs/replacing-sentry.md +12 -16
- data/docs/security.md +14 -20
- data/docs/self-hosting.md +24 -22
- data/docs/testing.md +6 -14
- data/docs/troubleshooting.md +12 -46
- data/lib/generators/railwatch/install/install_generator.rb +12 -240
- data/lib/generators/railwatch/install/templates/initializer.rb.tt +10 -40
- data/lib/generators/railwatch/install/templates/post-deploy +0 -7
- data/lib/railwatch/authentication.rb +6 -5
- data/lib/railwatch/buffer.rb +9 -0
- data/lib/railwatch/configuration.rb +21 -151
- data/lib/railwatch/engine.rb +9 -118
- data/lib/railwatch/patches.rb +0 -11
- data/lib/railwatch/reporter.rb +92 -21
- data/lib/railwatch/sampler.rb +10 -2
- data/lib/railwatch/subscribers/process_info.rb +1 -2
- data/lib/railwatch/version.rb +1 -1
- data/lib/railwatch.rb +8 -64
- data/lib/tasks/railwatch_tasks.rake +3 -325
- data/llms.txt +23 -25
- metadata +3 -453
- data/app/channels/railwatch/environment_channel.rb +0 -62
- data/app/controllers/concerns/railwatch/telemetry_identity.rb +0 -25
- data/app/controllers/railwatch/alerts_controller.rb +0 -48
- data/app/controllers/railwatch/anomaly_rules_controller.rb +0 -31
- data/app/controllers/railwatch/attachments_controller.rb +0 -22
- data/app/controllers/railwatch/broadcasts_controller.rb +0 -15
- data/app/controllers/railwatch/cache_events_controller.rb +0 -30
- data/app/controllers/railwatch/commands_controller.rb +0 -16
- data/app/controllers/railwatch/comments_controller.rb +0 -11
- data/app/controllers/railwatch/dashboard_controller.rb +0 -70
- data/app/controllers/railwatch/deploys_controller.rb +0 -34
- data/app/controllers/railwatch/deprecations_controller.rb +0 -54
- data/app/controllers/railwatch/environment_scoped.rb +0 -81
- data/app/controllers/railwatch/exceptions_controller.rb +0 -52
- data/app/controllers/railwatch/executions_controller.rb +0 -13
- data/app/controllers/railwatch/issues_controller.rb +0 -258
- data/app/controllers/railwatch/jobs_controller.rb +0 -63
- data/app/controllers/railwatch/llm_calls_controller.rb +0 -124
- data/app/controllers/railwatch/logs_controller.rb +0 -40
- data/app/controllers/railwatch/mails_controller.rb +0 -19
- data/app/controllers/railwatch/notifications_controller.rb +0 -11
- data/app/controllers/railwatch/outgoing_requests_controller.rb +0 -19
- data/app/controllers/railwatch/overview_controller.rb +0 -38
- data/app/controllers/railwatch/people_controller.rb +0 -25
- data/app/controllers/railwatch/processes_controller.rb +0 -33
- data/app/controllers/railwatch/profiles_controller.rb +0 -65
- data/app/controllers/railwatch/queries_controller.rb +0 -59
- data/app/controllers/railwatch/releases_controller.rb +0 -75
- data/app/controllers/railwatch/requests_controller.rb +0 -37
- data/app/controllers/railwatch/saved_views_controller.rb +0 -53
- data/app/controllers/railwatch/scheduled_tasks_controller.rb +0 -45
- data/app/controllers/railwatch/spans_controller.rb +0 -47
- data/app/controllers/railwatch/storage_ops_controller.rb +0 -15
- data/app/controllers/railwatch/tenants_controller.rb +0 -44
- data/app/controllers/railwatch/thresholds_controller.rb +0 -47
- data/app/controllers/railwatch/traces_controller.rb +0 -72
- data/app/controllers/railwatch/transactions_controller.rb +0 -21
- data/app/controllers/railwatch/view_renders_controller.rb +0 -28
- data/app/controllers/railwatch/visits_controller.rb +0 -53
- data/app/frontend/components/app-content.tsx +0 -26
- data/app/frontend/components/app-logo-icon.tsx +0 -23
- data/app/frontend/components/app-logo.tsx +0 -14
- data/app/frontend/components/app-shell.tsx +0 -38
- data/app/frontend/components/app-sidebar-header.tsx +0 -54
- data/app/frontend/components/app-sidebar.tsx +0 -94
- data/app/frontend/components/app-wordmark.tsx +0 -29
- data/app/frontend/components/breadcrumbs.tsx +0 -46
- data/app/frontend/components/icon.tsx +0 -16
- data/app/frontend/components/input-error.tsx +0 -18
- data/app/frontend/components/nav-footer.tsx +0 -46
- data/app/frontend/components/nav-main.tsx +0 -41
- data/app/frontend/components/nav-user.tsx +0 -50
- data/app/frontend/components/railwatch/chart-hover.tsx +0 -34
- data/app/frontend/components/railwatch/chart-panel.tsx +0 -170
- data/app/frontend/components/railwatch/code.tsx +0 -28
- data/app/frontend/components/railwatch/command-palette.tsx +0 -132
- data/app/frontend/components/railwatch/copy-block.tsx +0 -52
- data/app/frontend/components/railwatch/copy-id.tsx +0 -49
- data/app/frontend/components/railwatch/cursor-load-more.tsx +0 -39
- data/app/frontend/components/railwatch/data-table.tsx +0 -195
- data/app/frontend/components/railwatch/digit-roll.tsx +0 -312
- data/app/frontend/components/railwatch/empty-state.tsx +0 -159
- data/app/frontend/components/railwatch/env-nav.tsx +0 -130
- data/app/frontend/components/railwatch/env-switcher.tsx +0 -145
- data/app/frontend/components/railwatch/filter-bar.tsx +0 -153
- data/app/frontend/components/railwatch/flamegraph.tsx +0 -324
- data/app/frontend/components/railwatch/frames.tsx +0 -295
- data/app/frontend/components/railwatch/json-viewer.tsx +0 -159
- data/app/frontend/components/railwatch/live-dot.tsx +0 -78
- data/app/frontend/components/railwatch/live-toggle.tsx +0 -76
- data/app/frontend/components/railwatch/metric-chart.tsx +0 -112
- data/app/frontend/components/railwatch/mobile-page-switcher.tsx +0 -89
- data/app/frontend/components/railwatch/onboarding.tsx +0 -91
- data/app/frontend/components/railwatch/origin-identity.tsx +0 -84
- data/app/frontend/components/railwatch/page-header.tsx +0 -42
- data/app/frontend/components/railwatch/percentile-picker.tsx +0 -18
- data/app/frontend/components/railwatch/relative-time.tsx +0 -18
- data/app/frontend/components/railwatch/saved-views.tsx +0 -232
- data/app/frontend/components/railwatch/segmented.tsx +0 -64
- data/app/frontend/components/railwatch/series-chart.tsx +0 -400
- data/app/frontend/components/railwatch/shortcuts-dialog.tsx +0 -89
- data/app/frontend/components/railwatch/signal-toast.tsx +0 -121
- data/app/frontend/components/railwatch/sort-header.tsx +0 -37
- data/app/frontend/components/railwatch/source-link.tsx +0 -57
- data/app/frontend/components/railwatch/sparkline-cell.tsx +0 -14
- data/app/frontend/components/railwatch/sql-block.tsx +0 -116
- data/app/frontend/components/railwatch/stat.tsx +0 -185
- data/app/frontend/components/railwatch/status-badge.tsx +0 -79
- data/app/frontend/components/railwatch/step-picker.tsx +0 -57
- data/app/frontend/components/railwatch/timeline.tsx +0 -405
- data/app/frontend/components/railwatch/utilisation-bar.tsx +0 -44
- data/app/frontend/components/railwatch/window-picker.tsx +0 -147
- data/app/frontend/components/ui/avatar.tsx +0 -51
- data/app/frontend/components/ui/badge.tsx +0 -46
- data/app/frontend/components/ui/breadcrumb.tsx +0 -109
- data/app/frontend/components/ui/button.tsx +0 -60
- data/app/frontend/components/ui/card.tsx +0 -92
- data/app/frontend/components/ui/chart.tsx +0 -374
- data/app/frontend/components/ui/checkbox.tsx +0 -32
- data/app/frontend/components/ui/collapsible.tsx +0 -31
- data/app/frontend/components/ui/command.tsx +0 -182
- data/app/frontend/components/ui/dialog.tsx +0 -158
- data/app/frontend/components/ui/dropdown-menu.tsx +0 -255
- data/app/frontend/components/ui/hover-card.tsx +0 -42
- data/app/frontend/components/ui/input.tsx +0 -21
- data/app/frontend/components/ui/label.tsx +0 -24
- data/app/frontend/components/ui/popover.tsx +0 -87
- data/app/frontend/components/ui/select.tsx +0 -185
- data/app/frontend/components/ui/separator.tsx +0 -28
- data/app/frontend/components/ui/sheet.tsx +0 -137
- data/app/frontend/components/ui/sidebar.tsx +0 -726
- data/app/frontend/components/ui/skeleton.tsx +0 -13
- data/app/frontend/components/ui/sonner.tsx +0 -41
- data/app/frontend/components/ui/table.tsx +0 -114
- data/app/frontend/components/ui/tabs.tsx +0 -91
- data/app/frontend/components/ui/textarea.tsx +0 -18
- data/app/frontend/components/ui/tooltip.tsx +0 -61
- data/app/frontend/components/user-info.tsx +0 -32
- data/app/frontend/components/user-menu-content.tsx +0 -94
- data/app/frontend/entrypoints/application.css +0 -244
- data/app/frontend/entrypoints/inertia.tsx +0 -92
- data/app/frontend/fonts/CommitMono-Bold.woff2 +0 -0
- data/app/frontend/fonts/CommitMono-Regular.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Black.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Bold.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Medium.woff2 +0 -0
- data/app/frontend/fonts/Roboto-Regular.woff2 +0 -0
- data/app/frontend/hooks/use-appearance.tsx +0 -67
- data/app/frontend/hooks/use-clipboard.ts +0 -32
- data/app/frontend/hooks/use-flash.tsx +0 -23
- data/app/frontend/hooks/use-hotkeys.ts +0 -63
- data/app/frontend/hooks/use-initials.tsx +0 -15
- data/app/frontend/hooks/use-live.ts +0 -205
- data/app/frontend/hooks/use-mobile-navigation.ts +0 -8
- data/app/frontend/hooks/use-mobile.ts +0 -21
- data/app/frontend/hooks/use-percentile.ts +0 -24
- data/app/frontend/hooks/use-reduced-motion.ts +0 -25
- data/app/frontend/hooks/use-row-nav.ts +0 -106
- data/app/frontend/hooks/use-step.ts +0 -27
- data/app/frontend/hooks/use-ticker.ts +0 -12
- data/app/frontend/hooks/use-window.ts +0 -58
- data/app/frontend/layouts/app/app-sidebar-layout.tsx +0 -107
- data/app/frontend/layouts/app-layout.tsx +0 -21
- data/app/frontend/layouts/env-layout.tsx +0 -53
- data/app/frontend/layouts/persistent-layout.tsx +0 -18
- data/app/frontend/lib/cable.ts +0 -10
- data/app/frontend/lib/env-pages.ts +0 -236
- data/app/frontend/lib/execution-path.ts +0 -55
- data/app/frontend/lib/explain.ts +0 -50
- data/app/frontend/lib/filter.ts +0 -25
- data/app/frontend/lib/flamegraph.ts +0 -155
- data/app/frontend/lib/format.ts +0 -71
- data/app/frontend/lib/keyboard.ts +0 -18
- data/app/frontend/lib/mount.ts +0 -23
- data/app/frontend/lib/source-link.ts +0 -217
- data/app/frontend/lib/utils.ts +0 -6
- data/app/frontend/pages/alerts/index.tsx +0 -171
- data/app/frontend/pages/broadcasts/index.tsx +0 -171
- data/app/frontend/pages/cache_events/index.tsx +0 -127
- data/app/frontend/pages/commands/index.tsx +0 -143
- data/app/frontend/pages/deploys/index.tsx +0 -94
- data/app/frontend/pages/deploys/show.tsx +0 -309
- data/app/frontend/pages/deprecations/index.tsx +0 -176
- data/app/frontend/pages/exceptions/index.tsx +0 -271
- data/app/frontend/pages/executions/show.tsx +0 -821
- data/app/frontend/pages/issues/index.tsx +0 -399
- data/app/frontend/pages/issues/show.tsx +0 -1367
- data/app/frontend/pages/jobs/index.tsx +0 -381
- data/app/frontend/pages/jobs/klass.tsx +0 -215
- data/app/frontend/pages/llm_calls/index.tsx +0 -664
- data/app/frontend/pages/logs/index.tsx +0 -303
- data/app/frontend/pages/mails/index.tsx +0 -218
- data/app/frontend/pages/notifications/index.tsx +0 -161
- data/app/frontend/pages/outgoing_requests/index.tsx +0 -309
- data/app/frontend/pages/overview/show.tsx +0 -333
- data/app/frontend/pages/people/index.tsx +0 -102
- data/app/frontend/pages/people/show.tsx +0 -149
- data/app/frontend/pages/processes/index.tsx +0 -335
- data/app/frontend/pages/profiles/index.tsx +0 -110
- data/app/frontend/pages/profiles/show.tsx +0 -105
- data/app/frontend/pages/queries/index.tsx +0 -492
- data/app/frontend/pages/queries/show.tsx +0 -276
- data/app/frontend/pages/releases/index.tsx +0 -190
- data/app/frontend/pages/releases/release-health.tsx +0 -68
- data/app/frontend/pages/releases/release-path.ts +0 -25
- data/app/frontend/pages/releases/show.tsx +0 -262
- data/app/frontend/pages/requests/index.tsx +0 -235
- data/app/frontend/pages/requests/route.tsx +0 -159
- data/app/frontend/pages/scheduled_tasks/index.tsx +0 -220
- data/app/frontend/pages/spans/index.tsx +0 -229
- data/app/frontend/pages/spans/show.tsx +0 -220
- data/app/frontend/pages/storage_ops/index.tsx +0 -150
- data/app/frontend/pages/tenants/index.tsx +0 -236
- data/app/frontend/pages/tenants/show.tsx +0 -477
- data/app/frontend/pages/tenants/tenant-path.ts +0 -26
- data/app/frontend/pages/thresholds/index.tsx +0 -414
- data/app/frontend/pages/traces/show.tsx +0 -208
- data/app/frontend/pages/transactions/index.tsx +0 -220
- data/app/frontend/pages/view_renders/index.tsx +0 -241
- data/app/frontend/pages/visits/index.tsx +0 -321
- data/app/frontend/public/icon.png +0 -0
- data/app/frontend/public/icon.svg +0 -5
- data/app/frontend/routes/index.d.ts +0 -2136
- data/app/frontend/routes/index.js +0 -2112
- data/app/frontend/types/globals.d.ts +0 -9
- data/app/frontend/types/index.ts +0 -288
- data/app/frontend/types/vite-env.d.ts +0 -9
- data/app/helpers/railwatch/assets_helper.rb +0 -52
- data/app/jobs/railwatch/anomaly_scan_job.rb +0 -11
- data/app/jobs/railwatch/application_job.rb +0 -7
- data/app/jobs/railwatch/auto_resolve_issues_job.rb +0 -19
- data/app/jobs/railwatch/check_scheduled_tasks_job.rb +0 -113
- data/app/jobs/railwatch/detect_anomalies_job.rb +0 -171
- data/app/jobs/railwatch/detect_performance_issues_job.rb +0 -95
- data/app/jobs/railwatch/group_exceptions_job.rb +0 -91
- data/app/jobs/railwatch/optimize_telemetry_job.rb +0 -23
- data/app/jobs/railwatch/performance_scan_job.rb +0 -11
- data/app/jobs/railwatch/prune_telemetry_job.rb +0 -129
- data/app/jobs/railwatch/release_health_rollup_job.rb +0 -64
- data/app/jobs/railwatch/rollup_catchup_job.rb +0 -21
- data/app/jobs/railwatch/rollup_job.rb +0 -132
- data/app/jobs/railwatch/scheduled_task_scan_job.rb +0 -11
- data/app/models/concerns/railwatch/detection_snapshotting.rb +0 -20
- data/app/models/railwatch/alert.rb +0 -229
- data/app/models/railwatch/alert_rule.rb +0 -121
- data/app/models/railwatch/anomaly_rule.rb +0 -51
- data/app/models/railwatch/application.rb +0 -44
- data/app/models/railwatch/application_record.rb +0 -33
- data/app/models/railwatch/comment.rb +0 -36
- data/app/models/railwatch/deploy.rb +0 -67
- data/app/models/railwatch/environment.rb +0 -68
- data/app/models/railwatch/execution_presenter.rb +0 -185
- data/app/models/railwatch/filter_query.rb +0 -184
- data/app/models/railwatch/followup_receipt.rb +0 -27
- data/app/models/railwatch/ingest/batch.rb +0 -355
- data/app/models/railwatch/ingest/mapper.rb +0 -585
- data/app/models/railwatch/ingest/payload.rb +0 -96
- data/app/models/railwatch/ingest/rollup_absorber.rb +0 -170
- data/app/models/railwatch/ingest/writer.rb +0 -137
- data/app/models/railwatch/issue.rb +0 -277
- data/app/models/railwatch/issue_activity.rb +0 -23
- data/app/models/railwatch/issue_detection_presenter.rb +0 -309
- data/app/models/railwatch/issue_detection_snapshot.rb +0 -77
- data/app/models/railwatch/maintenance_task.rb +0 -53
- data/app/models/railwatch/saved_view.rb +0 -63
- data/app/models/railwatch/telemetry/aggregations.rb +0 -251
- data/app/models/railwatch/telemetry/attachment.rb +0 -31
- data/app/models/railwatch/telemetry/bounded_gzip.rb +0 -101
- data/app/models/railwatch/telemetry/broadcast.rb +0 -13
- data/app/models/railwatch/telemetry/cache_event.rb +0 -16
- data/app/models/railwatch/telemetry/child.rb +0 -53
- data/app/models/railwatch/telemetry/cursor_page.rb +0 -99
- data/app/models/railwatch/telemetry/deprecation.rb +0 -13
- data/app/models/railwatch/telemetry/enqueued_job.rb +0 -13
- data/app/models/railwatch/telemetry/exception.rb +0 -28
- data/app/models/railwatch/telemetry/execution.rb +0 -152
- data/app/models/railwatch/telemetry/export_delivery.rb +0 -32
- data/app/models/railwatch/telemetry/export_destination.rb +0 -66
- data/app/models/railwatch/telemetry/health_sample.rb +0 -72
- data/app/models/railwatch/telemetry/ingest_batch.rb +0 -31
- data/app/models/railwatch/telemetry/llm_call.rb +0 -37
- data/app/models/railwatch/telemetry/log.rb +0 -91
- data/app/models/railwatch/telemetry/mail.rb +0 -13
- data/app/models/railwatch/telemetry/n_plus_one.rb +0 -92
- data/app/models/railwatch/telemetry/notification.rb +0 -13
- data/app/models/railwatch/telemetry/outgoing_request.rb +0 -13
- data/app/models/railwatch/telemetry/person.rb +0 -50
- data/app/models/railwatch/telemetry/process.rb +0 -10
- data/app/models/railwatch/telemetry/profile.rb +0 -37
- data/app/models/railwatch/telemetry/query.rb +0 -57
- data/app/models/railwatch/telemetry/query_shape.rb +0 -45
- data/app/models/railwatch/telemetry/release_health.rb +0 -69
- data/app/models/railwatch/telemetry/rollup.rb +0 -157
- data/app/models/railwatch/telemetry/session.rb +0 -24
- data/app/models/railwatch/telemetry/span.rb +0 -19
- data/app/models/railwatch/telemetry/storage_op.rb +0 -13
- data/app/models/railwatch/telemetry/tenant.rb +0 -240
- data/app/models/railwatch/telemetry/transaction.rb +0 -13
- data/app/models/railwatch/telemetry/view_render.rb +0 -13
- data/app/models/railwatch/telemetry/visit.rb +0 -24
- data/app/models/railwatch/telemetry_record.rb +0 -107
- data/app/models/railwatch/threshold.rb +0 -66
- data/app/models/railwatch/user.rb +0 -47
- data/app/models/railwatch/viewer.rb +0 -13
- data/app/models/railwatch/window.rb +0 -66
- data/app/views/layouts/railwatch/dashboard.html.erb +0 -25
- data/db/railwatch_migrate/20260916000000_create_railwatch_tables.rb +0 -151
- data/db/railwatch_migrate/20260917000000_create_railwatch_maintenance_tasks.rb +0 -18
- data/db/railwatch_migrate/20260917120000_create_railwatch_followup_receipts.rb +0 -20
- data/db/railwatch_migrate/20260918120000_widen_host_user_ids.rb +0 -71
- data/db/railwatch_telemetry_migrate/20260903000000_enable_incremental_vacuum.rb +0 -62
- data/db/railwatch_telemetry_migrate/20260903000001_create_telemetry.rb +0 -481
- data/db/railwatch_telemetry_migrate/20260903000002_rename_tenant_to_app_tenant.rb +0 -14
- data/db/railwatch_telemetry_migrate/20260903000003_add_statement_count_to_transactions.rb +0 -9
- data/db/railwatch_telemetry_migrate/20260903000004_add_role_and_channel.rb +0 -10
- data/db/railwatch_telemetry_migrate/20260903000005_add_locals_to_exceptions.rb +0 -9
- data/db/railwatch_telemetry_migrate/20260903000006_add_spans_health_vitals_and_fts.rb +0 -82
- data/db/railwatch_telemetry_migrate/20260903000007_rename_span_attributes_to_payload.rb +0 -10
- data/db/railwatch_telemetry_migrate/20260903000008_add_profiles_and_attachments.rb +0 -60
- data/db/railwatch_telemetry_migrate/20260903000009_add_truncated_to_attachments.rb +0 -9
- data/db/railwatch_telemetry_migrate/20260903000010_create_sessions_and_release_health.rb +0 -51
- data/db/railwatch_telemetry_migrate/20260903000011_add_fingerprint_to_exceptions.rb +0 -11
- data/db/railwatch_telemetry_migrate/20260904000012_add_failed_to_broadcasts.rb +0 -10
- data/db/railwatch_telemetry_migrate/20260904010000_add_filter_cursor_indexes.rb +0 -37
- data/db/railwatch_telemetry_migrate/20260904020000_add_n_plus_ones_execution_id_index.rb +0 -11
- data/db/railwatch_telemetry_migrate/20260904120000_create_query_shapes.rb +0 -15
- data/db/railwatch_telemetry_migrate/20260906120000_add_backpressure_factor_to_ingest_batches.rb +0 -9
- data/db/railwatch_telemetry_migrate/20260907000000_rename_lantern_version_on_processes.rb +0 -10
- data/db/railwatch_telemetry_migrate/20260913000000_rename_nightrail_version_on_processes.rb +0 -9
- data/db/railwatch_telemetry_migrate/20260914000000_drop_orphan_durable_ingest_tables.rb +0 -18
- data/db/railwatch_telemetry_migrate/20260914010000_drop_orphan_durable_ingest_columns.rb +0 -25
- data/db/railwatch_telemetry_migrate/20260915000000_create_llm_calls.rb +0 -55
- data/db/railwatch_telemetry_migrate/20260915120000_add_detail_to_llm_calls.rb +0 -21
- data/db/railwatch_telemetry_migrate/20260915200000_add_explained_index_to_queries.rb +0 -16
- data/db/railwatch_telemetry_migrate/20260915210000_add_slowest_index_to_queries.rb +0 -18
- data/db/railwatch_telemetry_migrate/20260917010000_add_batch_ledger_to_ingest_batches.rb +0 -16
- data/db/railwatch_telemetry_migrate/20260919000100_create_export_queue.rb +0 -146
- data/db/railwatch_telemetry_migrate/20260922000000_add_covering_indexes_for_dashboard_aggregates.rb +0 -34
- data/db/railwatch_telemetry_migrate/20260923000000_add_people_index.rb +0 -15
- data/db/railwatch_telemetry_migrate/20260925000000_add_tenant_summary_index.rb +0 -17
- data/db/railwatch_telemetry_migrate/20261008000000_add_in_transaction_to_outgoing_requests.rb +0 -10
- data/docs/embedded.md +0 -503
- data/lib/puma/plugin/railwatch.rb +0 -215
- data/lib/railwatch/dashboard_assets.rb +0 -45
- data/lib/railwatch/embedded.rb +0 -50
- data/lib/railwatch/export/client.rb +0 -124
- data/lib/railwatch/export/lease.rb +0 -56
- data/lib/railwatch/export/outbox.rb +0 -361
- data/lib/railwatch/export/policy.rb +0 -79
- data/lib/railwatch/export/sender.rb +0 -130
- data/lib/railwatch/ingest_request_body_limit.rb +0 -10
- data/lib/railwatch/maintenance.rb +0 -194
- data/lib/railwatch/patches/migration_busy_timeout.rb +0 -73
- data/lib/railwatch/transport/local.rb +0 -78
- data/lib/railwatch/transport/socket.rb +0 -183
- data/lib/railwatch/writer.rb +0 -370
- data/public/railwatch/assets/CommitMono-Bold-D6h61ieg.woff2 +0 -0
- data/public/railwatch/assets/CommitMono-Regular-zr8w7Obm.woff2 +0 -0
- data/public/railwatch/assets/Roboto-Black-auA4GeOK.woff2 +0 -0
- data/public/railwatch/assets/Roboto-Bold-CJLnO8j1.woff2 +0 -0
- data/public/railwatch/assets/Roboto-Medium-Cm2bwKpj.woff2 +0 -0
- data/public/railwatch/assets/Roboto-Regular-Chaq1-PV.woff2 +0 -0
- data/public/railwatch/assets/app-layout-by7G3sa1.js +0 -41
- data/public/railwatch/assets/application-Cc5v_Vk9.css +0 -1
- data/public/railwatch/assets/arrow-up-DCZ7emux.js +0 -1
- data/public/railwatch/assets/braces-CykT5_5u.js +0 -1
- data/public/railwatch/assets/card-C-PPSA0g.js +0 -1
- data/public/railwatch/assets/chart-Cov79YC5.js +0 -39
- data/public/railwatch/assets/chart-hover-DdK4E-2h.js +0 -1
- data/public/railwatch/assets/chart-panel-BPaYRXJB.js +0 -1
- data/public/railwatch/assets/code-BYjC4YZ_.js +0 -1
- data/public/railwatch/assets/copy-id-LPfoj9cC.js +0 -1
- data/public/railwatch/assets/cursor-load-more-DSdhgpGl.js +0 -1
- data/public/railwatch/assets/data-table-CQ_YRWQs.js +0 -1
- data/public/railwatch/assets/env-layout-CdMWbUkm.js +0 -1
- data/public/railwatch/assets/execution-path-7MYt-Qbn.js +0 -1
- data/public/railwatch/assets/filter-bar-CrzpQ_vD.js +0 -1
- data/public/railwatch/assets/flamegraph-BIFEdTAg.js +0 -2
- data/public/railwatch/assets/format-B9SDkrWj.js +0 -1
- data/public/railwatch/assets/frames-C5t-x4f0.js +0 -1
- data/public/railwatch/assets/index--NQ7us-L.js +0 -1
- data/public/railwatch/assets/index-2kgYe_99.js +0 -1
- data/public/railwatch/assets/index-4YEPHxtO.js +0 -1
- data/public/railwatch/assets/index-AOCC1GDJ.js +0 -1
- data/public/railwatch/assets/index-BEo-u0eO.js +0 -1
- data/public/railwatch/assets/index-BJ1V3w2N.js +0 -1
- data/public/railwatch/assets/index-BPoHsBKb.js +0 -1
- data/public/railwatch/assets/index-BZzyGUM3.js +0 -1
- data/public/railwatch/assets/index-BgVq7yKL.js +0 -1
- data/public/railwatch/assets/index-BqFGEZvW.js +0 -1
- data/public/railwatch/assets/index-ByuHJ1CH.js +0 -1
- data/public/railwatch/assets/index-C2j50AL2.js +0 -1
- data/public/railwatch/assets/index-CLEdTkvW.js +0 -1
- data/public/railwatch/assets/index-CWgq8qBu.js +0 -1
- data/public/railwatch/assets/index-CXQ7_oVj.js +0 -2
- data/public/railwatch/assets/index-CmyYrjS2.js +0 -1
- data/public/railwatch/assets/index-Cn9_HjDo.js +0 -1
- data/public/railwatch/assets/index-CsMAm9UK.js +0 -1
- data/public/railwatch/assets/index-D0Kk_oGY.js +0 -1
- data/public/railwatch/assets/index-DC9ZptJh.js +0 -1
- data/public/railwatch/assets/index-DNzg7jmV.js +0 -1
- data/public/railwatch/assets/index-DQ8uJO5f.js +0 -1
- data/public/railwatch/assets/index-Deq14BxB.js +0 -1
- data/public/railwatch/assets/index-IaV3Blzp.js +0 -1
- data/public/railwatch/assets/index-TYNWcJQs.js +0 -1
- data/public/railwatch/assets/index-WonH2fcZ.js +0 -1
- data/public/railwatch/assets/index-WxWUaH_d.js +0 -1
- data/public/railwatch/assets/index-mUNrl4ky.js +0 -1
- data/public/railwatch/assets/inertia-DfNRARuA.js +0 -97
- data/public/railwatch/assets/json-viewer-DMsF5glp.js +0 -1
- data/public/railwatch/assets/klass-CmHYk5rz.js +0 -1
- data/public/railwatch/assets/origin-identity-1R3bqa3R.js +0 -1
- data/public/railwatch/assets/percentile-picker-73z5PAps.js +0 -1
- data/public/railwatch/assets/relative-time-Dsc_cCdX.js +0 -1
- data/public/railwatch/assets/release-health-BV5OaOWd.js +0 -1
- data/public/railwatch/assets/route-CWh58C7K.js +0 -1
- data/public/railwatch/assets/segmented-DB4zh-Am.js +0 -1
- data/public/railwatch/assets/select-DBKjFlOX.js +0 -1
- data/public/railwatch/assets/series-chart-BaiDG795.js +0 -1
- data/public/railwatch/assets/show-B4ICCFGh.js +0 -1
- data/public/railwatch/assets/show-B5lOU9Gv.js +0 -1
- data/public/railwatch/assets/show-BYPB74t4.js +0 -2
- data/public/railwatch/assets/show-C7A0m2M8.js +0 -1
- data/public/railwatch/assets/show-DT5X1zqE.js +0 -1
- data/public/railwatch/assets/show-D_NBdXsn.js +0 -2
- data/public/railwatch/assets/show-DgPCnRg8.js +0 -1
- data/public/railwatch/assets/show-Yl69HF0x.js +0 -1
- data/public/railwatch/assets/show-_QxuUQCm.js +0 -3
- data/public/railwatch/assets/show-g__jnN36.js +0 -1
- data/public/railwatch/assets/show-l4ztfjl9.js +0 -1
- data/public/railwatch/assets/sort-header-BcG8ulEH.js +0 -1
- data/public/railwatch/assets/source-link-B2183i2-.js +0 -1
- data/public/railwatch/assets/sparkline-cell-B47ipscB.js +0 -1
- data/public/railwatch/assets/stat-DT2hhsqS.js +0 -1
- data/public/railwatch/assets/status-badge-CmbRKlY7.js +0 -1
- data/public/railwatch/assets/tenant-path-C4rNGauE.js +0 -1
- data/public/railwatch/assets/use-clipboard-oTNeP4ax.js +0 -1
- data/public/railwatch/assets/use-live-CLZZj245.js +0 -1
- data/public/railwatch/icon.png +0 -0
- data/public/railwatch/icon.svg +0 -5
- data/public/railwatch/manifest.json +0 -1245
- data/public/railwatch/rails-vite.json +0 -1
- /data/{app/frontend/lib → lib/generators/railwatch/install/templates}/railwatch.ts +0 -0
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Sampled CPU/wall profiles for an execution, attachments (files an app
|
|
4
|
-
# attaches to an execution or exception), and opt-in captured bodies.
|
|
5
|
-
class AddProfilesAndAttachments < ActiveRecord::Migration[8.1]
|
|
6
|
-
def change
|
|
7
|
-
create_table :profiles do |t|
|
|
8
|
-
# The record envelope as it was when this migration shipped; inlined so
|
|
9
|
-
# the history never calls a model that has since changed.
|
|
10
|
-
t.datetime :occurred_at, null: false, precision: 6
|
|
11
|
-
t.string :deploy, limit: 128
|
|
12
|
-
t.string :server, limit: 255
|
|
13
|
-
t.string :group_hash, limit: 32
|
|
14
|
-
t.string :trace_id, limit: 36
|
|
15
|
-
t.string :execution_source, limit: 20
|
|
16
|
-
t.string :execution_id, limit: 36
|
|
17
|
-
t.string :execution_preview, limit: 255
|
|
18
|
-
t.string :execution_stage, limit: 32
|
|
19
|
-
t.string :user_ref, limit: 255
|
|
20
|
-
t.string :app_tenant, limit: 255
|
|
21
|
-
t.string :profiler, null: false, limit: 16 # vernier, stackprof
|
|
22
|
-
t.string :mode, limit: 8 # wall, cpu
|
|
23
|
-
t.integer :interval # microseconds between samples
|
|
24
|
-
t.integer :duration, null: false # microseconds profiled
|
|
25
|
-
t.integer :samples, null: false # total samples collected
|
|
26
|
-
t.binary :stacks, null: false # gzip of collapsed stacks: "frame;frame;frame count\n"
|
|
27
|
-
t.integer :stacks_bytes # uncompressed size
|
|
28
|
-
end
|
|
29
|
-
add_index :profiles, [ :execution_id ]
|
|
30
|
-
add_index :profiles, [ :group_hash, :occurred_at ]
|
|
31
|
-
add_index :profiles, [ :occurred_at ]
|
|
32
|
-
|
|
33
|
-
create_table :attachments do |t|
|
|
34
|
-
# The record envelope as it was when this migration shipped; inlined so
|
|
35
|
-
# the history never calls a model that has since changed.
|
|
36
|
-
t.datetime :occurred_at, null: false, precision: 6
|
|
37
|
-
t.string :deploy, limit: 128
|
|
38
|
-
t.string :server, limit: 255
|
|
39
|
-
t.string :group_hash, limit: 32
|
|
40
|
-
t.string :trace_id, limit: 36
|
|
41
|
-
t.string :execution_source, limit: 20
|
|
42
|
-
t.string :execution_id, limit: 36
|
|
43
|
-
t.string :execution_preview, limit: 255
|
|
44
|
-
t.string :execution_stage, limit: 32
|
|
45
|
-
t.string :user_ref, limit: 255
|
|
46
|
-
t.string :app_tenant, limit: 255
|
|
47
|
-
t.string :name, null: false, limit: 255
|
|
48
|
-
t.string :content_type, limit: 128
|
|
49
|
-
t.integer :bytes, null: false
|
|
50
|
-
t.binary :data, null: false # gzip
|
|
51
|
-
t.string :exception_group_hash, limit: 32 # set when attached to an exception
|
|
52
|
-
end
|
|
53
|
-
add_index :attachments, [ :execution_id ]
|
|
54
|
-
add_index :attachments, [ :exception_group_hash, :occurred_at ]
|
|
55
|
-
add_index :attachments, [ :occurred_at ]
|
|
56
|
-
|
|
57
|
-
add_column :outgoing_requests, :response_body, :text # captured on error only, truncated
|
|
58
|
-
add_column :executions, :profile_id, :integer # denormalised: the execution has a profile
|
|
59
|
-
end
|
|
60
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The gem cuts an attachment off at its size limit and flags the wire
|
|
4
|
-
# record; without this column the UI cannot tell a whole file from a stub.
|
|
5
|
-
class AddTruncatedToAttachments < ActiveRecord::Migration[8.1]
|
|
6
|
-
def change
|
|
7
|
-
add_column :attachments, :truncated, :boolean, default: false, null: false
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Release health. `sessions` are the raw records the gem ships -- one per
|
|
4
|
-
# browser tab and per authenticated/cookied server session, repeated every
|
|
5
|
-
# flush interval, so a session id appears many times and the rollup keeps the
|
|
6
|
-
# worst status it saw. `release_health` is the hourly aggregate per deploy
|
|
7
|
-
# (the release) that the crash-free rates are read from.
|
|
8
|
-
class CreateSessionsAndReleaseHealth < ActiveRecord::Migration[8.1]
|
|
9
|
-
def change
|
|
10
|
-
create_table :sessions do |t|
|
|
11
|
-
# The record envelope as it was when this migration shipped; inlined so
|
|
12
|
-
# the history never calls a model that has since changed.
|
|
13
|
-
t.datetime :occurred_at, null: false, precision: 6
|
|
14
|
-
t.string :deploy, limit: 128
|
|
15
|
-
t.string :server, limit: 255
|
|
16
|
-
t.string :group_hash, limit: 32
|
|
17
|
-
t.string :trace_id, limit: 36
|
|
18
|
-
t.string :execution_source, limit: 20
|
|
19
|
-
t.string :execution_id, limit: 36
|
|
20
|
-
t.string :execution_preview, limit: 255
|
|
21
|
-
t.string :execution_stage, limit: 32
|
|
22
|
-
t.string :user_ref, limit: 255
|
|
23
|
-
t.string :app_tenant, limit: 255
|
|
24
|
-
t.string :session_id, null: false, limit: 64
|
|
25
|
-
t.string :source, limit: 16 # browser, server
|
|
26
|
-
t.string :status, limit: 16 # started, ok, errored, crashed
|
|
27
|
-
t.datetime :started_at, precision: 6
|
|
28
|
-
t.integer :duration # microseconds, null until the session has one
|
|
29
|
-
t.integer :requests, default: 0
|
|
30
|
-
t.integer :visits, default: 0
|
|
31
|
-
t.integer :error_count, default: 0 # `errors` is a reserved Active Record name
|
|
32
|
-
t.boolean :ended, default: false
|
|
33
|
-
end
|
|
34
|
-
add_index :sessions, [ :session_id, :occurred_at ]
|
|
35
|
-
add_index :sessions, [ :deploy, :occurred_at ]
|
|
36
|
-
add_index :sessions, [ :occurred_at ]
|
|
37
|
-
|
|
38
|
-
create_table :release_health do |t|
|
|
39
|
-
t.string :deploy, null: false, limit: 128
|
|
40
|
-
t.datetime :bucket, null: false, precision: 6
|
|
41
|
-
t.integer :sessions, default: 0
|
|
42
|
-
t.integer :sessions_errored, default: 0
|
|
43
|
-
t.integer :sessions_crashed, default: 0
|
|
44
|
-
t.integer :users, default: 0
|
|
45
|
-
t.integer :users_crashed, default: 0
|
|
46
|
-
t.bigint :duration_sum, default: 0
|
|
47
|
-
t.integer :duration_count, default: 0
|
|
48
|
-
end
|
|
49
|
-
add_index :release_health, [ :deploy, :bucket ], unique: true
|
|
50
|
-
end
|
|
51
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The parts the gem hashed this exception into an issue on, and where they
|
|
4
|
-
# came from (its own default, a resolver, a per-call fingerprint, or the
|
|
5
|
-
# error class itself) -- so an issue can show why it grouped the way it did.
|
|
6
|
-
class AddFingerprintToExceptions < ActiveRecord::Migration[8.1]
|
|
7
|
-
def change
|
|
8
|
-
add_column :exceptions, :fingerprint, :json, default: [], null: false
|
|
9
|
-
add_column :exceptions, :fingerprint_source, :string, limit: 16
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Whether a channel action raised. The gem reports the exception itself
|
|
4
|
-
# (source "application.action_cable"); this flag lets the Broadcasts page mark
|
|
5
|
-
# the failed action alongside its siblings, the way jobs and mail already do.
|
|
6
|
-
class AddFailedToBroadcasts < ActiveRecord::Migration[8.1]
|
|
7
|
-
def change
|
|
8
|
-
add_column :broadcasts, :failed, :boolean, default: false, null: false
|
|
9
|
-
end
|
|
10
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Keyset pagination orders every telemetry list by (sort column, id), so an
|
|
4
|
-
# index that stops at the sort column still leaves SQLite sorting ties in a
|
|
5
|
-
# temp B-tree. Each index below ends in id for that reason, and exists only
|
|
6
|
-
# where the leading filter column is selective enough that seeking beats
|
|
7
|
-
# scanning the ordering index and filtering.
|
|
8
|
-
#
|
|
9
|
-
# Deliberately NOT indexed, even though the FilterBar exposes them:
|
|
10
|
-
# exceptions.handled, queries.connection, queries.role, and executions.queue
|
|
11
|
-
# all carry a handful of distinct values in practice, so the existing ordering
|
|
12
|
-
# index plus a row filter is as good as a seek and costs nothing on write.
|
|
13
|
-
class AddFilterCursorIndexes < ActiveRecord::Migration[8.1]
|
|
14
|
-
def change
|
|
15
|
-
# Jobs page, filtered by tenant. index_executions_on_app_tenant_and_occurred_at
|
|
16
|
-
# cannot serve it: the page is already restricted to kind = "job".
|
|
17
|
-
add_index :executions, [ :kind, :app_tenant, :occurred_at, :id ], name: "idx_executions_kind_tenant_cursor"
|
|
18
|
-
# "Failed jobs" is the most-used view on that page and failures are rare,
|
|
19
|
-
# so the two-valued outcome column is highly selective here.
|
|
20
|
-
add_index :executions, [ :kind, :outcome, :occurred_at, :id ], name: "idx_executions_kind_outcome_cursor"
|
|
21
|
-
|
|
22
|
-
# exceptions has only (occurred_at); both of these filters are per-tenant
|
|
23
|
-
# or per-class needles in a large table.
|
|
24
|
-
add_index :exceptions, [ :app_tenant, :occurred_at, :id ], name: "idx_exceptions_tenant_cursor"
|
|
25
|
-
add_index :exceptions, [ :class_name, :occurred_at, :id ], name: "idx_exceptions_class_cursor"
|
|
26
|
-
|
|
27
|
-
add_index :logs, [ :app_tenant, :occurred_at, :id ], name: "idx_logs_tenant_cursor"
|
|
28
|
-
# Replaced, not added: the same index with the keyset tiebreaker appended.
|
|
29
|
-
remove_index :logs, [ :level, :occurred_at ], name: "index_logs_on_level_and_occurred_at"
|
|
30
|
-
add_index :logs, [ :level, :occurred_at, :id ], name: "idx_logs_level_cursor"
|
|
31
|
-
|
|
32
|
-
# The queries page sorts by duration, which index_queries_on_occurred_at_and_duration
|
|
33
|
-
# cannot order by. The first index serves the unfiltered page.
|
|
34
|
-
add_index :queries, [ :duration, :id ], name: "idx_queries_duration_cursor"
|
|
35
|
-
add_index :queries, [ :app_tenant, :duration, :id ], name: "idx_queries_tenant_duration_cursor"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# n_plus_ones had no execution_id index, alone among the child tables, so
|
|
4
|
-
# every trace page and every get_route call that asked "which N+1s did
|
|
5
|
-
# these requests hit" scanned the table: 1.6 s at 70k rows on the
|
|
6
|
-
# platform's own tenant, and it only grows.
|
|
7
|
-
class AddNPlusOnesExecutionIdIndex < ActiveRecord::Migration[8.1]
|
|
8
|
-
def change
|
|
9
|
-
add_index :n_plus_ones, :execution_id, name: "index_n_plus_ones_on_execution_id"
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# A query group's normalized statement, stored once; rows that carry
|
|
4
|
-
# exactly it store "" instead (docs/architecture.md). queries.sql keeps
|
|
5
|
-
# its NOT NULL: relaxing it would rewrite the table on every tenant, which
|
|
6
|
-
# SQLite cannot do in place and the deploy's health window cannot afford.
|
|
7
|
-
class CreateQueryShapes < ActiveRecord::Migration[8.1]
|
|
8
|
-
def change
|
|
9
|
-
create_table :query_shapes, id: false do |t|
|
|
10
|
-
t.string :group_hash, null: false, limit: 32
|
|
11
|
-
t.text :sql, null: false
|
|
12
|
-
end
|
|
13
|
-
add_index :query_shapes, :group_hash, unique: true
|
|
14
|
-
end
|
|
15
|
-
end
|
data/db/railwatch_telemetry_migrate/20260906120000_add_backpressure_factor_to_ingest_batches.rb
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The gem reports when load forces it to sample every execution kind, so the
|
|
4
|
-
# platform can distinguish quiet traffic from reduced client-side reporting.
|
|
5
|
-
class AddBackpressureFactorToIngestBatches < ActiveRecord::Migration[8.1]
|
|
6
|
-
def change
|
|
7
|
-
add_column :ingest_batches, :backpressure_factor, :float, null: false, default: 1.0
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The gem version a process reports. Column renamed with the platform; the
|
|
4
|
-
# ingest mapper accepts both wire spellings while environments still run the
|
|
5
|
-
# lantern gem.
|
|
6
|
-
class RenameLanternVersionOnProcesses < ActiveRecord::Migration[8.1]
|
|
7
|
-
def change
|
|
8
|
-
rename_column :processes, :lantern_version, :nightrail_version
|
|
9
|
-
end
|
|
10
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The gem version a process reports. Column renamed with the platform; the
|
|
4
|
-
# ingest mapper still accepts the pinned lantern gem's wire spelling.
|
|
5
|
-
class RenameNightrailVersionOnProcesses < ActiveRecord::Migration[8.1]
|
|
6
|
-
def change
|
|
7
|
-
rename_column :processes, :nightrail_version, :railwatch_version
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Telemetry half of the primary migration of the same name: #84's
|
|
4
|
-
# rollup_cursors and source_maps, and #60's release_health_finalizations,
|
|
5
|
-
# stayed behind in every tenant after their code was reverted or replaced.
|
|
6
|
-
class DropOrphanDurableIngestTables < ActiveRecord::Migration[8.1]
|
|
7
|
-
ORPHAN_TABLES = %w[release_health_finalizations rollup_cursors source_maps].freeze
|
|
8
|
-
ORPHAN_VERSIONS = %w[20260904000013 20260905000100 20260905000200 20260905000400].freeze
|
|
9
|
-
|
|
10
|
-
def up
|
|
11
|
-
ORPHAN_TABLES.each { |table| drop_table table, if_exists: true }
|
|
12
|
-
execute "DELETE FROM schema_migrations WHERE version IN (#{ORPHAN_VERSIONS.map { |v| "'#{v}'" }.join(", ")})"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def down
|
|
16
|
-
raise ActiveRecord::IrreversibleMigration, "the dropped tables belonged to reverted code; there is nothing to restore"
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The column half of the #84 cleanup (see 20260914000000): its migrations
|
|
4
|
-
# also added delivery-state columns to ingest_batches and resolved-frame
|
|
5
|
-
# columns to exceptions in every tenant before the code was reverted in
|
|
6
|
-
# 5521379. Nothing reads them, and the weekly restore drill fails the
|
|
7
|
-
# column comparison on every restored tenant. Indexes go first: SQLite
|
|
8
|
-
# refuses to drop an indexed column.
|
|
9
|
-
class DropOrphanDurableIngestColumns < ActiveRecord::Migration[8.1]
|
|
10
|
-
def up
|
|
11
|
-
remove_index :ingest_batches, :followups_completed_at, if_exists: true
|
|
12
|
-
remove_index :ingest_batches, :delivery_key, if_exists: true
|
|
13
|
-
remove_index :ingest_batches, :batch_id, if_exists: true
|
|
14
|
-
%i[batch_id delivery_key followups followups_completed_at].each do |column|
|
|
15
|
-
remove_column :ingest_batches, column if column_exists?(:ingest_batches, column)
|
|
16
|
-
end
|
|
17
|
-
%i[resolved_frames resolved_frames_key].each do |column|
|
|
18
|
-
remove_column :exceptions, column if column_exists?(:exceptions, column)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def down
|
|
23
|
-
raise ActiveRecord::IrreversibleMigration, "the dropped columns belonged to reverted code; there is nothing to restore"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# One row per RubyLLM call: a model call of any operation, or a tool
|
|
4
|
-
# invocation (operation "tool", which carries a name and a duration but no
|
|
5
|
-
# tokens or cost). Token counts keep RubyLLM's normalized buckets rather
|
|
6
|
-
# than a provider's own names, and cost is nanodollars so a month of rollup
|
|
7
|
-
# sums stays exact -- nil there means unpriced, never free.
|
|
8
|
-
class CreateLlmCalls < ActiveRecord::Migration[8.1]
|
|
9
|
-
def change
|
|
10
|
-
create_table :llm_calls do |t|
|
|
11
|
-
# The record envelope as it was when this migration shipped; inlined so
|
|
12
|
-
# the history never calls a model that has since changed.
|
|
13
|
-
t.datetime :occurred_at, null: false, precision: 6
|
|
14
|
-
t.string :deploy, limit: 128
|
|
15
|
-
t.string :server, limit: 255
|
|
16
|
-
t.string :group_hash, limit: 32
|
|
17
|
-
t.string :trace_id, limit: 36
|
|
18
|
-
t.string :execution_source, limit: 20
|
|
19
|
-
t.string :execution_id, limit: 36
|
|
20
|
-
t.string :execution_preview, limit: 255
|
|
21
|
-
t.string :execution_stage, limit: 32
|
|
22
|
-
t.string :user_ref, limit: 255
|
|
23
|
-
t.string :app_tenant, limit: 255
|
|
24
|
-
t.string :operation, null: false, limit: 20
|
|
25
|
-
t.string :provider, limit: 64
|
|
26
|
-
t.string :model, limit: 255
|
|
27
|
-
t.string :response_model, limit: 255
|
|
28
|
-
t.string :tool_name, limit: 255
|
|
29
|
-
t.integer :duration, null: false
|
|
30
|
-
t.string :status, limit: 16
|
|
31
|
-
t.string :error, limit: 255
|
|
32
|
-
t.boolean :streaming
|
|
33
|
-
t.integer :message_count
|
|
34
|
-
t.integer :tool_count
|
|
35
|
-
t.integer :input_tokens
|
|
36
|
-
t.integer :output_tokens
|
|
37
|
-
t.integer :cache_read_tokens
|
|
38
|
-
t.integer :cache_write_tokens
|
|
39
|
-
t.integer :thinking_tokens
|
|
40
|
-
t.bigint :cost_nanos
|
|
41
|
-
# Present only for calls made inside RubyLLM.workflow (2.0 and up).
|
|
42
|
-
# The parent step id is what reconstructs a nested agent run.
|
|
43
|
-
t.string :workflow_id, limit: 64
|
|
44
|
-
t.string :workflow_name, limit: 255
|
|
45
|
-
t.string :workflow_step_id, limit: 64
|
|
46
|
-
t.string :workflow_step_name, limit: 255
|
|
47
|
-
t.string :workflow_step_parent_id, limit: 64
|
|
48
|
-
t.text :prompt
|
|
49
|
-
t.text :completion
|
|
50
|
-
end
|
|
51
|
-
add_index :llm_calls, [ :group_hash, :occurred_at ]
|
|
52
|
-
add_index :llm_calls, [ :execution_id ]
|
|
53
|
-
add_index :llm_calls, [ :workflow_id, :occurred_at ]
|
|
54
|
-
end
|
|
55
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# What an LLM call carried and how it was configured, alongside what it
|
|
4
|
-
# cost. finish_reason is the one that changes what you can see: max_tokens
|
|
5
|
-
# means the answer was cut off, and a truncated extraction otherwise reads
|
|
6
|
-
# exactly like a complete one.
|
|
7
|
-
class AddDetailToLlmCalls < ActiveRecord::Migration[8.1]
|
|
8
|
-
def change
|
|
9
|
-
change_table :llm_calls, bulk: true do |t|
|
|
10
|
-
t.string :finish_reason, limit: 32
|
|
11
|
-
t.string :provider_request_id, limit: 128
|
|
12
|
-
t.string :tools, limit: 1024
|
|
13
|
-
t.boolean :cost_reported
|
|
14
|
-
t.integer :attachments
|
|
15
|
-
t.string :attachment_types, limit: 128
|
|
16
|
-
t.string :attachment_names, limit: 1024
|
|
17
|
-
t.string :tool_call_id, limit: 128
|
|
18
|
-
t.json :params
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The queries page asks "which of these 200 shapes have a captured plan in
|
|
4
|
-
# the window?" -- WHERE occurred_at BETWEEN ? AND ? AND group_hash IN (200
|
|
5
|
-
# values) AND explain IS NOT NULL. The planner walks the (group_hash,
|
|
6
|
-
# occurred_at) index for every one of the 200 shapes and then checks
|
|
7
|
-
# `explain` on each row, which is 840 ms at one day of one environment's
|
|
8
|
-
# queries (1M rows), and that whole time is a GVL hold: sqlite3-ruby does
|
|
9
|
-
# not release the GVL inside sqlite3_step. Plans are only captured for slow
|
|
10
|
-
# queries, so a partial index over just the explained rows is tiny and
|
|
11
|
-
# answers the question in 4 ms.
|
|
12
|
-
class AddExplainedIndexToQueries < ActiveRecord::Migration[8.1]
|
|
13
|
-
def change
|
|
14
|
-
add_index :queries, [ :group_hash, :occurred_at ], name: "idx_queries_explained", where: "explain IS NOT NULL"
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The queries page's "slowest in window" list orders the window by duration
|
|
4
|
-
# and takes a page. Every existing index leads with occurred_at, so the
|
|
5
|
-
# planner scans the whole window and sorts it: 48 ms for a day of one
|
|
6
|
-
# environment's queries (1M rows) -- and sqlite3-ruby holds the GVL for the
|
|
7
|
-
# whole statement, so every other request thread waits too. An index that
|
|
8
|
-
# leads with (duration DESC, id DESC) matches the page's ORDER BY exactly, so
|
|
9
|
-
# SQLite walks it from the slowest row and stops at the page (microseconds,
|
|
10
|
-
# and it cannot get worse as the table grows); occurred_at rides along so
|
|
11
|
-
# the window filter is answered from the index too. The planner still
|
|
12
|
-
# prefers the occurred_at index on its own cost model, so CursorPage forces
|
|
13
|
-
# this one.
|
|
14
|
-
class AddSlowestIndexToQueries < ActiveRecord::Migration[8.1]
|
|
15
|
-
def change
|
|
16
|
-
add_index :queries, [ :duration, :id, :occurred_at ], name: "idx_queries_slowest", order: { duration: :desc, id: :desc }
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Delivery ledger for in-process ingest. The reporter gives every batch a
|
|
4
|
-
# stable id before the first attempt; recording it on the ingest_batches row
|
|
5
|
-
# inside the batch transaction lets a retry ask "did this commit?" instead of
|
|
6
|
-
# guessing, and lets the follow-up work the batch still owes (exception
|
|
7
|
-
# grouping, which writes the other database) be resumed after a crash.
|
|
8
|
-
# `followups` is the small outbox: nil once everything has run.
|
|
9
|
-
class AddBatchLedgerToIngestBatches < ActiveRecord::Migration[8.1]
|
|
10
|
-
def change
|
|
11
|
-
add_column :ingest_batches, :batch_id, :string, limit: 36
|
|
12
|
-
add_column :ingest_batches, :followups, :json
|
|
13
|
-
add_index :ingest_batches, :batch_id, unique: true
|
|
14
|
-
add_index :ingest_batches, :received_at, where: "followups IS NOT NULL", name: "index_ingest_batches_pending_followups"
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The durable queue an embedded install uses to mirror its telemetry to a
|
|
4
|
-
# remote receiver.
|
|
5
|
-
#
|
|
6
|
-
# Why the bodies are stored rather than re-derived from the rows next door:
|
|
7
|
-
# the rows are not a reversible copy of what was sent. Mapping renames and
|
|
8
|
-
# drops fields, caps strings, swaps a query's SQL for a shape reference and
|
|
9
|
-
# coalesces people; and ingest rejects records the receiver may well accept,
|
|
10
|
-
# so sending only what we kept would not be the same telemetry. A delivery
|
|
11
|
-
# therefore keeps the exact bytes it will send, and frees them the moment it
|
|
12
|
-
# reaches a terminal state -- the cost tracks what is unacknowledged, not what
|
|
13
|
-
# is stored.
|
|
14
|
-
#
|
|
15
|
-
# Nothing here is written unless export is explicitly enabled.
|
|
16
|
-
#
|
|
17
|
-
# Every statement is if_not_exists, because this migration has run before
|
|
18
|
-
# under another number. Through 0.5.0 it was 20260919000000; 0.5.1 moved it
|
|
19
|
-
# here so it could not collide with a host's own telemetry migration at that
|
|
20
|
-
# number (Railwatch Cloud has one). An install upgrading from 0.5.0 or older
|
|
21
|
-
# therefore already holds every table, index and column below, recorded
|
|
22
|
-
# under the old version, and sees this one as pending: a plain create_table
|
|
23
|
-
# raised "table export_destinations already exists" in db:prepare, which a
|
|
24
|
-
# deploy runs before the app boots. The old run is detected by what it
|
|
25
|
-
# built, not by its version, because on a host like Railwatch Cloud the old
|
|
26
|
-
# number belongs to a different migration.
|
|
27
|
-
#
|
|
28
|
-
# Rolling back has the mirror problem: on a database that came through the
|
|
29
|
-
# old number, these tables and columns -- and anything queued in them -- are
|
|
30
|
-
# the old version's, which stays recorded as applied. So down leaves them
|
|
31
|
-
# alone there, and reverses the migration everywhere else.
|
|
32
|
-
class CreateExportQueue < ActiveRecord::Migration[8.1]
|
|
33
|
-
OLD_VERSION = 20260919000000
|
|
34
|
-
|
|
35
|
-
def up
|
|
36
|
-
build_queue
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def down
|
|
40
|
-
if built_under_old_number?
|
|
41
|
-
say("left in place: #{OLD_VERSION} built this queue under its pre-0.5.1 number and is still recorded as applied")
|
|
42
|
-
else
|
|
43
|
-
revert { build_queue }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
# The old version is recorded, and no migration file this database knows
|
|
49
|
-
# of claims it: only the gem's own pre-0.5.1 CreateExportQueue did.
|
|
50
|
-
def built_under_old_number?
|
|
51
|
-
context = connection.pool.migration_context
|
|
52
|
-
context.get_all_versions.include?(OLD_VERSION) && context.migrations.none? { |m| m.version == OLD_VERSION }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def build_queue
|
|
56
|
-
# One row per destination this database has ever been pointed at.
|
|
57
|
-
create_table :export_destinations, if_not_exists: true do |t|
|
|
58
|
-
t.string :url, null: false
|
|
59
|
-
t.string :url_sha256, limit: 64, null: false
|
|
60
|
-
# Permanent for this database's lineage: it is how the receiver tells
|
|
61
|
-
# our deliveries from another installation's.
|
|
62
|
-
t.string :producer_id, limit: 36, null: false
|
|
63
|
-
# A fingerprint, never the token. If the token changes, queued bytes
|
|
64
|
-
# must not follow it to whatever tenant the new one belongs to.
|
|
65
|
-
t.string :credential_sha256, limit: 64, null: false
|
|
66
|
-
|
|
67
|
-
t.string :state, limit: 16, null: false, default: "ready"
|
|
68
|
-
t.datetime :retry_at, precision: 6
|
|
69
|
-
t.string :reason, limit: 64
|
|
70
|
-
|
|
71
|
-
t.string :lease_owner, limit: 36
|
|
72
|
-
t.bigint :lease_generation, null: false, default: 0
|
|
73
|
-
t.datetime :lease_expires_at, precision: 6
|
|
74
|
-
|
|
75
|
-
# Live totals, maintained in the same transaction as the rows they
|
|
76
|
-
# describe, so admission can be decided without counting the table.
|
|
77
|
-
t.bigint :queued_bytes, null: false, default: 0
|
|
78
|
-
t.bigint :queued_deliveries, null: false, default: 0
|
|
79
|
-
# Lifetime accounting: acked, rejected, expired, discarded, shed.
|
|
80
|
-
t.json :counters, null: false, default: {}
|
|
81
|
-
|
|
82
|
-
t.timestamps
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
add_index :export_destinations, :url_sha256, unique: true, if_not_exists: true
|
|
86
|
-
add_index :export_destinations, :producer_id, unique: true, if_not_exists: true
|
|
87
|
-
|
|
88
|
-
create_table :export_deliveries, if_not_exists: true do |t|
|
|
89
|
-
t.references :export_destination, null: false, foreign_key: true
|
|
90
|
-
# A UUIDv7: its embedded time is how the receiver ages it out, so a
|
|
91
|
-
# delivery cannot be made young again by relabelling it.
|
|
92
|
-
t.string :delivery_id, limit: 36, null: false
|
|
93
|
-
# What this delivery is a delivery OF. One per source batch today; a
|
|
94
|
-
# future policy that selects across batches supplies its own key.
|
|
95
|
-
t.string :selection_key, limit: 160, null: false
|
|
96
|
-
|
|
97
|
-
t.binary :body
|
|
98
|
-
t.string :body_sha256, limit: 64, null: false
|
|
99
|
-
t.string :metadata_sha256, limit: 64, null: false
|
|
100
|
-
t.bigint :body_bytes, null: false
|
|
101
|
-
t.bigint :ndjson_bytes, null: false
|
|
102
|
-
t.integer :record_count, null: false
|
|
103
|
-
# Everything about the delivery that is not its body: version, drop
|
|
104
|
-
# counts, backpressure. Digested into metadata_sha256 so the same id
|
|
105
|
-
# arriving with different counts is a conflict, not an update.
|
|
106
|
-
t.json :wire_metadata, null: false, default: {}
|
|
107
|
-
|
|
108
|
-
t.string :state, limit: 8, null: false, default: "pending"
|
|
109
|
-
# Set only when done: acked, rejected, expired, discarded.
|
|
110
|
-
t.string :disposition, limit: 16
|
|
111
|
-
t.datetime :enqueued_at, null: false, precision: 6
|
|
112
|
-
t.datetime :expires_at, null: false, precision: 6
|
|
113
|
-
t.datetime :next_attempt_at, null: false, precision: 6
|
|
114
|
-
t.bigint :attempts, null: false, default: 0
|
|
115
|
-
|
|
116
|
-
t.string :claim_token, limit: 36
|
|
117
|
-
t.bigint :claim_generation
|
|
118
|
-
t.datetime :claim_expires_at, precision: 6
|
|
119
|
-
|
|
120
|
-
t.integer :last_status
|
|
121
|
-
t.string :last_reason, limit: 64
|
|
122
|
-
t.json :ack
|
|
123
|
-
t.datetime :finished_at, precision: 6
|
|
124
|
-
|
|
125
|
-
t.timestamps
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
add_index :export_deliveries, %i[export_destination_id delivery_id], unique: true,
|
|
129
|
-
name: "index_export_deliveries_on_destination_and_delivery", if_not_exists: true
|
|
130
|
-
# One delivery per selection: a batch replayed into the same transaction
|
|
131
|
-
# cannot enqueue itself twice.
|
|
132
|
-
add_index :export_deliveries, %i[export_destination_id selection_key], unique: true,
|
|
133
|
-
name: "index_export_deliveries_on_destination_and_selection", if_not_exists: true
|
|
134
|
-
add_index :export_deliveries, %i[export_destination_id id], where: "state <> 'done'",
|
|
135
|
-
name: "index_export_deliveries_live", if_not_exists: true
|
|
136
|
-
add_index :export_deliveries, :expires_at, where: "body IS NOT NULL",
|
|
137
|
-
name: "index_export_deliveries_expiring", if_not_exists: true
|
|
138
|
-
add_index :export_deliveries, :finished_at, where: "state = 'done'",
|
|
139
|
-
name: "index_export_deliveries_finished", if_not_exists: true
|
|
140
|
-
|
|
141
|
-
# Why a batch did or did not enqueue anything. Null on every row an
|
|
142
|
-
# install without export ever writes.
|
|
143
|
-
add_column :ingest_batches, :export_disposition, :string, limit: 24, if_not_exists: true
|
|
144
|
-
add_column :ingest_batches, :export_record_count, :bigint, if_not_exists: true
|
|
145
|
-
end
|
|
146
|
-
end
|
data/db/railwatch_telemetry_migrate/20260922000000_add_covering_indexes_for_dashboard_aggregates.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Two dashboard aggregates read every row in the window and only a few
|
|
4
|
-
# narrow columns of each: the Jobs page's per-queue breakdown and the
|
|
5
|
-
# Processes page's health series. Through (kind, occurred_at) and
|
|
6
|
-
# (sampled_at) SQLite finds the rows in order but then fetches each one
|
|
7
|
-
# from the table, and on a telemetry file much larger than memory those
|
|
8
|
-
# rows are scattered pages on disk. On the platform's own 30 GB tenant,
|
|
9
|
-
# over a week: 38 s for the queue breakdown (491,000 job attempts) and
|
|
10
|
-
# 19 s for the health series (263,000 samples), with the GVL held the
|
|
11
|
-
# whole time, so every other request in the process waited too.
|
|
12
|
-
#
|
|
13
|
-
# Both indexes carry every column their query reads, so the whole answer
|
|
14
|
-
# comes from one contiguous index range: 335 ms and 370 ms on a copy of
|
|
15
|
-
# the same file. They cost 151 MB and 29 MB there, and took 13 s and 2 s
|
|
16
|
-
# to build.
|
|
17
|
-
#
|
|
18
|
-
# broadcasts is the one windowed table with no index led by occurred_at,
|
|
19
|
-
# so the Broadcasts page's "recent" list sorted the whole window to show
|
|
20
|
-
# 100 rows. Every other raw table has had this index since it was created.
|
|
21
|
-
#
|
|
22
|
-
# Free-text search over jobs and requests also matches the exception
|
|
23
|
-
# preview, which only a failed execution carries (15 of 491,000 job
|
|
24
|
-
# attempts in that same week). A partial index over just those rows lets
|
|
25
|
-
# Execution.named_like seek them instead of reading the window.
|
|
26
|
-
class AddCoveringIndexesForDashboardAggregates < ActiveRecord::Migration[8.1]
|
|
27
|
-
def change
|
|
28
|
-
add_index :executions, [ :kind, :occurred_at, :queue, :outcome, :queue_latency ], name: "idx_executions_queue_stats", if_not_exists: true
|
|
29
|
-
add_index :health_samples, [ :sampled_at, :threads_max, :threads_busy, :backlog, :queue_depth, :queue_latency ],
|
|
30
|
-
name: "idx_health_samples_series", if_not_exists: true
|
|
31
|
-
add_index :broadcasts, :occurred_at, if_not_exists: true
|
|
32
|
-
add_index :executions, [ :kind, :occurred_at ], name: "idx_executions_with_preview", where: "exception_preview IS NOT NULL", if_not_exists: true
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The People page groups the window's signed-in requests by user_ref.
|
|
4
|
-
# Through (user_ref, occurred_at) SQLite found those rows but fetched each
|
|
5
|
-
# one from the table for kind and status: 4 s over 30 days on the
|
|
6
|
-
# platform's own tenant, where 18,000 of 2.8 million executions carry a
|
|
7
|
-
# user. This index holds every column the query reads, and only for rows
|
|
8
|
-
# that have a user, so it answers in 18 ms from under a megabyte. It took
|
|
9
|
-
# 10 s to build on a copy of that 30 GB file.
|
|
10
|
-
class AddPeopleIndex < ActiveRecord::Migration[8.1]
|
|
11
|
-
def change
|
|
12
|
-
add_index :executions, [ :user_ref, :kind, :occurred_at, :status ], name: "idx_executions_people",
|
|
13
|
-
where: "user_ref IS NOT NULL", if_not_exists: true
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# The Tenants page and MCP's list_tenants sum every tenant-tagged request
|
|
4
|
-
# and job in the window per tenant. Through (app_tenant, occurred_at)
|
|
5
|
-
# SQLite finds the rows but fetches each from the table for kind, status,
|
|
6
|
-
# outcome, duration and user_ref: 8.1 s over 30 days on rebulk-system
|
|
7
|
-
# (358,000 tagged requests), and 24 s once in production, which held the
|
|
8
|
-
# web process -- and every ingest request queued behind it -- the whole
|
|
9
|
-
# time. This index carries every column those aggregates read, only for
|
|
10
|
-
# tagged rows: 131 ms for the same query, 41 MB, 1.6 s to build on a copy
|
|
11
|
-
# of that 16 GB file. An untagged app gets an empty index.
|
|
12
|
-
class AddTenantSummaryIndex < ActiveRecord::Migration[8.1]
|
|
13
|
-
def change
|
|
14
|
-
add_index :executions, [ :kind, :app_tenant, :occurred_at, :status, :outcome, :duration, :user_ref ],
|
|
15
|
-
name: "idx_executions_tenant_summary", where: "app_tenant IS NOT NULL", if_not_exists: true
|
|
16
|
-
end
|
|
17
|
-
end
|
data/db/railwatch_telemetry_migrate/20261008000000_add_in_transaction_to_outgoing_requests.rb
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# An outgoing HTTP call made while the execution held a database transaction
|
|
4
|
-
# open: the transaction (and on SQLite with BEGIN IMMEDIATE, the writer lock)
|
|
5
|
-
# stays held for the whole round trip. Same meaning as queries.in_transaction.
|
|
6
|
-
class AddInTransactionToOutgoingRequests < ActiveRecord::Migration[8.1]
|
|
7
|
-
def change
|
|
8
|
-
add_column :outgoing_requests, :in_transaction, :boolean, default: false
|
|
9
|
-
end
|
|
10
|
-
end
|