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.
Files changed (454) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +37 -33
  3. data/CHANGELOG.md +66 -0
  4. data/README.md +51 -60
  5. data/config/routes.rb +0 -59
  6. data/docs/ai-and-mcp.md +9 -8
  7. data/docs/configuration.md +57 -71
  8. data/docs/faq.md +17 -25
  9. data/docs/getting-started.md +105 -117
  10. data/docs/replacing-nightwatch.md +8 -7
  11. data/docs/replacing-sentry.md +12 -16
  12. data/docs/security.md +14 -20
  13. data/docs/self-hosting.md +24 -22
  14. data/docs/testing.md +6 -14
  15. data/docs/troubleshooting.md +12 -46
  16. data/lib/generators/railwatch/install/install_generator.rb +12 -240
  17. data/lib/generators/railwatch/install/templates/initializer.rb.tt +10 -40
  18. data/lib/generators/railwatch/install/templates/post-deploy +0 -7
  19. data/lib/railwatch/authentication.rb +6 -5
  20. data/lib/railwatch/buffer.rb +9 -0
  21. data/lib/railwatch/configuration.rb +21 -151
  22. data/lib/railwatch/engine.rb +9 -118
  23. data/lib/railwatch/patches.rb +0 -11
  24. data/lib/railwatch/reporter.rb +92 -21
  25. data/lib/railwatch/sampler.rb +10 -2
  26. data/lib/railwatch/subscribers/process_info.rb +1 -2
  27. data/lib/railwatch/version.rb +1 -1
  28. data/lib/railwatch.rb +8 -64
  29. data/lib/tasks/railwatch_tasks.rake +3 -325
  30. data/llms.txt +23 -25
  31. metadata +3 -453
  32. data/app/channels/railwatch/environment_channel.rb +0 -62
  33. data/app/controllers/concerns/railwatch/telemetry_identity.rb +0 -25
  34. data/app/controllers/railwatch/alerts_controller.rb +0 -48
  35. data/app/controllers/railwatch/anomaly_rules_controller.rb +0 -31
  36. data/app/controllers/railwatch/attachments_controller.rb +0 -22
  37. data/app/controllers/railwatch/broadcasts_controller.rb +0 -15
  38. data/app/controllers/railwatch/cache_events_controller.rb +0 -30
  39. data/app/controllers/railwatch/commands_controller.rb +0 -16
  40. data/app/controllers/railwatch/comments_controller.rb +0 -11
  41. data/app/controllers/railwatch/dashboard_controller.rb +0 -70
  42. data/app/controllers/railwatch/deploys_controller.rb +0 -34
  43. data/app/controllers/railwatch/deprecations_controller.rb +0 -54
  44. data/app/controllers/railwatch/environment_scoped.rb +0 -81
  45. data/app/controllers/railwatch/exceptions_controller.rb +0 -52
  46. data/app/controllers/railwatch/executions_controller.rb +0 -13
  47. data/app/controllers/railwatch/issues_controller.rb +0 -258
  48. data/app/controllers/railwatch/jobs_controller.rb +0 -63
  49. data/app/controllers/railwatch/llm_calls_controller.rb +0 -124
  50. data/app/controllers/railwatch/logs_controller.rb +0 -40
  51. data/app/controllers/railwatch/mails_controller.rb +0 -19
  52. data/app/controllers/railwatch/notifications_controller.rb +0 -11
  53. data/app/controllers/railwatch/outgoing_requests_controller.rb +0 -19
  54. data/app/controllers/railwatch/overview_controller.rb +0 -38
  55. data/app/controllers/railwatch/people_controller.rb +0 -25
  56. data/app/controllers/railwatch/processes_controller.rb +0 -33
  57. data/app/controllers/railwatch/profiles_controller.rb +0 -65
  58. data/app/controllers/railwatch/queries_controller.rb +0 -59
  59. data/app/controllers/railwatch/releases_controller.rb +0 -75
  60. data/app/controllers/railwatch/requests_controller.rb +0 -37
  61. data/app/controllers/railwatch/saved_views_controller.rb +0 -53
  62. data/app/controllers/railwatch/scheduled_tasks_controller.rb +0 -45
  63. data/app/controllers/railwatch/spans_controller.rb +0 -47
  64. data/app/controllers/railwatch/storage_ops_controller.rb +0 -15
  65. data/app/controllers/railwatch/tenants_controller.rb +0 -44
  66. data/app/controllers/railwatch/thresholds_controller.rb +0 -47
  67. data/app/controllers/railwatch/traces_controller.rb +0 -72
  68. data/app/controllers/railwatch/transactions_controller.rb +0 -21
  69. data/app/controllers/railwatch/view_renders_controller.rb +0 -28
  70. data/app/controllers/railwatch/visits_controller.rb +0 -53
  71. data/app/frontend/components/app-content.tsx +0 -26
  72. data/app/frontend/components/app-logo-icon.tsx +0 -23
  73. data/app/frontend/components/app-logo.tsx +0 -14
  74. data/app/frontend/components/app-shell.tsx +0 -38
  75. data/app/frontend/components/app-sidebar-header.tsx +0 -54
  76. data/app/frontend/components/app-sidebar.tsx +0 -94
  77. data/app/frontend/components/app-wordmark.tsx +0 -29
  78. data/app/frontend/components/breadcrumbs.tsx +0 -46
  79. data/app/frontend/components/icon.tsx +0 -16
  80. data/app/frontend/components/input-error.tsx +0 -18
  81. data/app/frontend/components/nav-footer.tsx +0 -46
  82. data/app/frontend/components/nav-main.tsx +0 -41
  83. data/app/frontend/components/nav-user.tsx +0 -50
  84. data/app/frontend/components/railwatch/chart-hover.tsx +0 -34
  85. data/app/frontend/components/railwatch/chart-panel.tsx +0 -170
  86. data/app/frontend/components/railwatch/code.tsx +0 -28
  87. data/app/frontend/components/railwatch/command-palette.tsx +0 -132
  88. data/app/frontend/components/railwatch/copy-block.tsx +0 -52
  89. data/app/frontend/components/railwatch/copy-id.tsx +0 -49
  90. data/app/frontend/components/railwatch/cursor-load-more.tsx +0 -39
  91. data/app/frontend/components/railwatch/data-table.tsx +0 -195
  92. data/app/frontend/components/railwatch/digit-roll.tsx +0 -312
  93. data/app/frontend/components/railwatch/empty-state.tsx +0 -159
  94. data/app/frontend/components/railwatch/env-nav.tsx +0 -130
  95. data/app/frontend/components/railwatch/env-switcher.tsx +0 -145
  96. data/app/frontend/components/railwatch/filter-bar.tsx +0 -153
  97. data/app/frontend/components/railwatch/flamegraph.tsx +0 -324
  98. data/app/frontend/components/railwatch/frames.tsx +0 -295
  99. data/app/frontend/components/railwatch/json-viewer.tsx +0 -159
  100. data/app/frontend/components/railwatch/live-dot.tsx +0 -78
  101. data/app/frontend/components/railwatch/live-toggle.tsx +0 -76
  102. data/app/frontend/components/railwatch/metric-chart.tsx +0 -112
  103. data/app/frontend/components/railwatch/mobile-page-switcher.tsx +0 -89
  104. data/app/frontend/components/railwatch/onboarding.tsx +0 -91
  105. data/app/frontend/components/railwatch/origin-identity.tsx +0 -84
  106. data/app/frontend/components/railwatch/page-header.tsx +0 -42
  107. data/app/frontend/components/railwatch/percentile-picker.tsx +0 -18
  108. data/app/frontend/components/railwatch/relative-time.tsx +0 -18
  109. data/app/frontend/components/railwatch/saved-views.tsx +0 -232
  110. data/app/frontend/components/railwatch/segmented.tsx +0 -64
  111. data/app/frontend/components/railwatch/series-chart.tsx +0 -400
  112. data/app/frontend/components/railwatch/shortcuts-dialog.tsx +0 -89
  113. data/app/frontend/components/railwatch/signal-toast.tsx +0 -121
  114. data/app/frontend/components/railwatch/sort-header.tsx +0 -37
  115. data/app/frontend/components/railwatch/source-link.tsx +0 -57
  116. data/app/frontend/components/railwatch/sparkline-cell.tsx +0 -14
  117. data/app/frontend/components/railwatch/sql-block.tsx +0 -116
  118. data/app/frontend/components/railwatch/stat.tsx +0 -185
  119. data/app/frontend/components/railwatch/status-badge.tsx +0 -79
  120. data/app/frontend/components/railwatch/step-picker.tsx +0 -57
  121. data/app/frontend/components/railwatch/timeline.tsx +0 -405
  122. data/app/frontend/components/railwatch/utilisation-bar.tsx +0 -44
  123. data/app/frontend/components/railwatch/window-picker.tsx +0 -147
  124. data/app/frontend/components/ui/avatar.tsx +0 -51
  125. data/app/frontend/components/ui/badge.tsx +0 -46
  126. data/app/frontend/components/ui/breadcrumb.tsx +0 -109
  127. data/app/frontend/components/ui/button.tsx +0 -60
  128. data/app/frontend/components/ui/card.tsx +0 -92
  129. data/app/frontend/components/ui/chart.tsx +0 -374
  130. data/app/frontend/components/ui/checkbox.tsx +0 -32
  131. data/app/frontend/components/ui/collapsible.tsx +0 -31
  132. data/app/frontend/components/ui/command.tsx +0 -182
  133. data/app/frontend/components/ui/dialog.tsx +0 -158
  134. data/app/frontend/components/ui/dropdown-menu.tsx +0 -255
  135. data/app/frontend/components/ui/hover-card.tsx +0 -42
  136. data/app/frontend/components/ui/input.tsx +0 -21
  137. data/app/frontend/components/ui/label.tsx +0 -24
  138. data/app/frontend/components/ui/popover.tsx +0 -87
  139. data/app/frontend/components/ui/select.tsx +0 -185
  140. data/app/frontend/components/ui/separator.tsx +0 -28
  141. data/app/frontend/components/ui/sheet.tsx +0 -137
  142. data/app/frontend/components/ui/sidebar.tsx +0 -726
  143. data/app/frontend/components/ui/skeleton.tsx +0 -13
  144. data/app/frontend/components/ui/sonner.tsx +0 -41
  145. data/app/frontend/components/ui/table.tsx +0 -114
  146. data/app/frontend/components/ui/tabs.tsx +0 -91
  147. data/app/frontend/components/ui/textarea.tsx +0 -18
  148. data/app/frontend/components/ui/tooltip.tsx +0 -61
  149. data/app/frontend/components/user-info.tsx +0 -32
  150. data/app/frontend/components/user-menu-content.tsx +0 -94
  151. data/app/frontend/entrypoints/application.css +0 -244
  152. data/app/frontend/entrypoints/inertia.tsx +0 -92
  153. data/app/frontend/fonts/CommitMono-Bold.woff2 +0 -0
  154. data/app/frontend/fonts/CommitMono-Regular.woff2 +0 -0
  155. data/app/frontend/fonts/Roboto-Black.woff2 +0 -0
  156. data/app/frontend/fonts/Roboto-Bold.woff2 +0 -0
  157. data/app/frontend/fonts/Roboto-Medium.woff2 +0 -0
  158. data/app/frontend/fonts/Roboto-Regular.woff2 +0 -0
  159. data/app/frontend/hooks/use-appearance.tsx +0 -67
  160. data/app/frontend/hooks/use-clipboard.ts +0 -32
  161. data/app/frontend/hooks/use-flash.tsx +0 -23
  162. data/app/frontend/hooks/use-hotkeys.ts +0 -63
  163. data/app/frontend/hooks/use-initials.tsx +0 -15
  164. data/app/frontend/hooks/use-live.ts +0 -205
  165. data/app/frontend/hooks/use-mobile-navigation.ts +0 -8
  166. data/app/frontend/hooks/use-mobile.ts +0 -21
  167. data/app/frontend/hooks/use-percentile.ts +0 -24
  168. data/app/frontend/hooks/use-reduced-motion.ts +0 -25
  169. data/app/frontend/hooks/use-row-nav.ts +0 -106
  170. data/app/frontend/hooks/use-step.ts +0 -27
  171. data/app/frontend/hooks/use-ticker.ts +0 -12
  172. data/app/frontend/hooks/use-window.ts +0 -58
  173. data/app/frontend/layouts/app/app-sidebar-layout.tsx +0 -107
  174. data/app/frontend/layouts/app-layout.tsx +0 -21
  175. data/app/frontend/layouts/env-layout.tsx +0 -53
  176. data/app/frontend/layouts/persistent-layout.tsx +0 -18
  177. data/app/frontend/lib/cable.ts +0 -10
  178. data/app/frontend/lib/env-pages.ts +0 -236
  179. data/app/frontend/lib/execution-path.ts +0 -55
  180. data/app/frontend/lib/explain.ts +0 -50
  181. data/app/frontend/lib/filter.ts +0 -25
  182. data/app/frontend/lib/flamegraph.ts +0 -155
  183. data/app/frontend/lib/format.ts +0 -71
  184. data/app/frontend/lib/keyboard.ts +0 -18
  185. data/app/frontend/lib/mount.ts +0 -23
  186. data/app/frontend/lib/source-link.ts +0 -217
  187. data/app/frontend/lib/utils.ts +0 -6
  188. data/app/frontend/pages/alerts/index.tsx +0 -171
  189. data/app/frontend/pages/broadcasts/index.tsx +0 -171
  190. data/app/frontend/pages/cache_events/index.tsx +0 -127
  191. data/app/frontend/pages/commands/index.tsx +0 -143
  192. data/app/frontend/pages/deploys/index.tsx +0 -94
  193. data/app/frontend/pages/deploys/show.tsx +0 -309
  194. data/app/frontend/pages/deprecations/index.tsx +0 -176
  195. data/app/frontend/pages/exceptions/index.tsx +0 -271
  196. data/app/frontend/pages/executions/show.tsx +0 -821
  197. data/app/frontend/pages/issues/index.tsx +0 -399
  198. data/app/frontend/pages/issues/show.tsx +0 -1367
  199. data/app/frontend/pages/jobs/index.tsx +0 -381
  200. data/app/frontend/pages/jobs/klass.tsx +0 -215
  201. data/app/frontend/pages/llm_calls/index.tsx +0 -664
  202. data/app/frontend/pages/logs/index.tsx +0 -303
  203. data/app/frontend/pages/mails/index.tsx +0 -218
  204. data/app/frontend/pages/notifications/index.tsx +0 -161
  205. data/app/frontend/pages/outgoing_requests/index.tsx +0 -309
  206. data/app/frontend/pages/overview/show.tsx +0 -333
  207. data/app/frontend/pages/people/index.tsx +0 -102
  208. data/app/frontend/pages/people/show.tsx +0 -149
  209. data/app/frontend/pages/processes/index.tsx +0 -335
  210. data/app/frontend/pages/profiles/index.tsx +0 -110
  211. data/app/frontend/pages/profiles/show.tsx +0 -105
  212. data/app/frontend/pages/queries/index.tsx +0 -492
  213. data/app/frontend/pages/queries/show.tsx +0 -276
  214. data/app/frontend/pages/releases/index.tsx +0 -190
  215. data/app/frontend/pages/releases/release-health.tsx +0 -68
  216. data/app/frontend/pages/releases/release-path.ts +0 -25
  217. data/app/frontend/pages/releases/show.tsx +0 -262
  218. data/app/frontend/pages/requests/index.tsx +0 -235
  219. data/app/frontend/pages/requests/route.tsx +0 -159
  220. data/app/frontend/pages/scheduled_tasks/index.tsx +0 -220
  221. data/app/frontend/pages/spans/index.tsx +0 -229
  222. data/app/frontend/pages/spans/show.tsx +0 -220
  223. data/app/frontend/pages/storage_ops/index.tsx +0 -150
  224. data/app/frontend/pages/tenants/index.tsx +0 -236
  225. data/app/frontend/pages/tenants/show.tsx +0 -477
  226. data/app/frontend/pages/tenants/tenant-path.ts +0 -26
  227. data/app/frontend/pages/thresholds/index.tsx +0 -414
  228. data/app/frontend/pages/traces/show.tsx +0 -208
  229. data/app/frontend/pages/transactions/index.tsx +0 -220
  230. data/app/frontend/pages/view_renders/index.tsx +0 -241
  231. data/app/frontend/pages/visits/index.tsx +0 -321
  232. data/app/frontend/public/icon.png +0 -0
  233. data/app/frontend/public/icon.svg +0 -5
  234. data/app/frontend/routes/index.d.ts +0 -2136
  235. data/app/frontend/routes/index.js +0 -2112
  236. data/app/frontend/types/globals.d.ts +0 -9
  237. data/app/frontend/types/index.ts +0 -288
  238. data/app/frontend/types/vite-env.d.ts +0 -9
  239. data/app/helpers/railwatch/assets_helper.rb +0 -52
  240. data/app/jobs/railwatch/anomaly_scan_job.rb +0 -11
  241. data/app/jobs/railwatch/application_job.rb +0 -7
  242. data/app/jobs/railwatch/auto_resolve_issues_job.rb +0 -19
  243. data/app/jobs/railwatch/check_scheduled_tasks_job.rb +0 -113
  244. data/app/jobs/railwatch/detect_anomalies_job.rb +0 -171
  245. data/app/jobs/railwatch/detect_performance_issues_job.rb +0 -95
  246. data/app/jobs/railwatch/group_exceptions_job.rb +0 -91
  247. data/app/jobs/railwatch/optimize_telemetry_job.rb +0 -23
  248. data/app/jobs/railwatch/performance_scan_job.rb +0 -11
  249. data/app/jobs/railwatch/prune_telemetry_job.rb +0 -129
  250. data/app/jobs/railwatch/release_health_rollup_job.rb +0 -64
  251. data/app/jobs/railwatch/rollup_catchup_job.rb +0 -21
  252. data/app/jobs/railwatch/rollup_job.rb +0 -132
  253. data/app/jobs/railwatch/scheduled_task_scan_job.rb +0 -11
  254. data/app/models/concerns/railwatch/detection_snapshotting.rb +0 -20
  255. data/app/models/railwatch/alert.rb +0 -229
  256. data/app/models/railwatch/alert_rule.rb +0 -121
  257. data/app/models/railwatch/anomaly_rule.rb +0 -51
  258. data/app/models/railwatch/application.rb +0 -44
  259. data/app/models/railwatch/application_record.rb +0 -33
  260. data/app/models/railwatch/comment.rb +0 -36
  261. data/app/models/railwatch/deploy.rb +0 -67
  262. data/app/models/railwatch/environment.rb +0 -68
  263. data/app/models/railwatch/execution_presenter.rb +0 -185
  264. data/app/models/railwatch/filter_query.rb +0 -184
  265. data/app/models/railwatch/followup_receipt.rb +0 -27
  266. data/app/models/railwatch/ingest/batch.rb +0 -355
  267. data/app/models/railwatch/ingest/mapper.rb +0 -585
  268. data/app/models/railwatch/ingest/payload.rb +0 -96
  269. data/app/models/railwatch/ingest/rollup_absorber.rb +0 -170
  270. data/app/models/railwatch/ingest/writer.rb +0 -137
  271. data/app/models/railwatch/issue.rb +0 -277
  272. data/app/models/railwatch/issue_activity.rb +0 -23
  273. data/app/models/railwatch/issue_detection_presenter.rb +0 -309
  274. data/app/models/railwatch/issue_detection_snapshot.rb +0 -77
  275. data/app/models/railwatch/maintenance_task.rb +0 -53
  276. data/app/models/railwatch/saved_view.rb +0 -63
  277. data/app/models/railwatch/telemetry/aggregations.rb +0 -251
  278. data/app/models/railwatch/telemetry/attachment.rb +0 -31
  279. data/app/models/railwatch/telemetry/bounded_gzip.rb +0 -101
  280. data/app/models/railwatch/telemetry/broadcast.rb +0 -13
  281. data/app/models/railwatch/telemetry/cache_event.rb +0 -16
  282. data/app/models/railwatch/telemetry/child.rb +0 -53
  283. data/app/models/railwatch/telemetry/cursor_page.rb +0 -99
  284. data/app/models/railwatch/telemetry/deprecation.rb +0 -13
  285. data/app/models/railwatch/telemetry/enqueued_job.rb +0 -13
  286. data/app/models/railwatch/telemetry/exception.rb +0 -28
  287. data/app/models/railwatch/telemetry/execution.rb +0 -152
  288. data/app/models/railwatch/telemetry/export_delivery.rb +0 -32
  289. data/app/models/railwatch/telemetry/export_destination.rb +0 -66
  290. data/app/models/railwatch/telemetry/health_sample.rb +0 -72
  291. data/app/models/railwatch/telemetry/ingest_batch.rb +0 -31
  292. data/app/models/railwatch/telemetry/llm_call.rb +0 -37
  293. data/app/models/railwatch/telemetry/log.rb +0 -91
  294. data/app/models/railwatch/telemetry/mail.rb +0 -13
  295. data/app/models/railwatch/telemetry/n_plus_one.rb +0 -92
  296. data/app/models/railwatch/telemetry/notification.rb +0 -13
  297. data/app/models/railwatch/telemetry/outgoing_request.rb +0 -13
  298. data/app/models/railwatch/telemetry/person.rb +0 -50
  299. data/app/models/railwatch/telemetry/process.rb +0 -10
  300. data/app/models/railwatch/telemetry/profile.rb +0 -37
  301. data/app/models/railwatch/telemetry/query.rb +0 -57
  302. data/app/models/railwatch/telemetry/query_shape.rb +0 -45
  303. data/app/models/railwatch/telemetry/release_health.rb +0 -69
  304. data/app/models/railwatch/telemetry/rollup.rb +0 -157
  305. data/app/models/railwatch/telemetry/session.rb +0 -24
  306. data/app/models/railwatch/telemetry/span.rb +0 -19
  307. data/app/models/railwatch/telemetry/storage_op.rb +0 -13
  308. data/app/models/railwatch/telemetry/tenant.rb +0 -240
  309. data/app/models/railwatch/telemetry/transaction.rb +0 -13
  310. data/app/models/railwatch/telemetry/view_render.rb +0 -13
  311. data/app/models/railwatch/telemetry/visit.rb +0 -24
  312. data/app/models/railwatch/telemetry_record.rb +0 -107
  313. data/app/models/railwatch/threshold.rb +0 -66
  314. data/app/models/railwatch/user.rb +0 -47
  315. data/app/models/railwatch/viewer.rb +0 -13
  316. data/app/models/railwatch/window.rb +0 -66
  317. data/app/views/layouts/railwatch/dashboard.html.erb +0 -25
  318. data/db/railwatch_migrate/20260916000000_create_railwatch_tables.rb +0 -151
  319. data/db/railwatch_migrate/20260917000000_create_railwatch_maintenance_tasks.rb +0 -18
  320. data/db/railwatch_migrate/20260917120000_create_railwatch_followup_receipts.rb +0 -20
  321. data/db/railwatch_migrate/20260918120000_widen_host_user_ids.rb +0 -71
  322. data/db/railwatch_telemetry_migrate/20260903000000_enable_incremental_vacuum.rb +0 -62
  323. data/db/railwatch_telemetry_migrate/20260903000001_create_telemetry.rb +0 -481
  324. data/db/railwatch_telemetry_migrate/20260903000002_rename_tenant_to_app_tenant.rb +0 -14
  325. data/db/railwatch_telemetry_migrate/20260903000003_add_statement_count_to_transactions.rb +0 -9
  326. data/db/railwatch_telemetry_migrate/20260903000004_add_role_and_channel.rb +0 -10
  327. data/db/railwatch_telemetry_migrate/20260903000005_add_locals_to_exceptions.rb +0 -9
  328. data/db/railwatch_telemetry_migrate/20260903000006_add_spans_health_vitals_and_fts.rb +0 -82
  329. data/db/railwatch_telemetry_migrate/20260903000007_rename_span_attributes_to_payload.rb +0 -10
  330. data/db/railwatch_telemetry_migrate/20260903000008_add_profiles_and_attachments.rb +0 -60
  331. data/db/railwatch_telemetry_migrate/20260903000009_add_truncated_to_attachments.rb +0 -9
  332. data/db/railwatch_telemetry_migrate/20260903000010_create_sessions_and_release_health.rb +0 -51
  333. data/db/railwatch_telemetry_migrate/20260903000011_add_fingerprint_to_exceptions.rb +0 -11
  334. data/db/railwatch_telemetry_migrate/20260904000012_add_failed_to_broadcasts.rb +0 -10
  335. data/db/railwatch_telemetry_migrate/20260904010000_add_filter_cursor_indexes.rb +0 -37
  336. data/db/railwatch_telemetry_migrate/20260904020000_add_n_plus_ones_execution_id_index.rb +0 -11
  337. data/db/railwatch_telemetry_migrate/20260904120000_create_query_shapes.rb +0 -15
  338. data/db/railwatch_telemetry_migrate/20260906120000_add_backpressure_factor_to_ingest_batches.rb +0 -9
  339. data/db/railwatch_telemetry_migrate/20260907000000_rename_lantern_version_on_processes.rb +0 -10
  340. data/db/railwatch_telemetry_migrate/20260913000000_rename_nightrail_version_on_processes.rb +0 -9
  341. data/db/railwatch_telemetry_migrate/20260914000000_drop_orphan_durable_ingest_tables.rb +0 -18
  342. data/db/railwatch_telemetry_migrate/20260914010000_drop_orphan_durable_ingest_columns.rb +0 -25
  343. data/db/railwatch_telemetry_migrate/20260915000000_create_llm_calls.rb +0 -55
  344. data/db/railwatch_telemetry_migrate/20260915120000_add_detail_to_llm_calls.rb +0 -21
  345. data/db/railwatch_telemetry_migrate/20260915200000_add_explained_index_to_queries.rb +0 -16
  346. data/db/railwatch_telemetry_migrate/20260915210000_add_slowest_index_to_queries.rb +0 -18
  347. data/db/railwatch_telemetry_migrate/20260917010000_add_batch_ledger_to_ingest_batches.rb +0 -16
  348. data/db/railwatch_telemetry_migrate/20260919000100_create_export_queue.rb +0 -146
  349. data/db/railwatch_telemetry_migrate/20260922000000_add_covering_indexes_for_dashboard_aggregates.rb +0 -34
  350. data/db/railwatch_telemetry_migrate/20260923000000_add_people_index.rb +0 -15
  351. data/db/railwatch_telemetry_migrate/20260925000000_add_tenant_summary_index.rb +0 -17
  352. data/db/railwatch_telemetry_migrate/20261008000000_add_in_transaction_to_outgoing_requests.rb +0 -10
  353. data/docs/embedded.md +0 -503
  354. data/lib/puma/plugin/railwatch.rb +0 -215
  355. data/lib/railwatch/dashboard_assets.rb +0 -45
  356. data/lib/railwatch/embedded.rb +0 -50
  357. data/lib/railwatch/export/client.rb +0 -124
  358. data/lib/railwatch/export/lease.rb +0 -56
  359. data/lib/railwatch/export/outbox.rb +0 -361
  360. data/lib/railwatch/export/policy.rb +0 -79
  361. data/lib/railwatch/export/sender.rb +0 -130
  362. data/lib/railwatch/ingest_request_body_limit.rb +0 -10
  363. data/lib/railwatch/maintenance.rb +0 -194
  364. data/lib/railwatch/patches/migration_busy_timeout.rb +0 -73
  365. data/lib/railwatch/transport/local.rb +0 -78
  366. data/lib/railwatch/transport/socket.rb +0 -183
  367. data/lib/railwatch/writer.rb +0 -370
  368. data/public/railwatch/assets/CommitMono-Bold-D6h61ieg.woff2 +0 -0
  369. data/public/railwatch/assets/CommitMono-Regular-zr8w7Obm.woff2 +0 -0
  370. data/public/railwatch/assets/Roboto-Black-auA4GeOK.woff2 +0 -0
  371. data/public/railwatch/assets/Roboto-Bold-CJLnO8j1.woff2 +0 -0
  372. data/public/railwatch/assets/Roboto-Medium-Cm2bwKpj.woff2 +0 -0
  373. data/public/railwatch/assets/Roboto-Regular-Chaq1-PV.woff2 +0 -0
  374. data/public/railwatch/assets/app-layout-by7G3sa1.js +0 -41
  375. data/public/railwatch/assets/application-Cc5v_Vk9.css +0 -1
  376. data/public/railwatch/assets/arrow-up-DCZ7emux.js +0 -1
  377. data/public/railwatch/assets/braces-CykT5_5u.js +0 -1
  378. data/public/railwatch/assets/card-C-PPSA0g.js +0 -1
  379. data/public/railwatch/assets/chart-Cov79YC5.js +0 -39
  380. data/public/railwatch/assets/chart-hover-DdK4E-2h.js +0 -1
  381. data/public/railwatch/assets/chart-panel-BPaYRXJB.js +0 -1
  382. data/public/railwatch/assets/code-BYjC4YZ_.js +0 -1
  383. data/public/railwatch/assets/copy-id-LPfoj9cC.js +0 -1
  384. data/public/railwatch/assets/cursor-load-more-DSdhgpGl.js +0 -1
  385. data/public/railwatch/assets/data-table-CQ_YRWQs.js +0 -1
  386. data/public/railwatch/assets/env-layout-CdMWbUkm.js +0 -1
  387. data/public/railwatch/assets/execution-path-7MYt-Qbn.js +0 -1
  388. data/public/railwatch/assets/filter-bar-CrzpQ_vD.js +0 -1
  389. data/public/railwatch/assets/flamegraph-BIFEdTAg.js +0 -2
  390. data/public/railwatch/assets/format-B9SDkrWj.js +0 -1
  391. data/public/railwatch/assets/frames-C5t-x4f0.js +0 -1
  392. data/public/railwatch/assets/index--NQ7us-L.js +0 -1
  393. data/public/railwatch/assets/index-2kgYe_99.js +0 -1
  394. data/public/railwatch/assets/index-4YEPHxtO.js +0 -1
  395. data/public/railwatch/assets/index-AOCC1GDJ.js +0 -1
  396. data/public/railwatch/assets/index-BEo-u0eO.js +0 -1
  397. data/public/railwatch/assets/index-BJ1V3w2N.js +0 -1
  398. data/public/railwatch/assets/index-BPoHsBKb.js +0 -1
  399. data/public/railwatch/assets/index-BZzyGUM3.js +0 -1
  400. data/public/railwatch/assets/index-BgVq7yKL.js +0 -1
  401. data/public/railwatch/assets/index-BqFGEZvW.js +0 -1
  402. data/public/railwatch/assets/index-ByuHJ1CH.js +0 -1
  403. data/public/railwatch/assets/index-C2j50AL2.js +0 -1
  404. data/public/railwatch/assets/index-CLEdTkvW.js +0 -1
  405. data/public/railwatch/assets/index-CWgq8qBu.js +0 -1
  406. data/public/railwatch/assets/index-CXQ7_oVj.js +0 -2
  407. data/public/railwatch/assets/index-CmyYrjS2.js +0 -1
  408. data/public/railwatch/assets/index-Cn9_HjDo.js +0 -1
  409. data/public/railwatch/assets/index-CsMAm9UK.js +0 -1
  410. data/public/railwatch/assets/index-D0Kk_oGY.js +0 -1
  411. data/public/railwatch/assets/index-DC9ZptJh.js +0 -1
  412. data/public/railwatch/assets/index-DNzg7jmV.js +0 -1
  413. data/public/railwatch/assets/index-DQ8uJO5f.js +0 -1
  414. data/public/railwatch/assets/index-Deq14BxB.js +0 -1
  415. data/public/railwatch/assets/index-IaV3Blzp.js +0 -1
  416. data/public/railwatch/assets/index-TYNWcJQs.js +0 -1
  417. data/public/railwatch/assets/index-WonH2fcZ.js +0 -1
  418. data/public/railwatch/assets/index-WxWUaH_d.js +0 -1
  419. data/public/railwatch/assets/index-mUNrl4ky.js +0 -1
  420. data/public/railwatch/assets/inertia-DfNRARuA.js +0 -97
  421. data/public/railwatch/assets/json-viewer-DMsF5glp.js +0 -1
  422. data/public/railwatch/assets/klass-CmHYk5rz.js +0 -1
  423. data/public/railwatch/assets/origin-identity-1R3bqa3R.js +0 -1
  424. data/public/railwatch/assets/percentile-picker-73z5PAps.js +0 -1
  425. data/public/railwatch/assets/relative-time-Dsc_cCdX.js +0 -1
  426. data/public/railwatch/assets/release-health-BV5OaOWd.js +0 -1
  427. data/public/railwatch/assets/route-CWh58C7K.js +0 -1
  428. data/public/railwatch/assets/segmented-DB4zh-Am.js +0 -1
  429. data/public/railwatch/assets/select-DBKjFlOX.js +0 -1
  430. data/public/railwatch/assets/series-chart-BaiDG795.js +0 -1
  431. data/public/railwatch/assets/show-B4ICCFGh.js +0 -1
  432. data/public/railwatch/assets/show-B5lOU9Gv.js +0 -1
  433. data/public/railwatch/assets/show-BYPB74t4.js +0 -2
  434. data/public/railwatch/assets/show-C7A0m2M8.js +0 -1
  435. data/public/railwatch/assets/show-DT5X1zqE.js +0 -1
  436. data/public/railwatch/assets/show-D_NBdXsn.js +0 -2
  437. data/public/railwatch/assets/show-DgPCnRg8.js +0 -1
  438. data/public/railwatch/assets/show-Yl69HF0x.js +0 -1
  439. data/public/railwatch/assets/show-_QxuUQCm.js +0 -3
  440. data/public/railwatch/assets/show-g__jnN36.js +0 -1
  441. data/public/railwatch/assets/show-l4ztfjl9.js +0 -1
  442. data/public/railwatch/assets/sort-header-BcG8ulEH.js +0 -1
  443. data/public/railwatch/assets/source-link-B2183i2-.js +0 -1
  444. data/public/railwatch/assets/sparkline-cell-B47ipscB.js +0 -1
  445. data/public/railwatch/assets/stat-DT2hhsqS.js +0 -1
  446. data/public/railwatch/assets/status-badge-CmbRKlY7.js +0 -1
  447. data/public/railwatch/assets/tenant-path-C4rNGauE.js +0 -1
  448. data/public/railwatch/assets/use-clipboard-oTNeP4ax.js +0 -1
  449. data/public/railwatch/assets/use-live-CLZZj245.js +0 -1
  450. data/public/railwatch/icon.png +0 -0
  451. data/public/railwatch/icon.svg +0 -5
  452. data/public/railwatch/manifest.json +0 -1245
  453. data/public/railwatch/rails-vite.json +0 -1
  454. /data/{app/frontend/lib → lib/generators/railwatch/install/templates}/railwatch.ts +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93de03467c62b34decd8de64008cee94e3032bbbf51d574d65f1271a4261c22a
4
- data.tar.gz: 6a7bb7839ae87ee9a00b94b9404ebe518208470afc77947c5c304966454c0953
3
+ metadata.gz: 336bf2e2440f9d076539faaca52e7d04db59422aeb280250a4c4556e7c6562ea
4
+ data.tar.gz: ea7b81637d1e104faa87e9ceb756cd1af43afb801108335674a508658b9adafa
5
5
  SHA512:
6
- metadata.gz: 94efd4b22a285f4735aeb652450f73e2135f795bb78f4a901b44fb89989769e817571b3768ce3aba4e7a442a29492f48767445b6c8967bd0f77eed4e3e4bed5b
7
- data.tar.gz: 38e2952771cfbf9a359f66000257895e08c0ba47f5144e8084fb5f98af9129904a66d05482896d443c2dd1d3239b0336cde17656dd869635e2ed887b49640dda
6
+ metadata.gz: 2223825b1e9287148a7a4a0707b786b6ac88a4859b1566f4630706b3dffd50b13ef19815e70ffba85aa5669c37925a20895af68e4377098fd51c6250a680431b
7
+ data.tar.gz: 71d620559e2d9fd431ae93fd269bd4b573e13bf23295a4bb98cfa395f720ee3fa94bf0557fe562ae2e7e4492428b22ccdaf82c25c0082485ee2550cf82ee7c5c
data/AGENTS.md CHANGED
@@ -4,9 +4,11 @@ About *using* the `railwatch` gem from a Rails application; copy
4
4
  this into that application's repository. Index of everything else:
5
5
  [`llms.txt`](llms.txt).
6
6
 
7
- Railwatch instruments a Rails app end to end and stores linked telemetry in
8
- two SQLite databases of the app's own (embedded, the default) or sends it to
9
- Railwatch Cloud. Every request, job attempt, scheduled task run, and command is
7
+ Railwatch instruments a Rails app end to end and sends linked telemetry over
8
+ HTTPS to a Railwatch server: Railwatch Cloud (`https://railwatch.rebulk.com`,
9
+ the default), a self-hosted [railwatch-rs](https://github.com/Rebulk/railwatch-rs),
10
+ or the one the [`railwatch-server`](https://github.com/Rebulk/railwatch-server)
11
+ gem runs next to Puma. Every request, job attempt, scheduled task run, and command is
10
12
  an **execution**; every query, cache read, log line, outgoing HTTP call, LLM
11
13
  call, view render, exception, and span is a child of one, linked by
12
14
  `execution_id`/`trace_id`. It never writes to the app's primary database.
@@ -15,40 +17,41 @@ call, view render, exception, and span is a child of one, linked by
15
17
 
16
18
  ```sh
17
19
  bundle add railwatch
18
- bin/rails generate railwatch:install # embedded: dashboard at /railwatch
19
- bin/rails generate railwatch:install --prompt-token --kamal-secrets # or: Railwatch Cloud
20
+ bin/rails generate railwatch:install --prompt-token --kamal-secrets # Railwatch Cloud
21
+ bin/rails generate railwatch:install --url=https://telemetry.example.com # self-hosted railwatch-rs
20
22
  ```
21
23
 
22
- With no flags the install is embedded (see [Embedded mode](docs/embedded.md)):
23
- telemetry stays in two SQLite databases the app owns (`railwatch`,
24
- `railwatch_telemetry`, added to `config/database.yml`), Puma forks one writer
25
- for them (`plugin :railwatch` in `config/puma.rb`), and the dashboard is served
26
- at `/railwatch`. It is open in development and answers 401 elsewhere until
27
- `RAILS_ENV=production bin/rails railwatch:authentication:configure` sets a
28
- password. An exported `RAILWATCH_TOKEN` alone does not change the mode.
29
- `--cloud`, or any of `--prompt-token`, `--token-stdin`, `--url`,
30
- `--kamal-secrets`, sends telemetry to Railwatch Cloud instead.
31
-
32
- Both modes write `config/initializers/railwatch.rb`, mount `Railwatch::Engine`
33
- at `/railwatch`, add the Kamal `post-deploy` hook and the Inertia browser client
34
- where the app has them, and require `railwatch/rspec` (or `railwatch/minitest`)
35
- in the test helper; the cloud install then runs `railwatch:doctor`. A
24
+ The generator writes `config/initializers/railwatch.rb`, mounts
25
+ `Railwatch::Engine` at `/railwatch` (it serves only the browser beacon), adds
26
+ the Kamal `post-deploy` hook and the Inertia browser client where the app has
27
+ them, requires `railwatch/rspec` (or `railwatch/minitest`) in the test helper,
28
+ and runs `railwatch:doctor` (`--no-doctor` skips it). A
36
29
  prompted/stdin/environment token goes into `.env` only when Git confirms that
37
- file is ignored; token values are never printed. Configuration lives only in
38
- that initializer; every option also has a `RAILWATCH_*` environment variable.
39
- An embedded install mirrors to Railwatch Cloud as well with a token and
40
- `c.export_enabled = true`.
30
+ file is ignored; token values are never printed. Without a token the gem is
31
+ inert. Configuration lives only in that initializer; every option also has a
32
+ `RAILWATCH_*` environment variable.
33
+
34
+ Embedded (the dashboard inside the app, no token to manage): add
35
+ `gem "railwatch-server"` to the Gemfile and `plugin :railwatch_server` to
36
+ `config/puma.rb`. It provisions `storage/railwatch/<env>` on first boot and
37
+ points this agent at it. Its dashboard at `/railwatch` is gated by this gem's
38
+ `http_basic_auth_*` settings (open in development, 401 elsewhere until
39
+ `RAILS_ENV=production bin/rails railwatch:authentication:configure` sets a
40
+ password) or, with Basic off, by `c.base_controller_class`.
41
+
42
+ Railwatch 0.x's in-gem embedded mode (`c.transport = :local`, `plugin :railwatch`,
43
+ the `railwatch`/`railwatch_telemetry` databases) is gone in 1.0; remove all three
44
+ and add railwatch-server. Its old SQLite files are not migrated.
41
45
 
42
46
  ## Rake tasks
43
47
 
44
48
  | Task | Does |
45
49
  |---|---|
46
- | `bin/rails railwatch:doctor` | ✓/✗ per check. Embedded: databases, migrations, writer process, last write, maintenance, dashboard access, export. Cloud: token, token storage, ingest URL, reachability. Both: middleware, engine mount, deploy, sample rates, ignored types, Kamal hook, browser client and whether an entrypoint calls it, profiler backend, test matchers. Exits non-zero on a missing database, pending migrations, broken export, a missing or tracked token, or an unreachable host. **Run this first when telemetry is missing.** |
47
- | `bin/rails railwatch:authentication:configure` | Sets the embedded dashboard's HTTP Basic credentials for the current `RAILS_ENV`. |
48
- | `bin/rails railwatch:export:status` | What the export queue holds and whether it can send. |
49
- | `bin/rails railwatch:token` | Where to create a Railwatch Cloud ingest token for this app. |
50
- | `bin/rails railwatch:mcp` | Paste-ready MCP client configuration for this app's Railwatch Cloud. |
51
- | `bin/rails railwatch:deploy[ref,name,url]` | Records a deploy marker (in the embedded database, or on the cloud). Use as a release step when not deploying with Kamal. |
50
+ | `bin/rails railwatch:doctor` | ✓/✗ per check: token, token storage, ingest URL, reachability, middleware, engine mount, deploy, sample rates, ignored types, Kamal hook, browser client and whether an entrypoint calls it, profiler backend, test matchers. Exits non-zero on a missing or tracked token, or an unreachable host. **Run this first when telemetry is missing.** |
51
+ | `bin/rails railwatch:authentication:configure` | Sets the HTTP Basic credentials that gate railwatch-server's dashboard, for the current `RAILS_ENV`. |
52
+ | `bin/rails railwatch:token` | Where to create an ingest token for this app on the server `ingest_url` points at. |
53
+ | `bin/rails railwatch:mcp` | Paste-ready MCP client configuration for that server. |
54
+ | `bin/rails railwatch:deploy[ref,name,url]` | Records a deploy marker on the server. Use as a release step when not deploying with Kamal. |
52
55
  | `bin/rails 'railwatch:sourcemaps[public,true]'` | Uploads Vite source maps for the configured deploy, then deletes acknowledged files. Run after building and before publishing assets. Omit `true` to retain files. See [Source maps](docs/source-maps.md). |
53
56
 
54
57
  ## Facade
@@ -89,9 +92,9 @@ Per action, in a controller class body: `railwatch_sample 0.01, only: :index`,
89
92
  ## Specs
90
93
 
91
94
  `require "railwatch/rspec"` in `spec/rails_helper.rb` (or `"railwatch/minitest"` in
92
- `test/test_helper.rb`). Railwatch must be enabled in the test env: an embedded
93
- install is, and needs `RAILS_ENV=test bin/rails db:prepare` once so its test
94
- databases exist; a cloud install needs any non-blank `RAILWATCH_TOKEN`. Records
95
+ `test/test_helper.rb`). Railwatch must be enabled in the test env, which
96
+ needs any non-blank `RAILWATCH_TOKEN` there (railwatch-server is off in test
97
+ and does not set one). Records
95
98
  go to an in-memory transport, never over the wire. All matchers are block
96
99
  matchers.
97
100
 
@@ -117,7 +120,8 @@ melt in production.
117
120
 
118
121
  ## MCP
119
122
 
120
- Railwatch Cloud (not embedded mode) is an MCP server at `<ingest host>/mcp`.
123
+ Railwatch Cloud and railwatch-rs are MCP servers at `<ingest host>/mcp`
124
+ (with railwatch-server: the app's host plus `/railwatch/mcp`).
121
125
  Generate a personal token at Settings → Profile → "API & MCP token", then:
122
126
 
123
127
  ```sh
data/CHANGELOG.md CHANGED
@@ -6,6 +6,72 @@
6
6
  filled in by the release commit, which is also the only commit that
7
7
  touches lib/railwatch/version.rb and Gemfile.lock. See CONTRIBUTING.md. -->
8
8
 
9
+ ## 1.0.0 (2026-10-22)
10
+
11
+ - **Breaking: `railwatch` is the agent only.** It instruments the app and
12
+ sends to an ingest URL: Railwatch Cloud (the default,
13
+ `https://railwatch.rebulk.com`) or a self-hosted
14
+ [railwatch-rs](https://github.com/Rebulk/railwatch-rs) server
15
+ (`RAILWATCH_INGEST_URL`, `RAILWATCH_TOKEN`). Embedded mode is gone from
16
+ this gem: `transport :local` / `RAILWATCH_TRANSPORT`, the two SQLite
17
+ databases (`railwatch`, `railwatch_telemetry`) and their migrations, the
18
+ Puma writer (`plugin :railwatch`), the maintenance clock, export to the
19
+ cloud, the dashboard pages, its live channel and its compiled bundle.
20
+ The dashboard is part of the server now, and the gem has no runtime
21
+ dependency on `inertia_rails` or `tdigest`.
22
+ - The dashboard inside the app is the separate
23
+ [railwatch-server](https://github.com/Rebulk/railwatch-server) gem. It
24
+ runs the railwatch-rs server next to Puma and points this agent at it.
25
+ - Removed settings: `transport`, `issue_prefix`, `repository_url`,
26
+ `retention_days`, `dashboard_user`, `dashboard_open`, `writer_socket`,
27
+ `migration_busy_timeout`, and every `export_*`, with their
28
+ `RAILWATCH_*` variables. Removed rake tasks: `railwatch:vacuum`,
29
+ `railwatch:vacuum:status`, `railwatch:export:status`, `:rebind` and
30
+ `:discard`. Removed: `Railwatch.migrations_path`,
31
+ `Railwatch.url_helpers`, `Railwatch.frontend_path`.
32
+ - `http_basic_auth_enabled`, `http_basic_auth_user`,
33
+ `http_basic_auth_password`, `base_controller_class` and
34
+ `bin/rails railwatch:authentication:configure` stay. They are the gate
35
+ railwatch-server puts in front of its dashboard, and do nothing without
36
+ it.
37
+ - `bin/rails generate railwatch:install` sets up the agent only: token,
38
+ ingest URL (`--url` for a self-hosted server), the beacon mount, the
39
+ Kamal hook, the browser client and the test helpers. It no longer
40
+ writes `config/database.yml` or `config/puma.rb`, and `--cloud` is gone
41
+ because there is no other mode.
42
+ - The browser client moved to
43
+ `lib/generators/railwatch/install/templates/railwatch.ts`
44
+ (`Railwatch.browser_client_path`). Apps that already copied it keep
45
+ their copy at `app/frontend/lib/railwatch.ts`.
46
+ - Upgrading an embedded 0.x install: delete `c.transport = :local` (or
47
+ `RAILWATCH_TRANSPORT=local`), delete `plugin :railwatch` from
48
+ `config/puma.rb` (Puma refuses to boot with a plugin it cannot find),
49
+ and delete the `railwatch` and `railwatch_telemetry` entries from
50
+ `config/database.yml`. Then add `gem "railwatch-server"` and
51
+ `plugin :railwatch_server`. The old data in
52
+ `storage/<env>_railwatch.sqlite3` and
53
+ `storage/<env>_railwatch_telemetry.sqlite3` is not migrated: railwatch-rs
54
+ has no import for these files (`railwatch import-rails` reads a
55
+ Railwatch Cloud install, not this gem's embedded databases), so the new
56
+ dashboard starts empty. Keep the old files only if you want them; they
57
+ can be deleted.
58
+
59
+ ## 0.9.4 (2026-10-22)
60
+
61
+ - Sampling recovers as soon as ingest does. A receiver refusing with a
62
+ `Retry-After` (a Railwatch server below its disk floor answers 503 with
63
+ `Retry-After: 60`) kept the app at 1/8 sampling for 50-60 s after it was
64
+ accepting again: the factor only halved per accepted delivery, and those
65
+ waited on 32-60 s backoff rungs. A refusal is now retried after its
66
+ `Retry-After` or 7.5-15 s, whichever is sooner (never sooner than the
67
+ backoff rung), and the first accepted delivery puts the factor back to
68
+ 1x.
69
+ - A refusal is no longer silent. One `[railwatch]` line when ingest starts
70
+ refusing, and one when it accepts again, with how many executions
71
+ backpressure sampled out and how many records were dropped meanwhile.
72
+ Both go through `on_unrecoverable` / `warn_on_data_loss`, like lost
73
+ batches.
74
+
9
75
  ## 0.9.3 (2026-10-18)
10
76
 
11
77
  - The dashboard's route helpers and its browser beacon follow the
data/README.md CHANGED
@@ -6,37 +6,26 @@ outgoing HTTP, storage, views, and logs, and links them into one trace
6
6
  per execution, for about half a millisecond per request plus tens of
7
7
  microseconds per query, with zero writes to your database.
8
8
 
9
- By default all of it stays inside the app:
10
- [embedded mode](docs/embedded.md) serves the full dashboard at
11
- `/railwatch` out of two SQLite files your app owns, with no token, no
12
- Node, no Redis and no job worker. Railwatch Cloud is optional: it
13
- delivers alerts to Slack, email, webhooks or Linear (including when the
14
- app is down), serves MCP to your AI assistant, and puts many apps and
15
- servers in one place.
9
+ The gem is the agent. It sends what it records over HTTPS to a
10
+ Railwatch server, which stores it, groups exceptions into issues, sends
11
+ alerts, and serves the dashboard and an MCP server:
16
12
 
17
- ## Install
18
-
19
- ```sh
20
- bundle add railwatch # 1. add the public gem
21
- bin/rails generate railwatch:install # 2. embedded: databases, Puma writer, dashboard at /railwatch
22
- ```
23
-
24
- Restart and open `/railwatch`. It is open in development; before you
25
- deploy, give it a password with
26
- `RAILS_ENV=production bin/rails railwatch:authentication:configure`
27
- (it answers 401 in production until you do). On a PostgreSQL or MySQL
28
- app without the `sqlite3` gem, the generator adds it to the Gemfile;
29
- run `bundle install` and `bin/rails db:prepare` to finish.
13
+ - **Railwatch Cloud** at <https://railwatch.rebulk.com>, the default.
14
+ - **Self-hosted [railwatch-rs](https://github.com/Rebulk/railwatch-rs)**,
15
+ one static binary for many apps ([Self-hosting](docs/self-hosting.md)).
16
+ - **Embedded**: the [`railwatch-server`](https://github.com/Rebulk/railwatch-server)
17
+ gem runs that server next to Puma for one app and serves the dashboard
18
+ at `/railwatch`, with nothing else to run.
30
19
 
31
- To send everything to Railwatch Cloud instead, pass `--cloud` or a token
32
- option:
20
+ ## Install
33
21
 
34
22
  ```sh
35
- bundle add railwatch
36
- bin/rails generate railwatch:install --prompt-token # hidden token input plus app wiring
23
+ bundle add railwatch # 1. add the public gem
24
+ bin/rails generate railwatch:install --prompt-token # 2. hidden token input plus app wiring
37
25
  bin/rails railwatch:doctor # check every piece is wired up after restart
38
26
  ```
39
27
 
28
+ For a self-hosted server, add `--url=https://telemetry.example.com`.
40
29
  The generator's flags, getting a token, and deploying with Kamal,
41
30
  Docker, Heroku, or Render are covered in
42
31
  [Getting started](docs/getting-started.md). For an unreleased revision,
@@ -46,6 +35,36 @@ use the Git source instead:
46
35
  gem "railwatch", github: "Rebulk/railwatch"
47
36
  ```
48
37
 
38
+ ### Embedded
39
+
40
+ To keep everything inside the app, add `railwatch-server` next to this
41
+ gem:
42
+
43
+ ```ruby
44
+ # Gemfile
45
+ gem "railwatch"
46
+ gem "railwatch-server"
47
+ ```
48
+
49
+ ```ruby
50
+ # config/puma.rb
51
+ plugin :railwatch_server
52
+ ```
53
+
54
+ It provisions its data under `storage/railwatch/<env>` on first boot and
55
+ points this gem at it, so there is no token to manage. The dashboard at
56
+ `/railwatch` is open in development and answers 401 elsewhere until you
57
+ give it a password with
58
+ `RAILS_ENV=production bin/rails railwatch:authentication:configure`, or
59
+ put it behind your own admin authentication
60
+ ([Configuration](docs/configuration.md#dashboard-gate-railwatch-server)).
61
+ Everything else is in the
62
+ [railwatch-server README](https://github.com/Rebulk/railwatch-server#readme).
63
+
64
+ Railwatch 0.x kept embedded telemetry in two SQLite databases written by
65
+ `plugin :railwatch`. 1.0 removes that mode; see
66
+ [Coming from 0.x embedded mode](docs/getting-started.md#coming-from-0x-embedded-mode).
67
+
49
68
  ## What you get
50
69
 
51
70
  - Requests, jobs, scheduled tasks, commands, queries, exceptions, and
@@ -63,8 +82,8 @@ gem "railwatch", github: "Rebulk/railwatch"
63
82
  and browser errors ([Getting started](docs/getting-started.md)).
64
83
  - RSpec and Minitest matchers that turn a query budget into a CI gate
65
84
  ([Testing](docs/testing.md)).
66
- - With Railwatch Cloud, an MCP server so Claude Code, Cursor, VS Code, or
67
- Zed can read your production data
85
+ - An MCP server on the Railwatch server, so Claude Code, Cursor, VS Code,
86
+ or Zed can read your production data
68
87
  ([AI assistants and MCP](docs/ai-and-mcp.md)).
69
88
 
70
89
  Configuration lives in `config/initializers/railwatch.rb`; most options
@@ -85,36 +104,12 @@ expect { get "/widgets" }.to have_railwatch_queries(at_most: 6)
85
104
  expect { get "/widgets" }.not_to have_railwatch_n_plus_one
86
105
  ```
87
106
 
88
- ## Embedded mode
89
-
90
- Telemetry goes to two SQLite files the app owns -- `railwatch` for
91
- issues, comments and saved views, `railwatch_telemetry` for what the app
92
- reports -- and the dashboard is served at `/railwatch` from a bundle
93
- shipped inside the gem. Nothing leaves the machine unless you turn on
94
- export to Railwatch Cloud, and there is nothing else to run.
95
-
96
- Puma forks a single writer process (`plugin :railwatch`, which the
97
- installer adds) that owns both files. The web workers hand it batches
98
- over a Unix socket instead of writing SQLite on their own threads, and it
99
- runs the maintenance clock too, so exception grouping, rollups, retention
100
- and threshold scans happen without a queue.
101
-
102
- That dashboard reads every query, log line and exception the app
103
- produced, so it is gated the way Mission Control Jobs is: HTTP Basic is
104
- on, and with no credentials every request is 401 until you set them
105
- with `bin/rails railwatch:authentication:configure`. Development is the
106
- exception: with no credentials set there, it is open. Apps that would
107
- rather use their own authentication turn Basic off and gate the pages
108
- with `base_controller_class` or a routes constraint around the mount; a
109
- `dashboard_user` resolver then names the operator and authorizes live
110
- updates, but does not gate pages. [Embedded mode](docs/embedded.md)
111
- covers all of it, including upgrades and what it costs to store.
112
-
113
107
  ## Documentation
114
108
 
115
- - [Getting started](docs/getting-started.md) — the embedded install, the
116
- Railwatch Cloud install and its token, the three optional lines, and
117
- deploying with Kamal, Docker, Heroku, Render, or none of them.
109
+ - [Getting started](docs/getting-started.md) — the install and its token,
110
+ embedded with railwatch-server, moving from 0.x embedded mode, the three
111
+ optional lines, and deploying with Kamal, Docker, Heroku, Render, or none
112
+ of them.
118
113
  - [Configuration](docs/configuration.md) — every option and `RAILWATCH_*`
119
114
  variable, field by field.
120
115
  - [Record types](docs/records.md) — every record Railwatch ships and every
@@ -122,17 +117,13 @@ covers all of it, including upgrades and what it costs to store.
122
117
  - [Testing](docs/testing.md) — the RSpec and Minitest matchers, and a CI
123
118
  performance gate.
124
119
  - [AI assistants and MCP](docs/ai-and-mcp.md) — connecting Claude Code,
125
- Cursor, VS Code, or Zed to your production data through Railwatch
126
- Cloud.
120
+ Cursor, VS Code, or Zed to your production data.
127
121
  - [Replacing Sentry](docs/replacing-sentry.md) — a step-by-step migration,
128
122
  option by option and call site by call site.
129
123
  - [Coming from Laravel Nightwatch](docs/replacing-nightwatch.md) — the
130
124
  record-type mapping and the sampling model, for Laravel people.
131
- - [Embedded mode](docs/embedded.md) — the default: the whole dashboard
132
- inside your app, telemetry in your own SQLite files, and optional
133
- export to Railwatch Cloud.
134
125
  - [Self-hosting](docs/self-hosting.md) — pointing the gem at your own
135
- Railwatch Cloud.
126
+ railwatch-rs server.
136
127
  - [Troubleshooting](docs/troubleshooting.md) — every failure mode, paired
137
128
  with the `railwatch:doctor` line it shows up as.
138
129
  - [FAQ](docs/faq.md) — overhead numbers, retention, PII posture, SQLite.
data/config/routes.rb CHANGED
@@ -2,63 +2,4 @@
2
2
 
3
3
  Railwatch::Engine.routes.draw do
4
4
  post "beacon", to: "beacon#create"
5
-
6
- # The embedded dashboard. Same URL shape as the hosted platform so the
7
- # prebuilt bundle's route helpers resolve unchanged once js-routes knows
8
- # the mount point; a singleton install always answers for app 1, env 1.
9
- root to: redirect { |_p, req| "#{req.script_name}/apps/1/envs/1" }
10
- get "dashboard", to: redirect { |_p, req| "#{req.script_name}/apps/1/envs/1" }
11
- get "docs", to: redirect("https://railwatch.rebulk.com/docs")
12
-
13
- scope "apps/:application_id", as: :application do
14
- get "/", to: redirect { |p, req| "#{req.script_name}/apps/#{p[:application_id]}/envs/1" }
15
- scope "envs/:environment_id", as: :environment do
16
- get "/", to: "overview#show", as: :overview
17
- resources :requests, only: [ :index, :show ] do
18
- get "routes/:group_hash", to: "requests#route", on: :collection, as: :route
19
- end
20
- resources :jobs, only: [ :index, :show ] do
21
- get "classes/:group_hash", to: "jobs#klass", on: :collection, as: :klass
22
- end
23
- resources :scheduled_tasks, only: [ :index, :show ]
24
- resources :commands, only: [ :index, :show ]
25
- resources :executions, only: [ :show ]
26
- resources :queries, only: [ :index, :show ]
27
- resources :spans, only: [ :index, :show ]
28
- resources :profiles, only: [ :index, :show ]
29
- resources :attachments, only: [ :show ]
30
- get "traces/:trace_id", to: "traces#show", as: :trace
31
- resources :view_renders, path: "views", only: [ :index ]
32
- resources :transactions, only: [ :index ]
33
- resources :deprecations, only: [ :index ]
34
- resources :exceptions, only: [ :index ]
35
- resources :cache_events, path: "cache", only: [ :index ]
36
- resources :mails, path: "mail", only: [ :index ]
37
- resources :notifications, only: [ :index ]
38
- resources :broadcasts, only: [ :index ]
39
- resources :outgoing_requests, only: [ :index ]
40
- resources :llm_calls, path: "llm", only: [ :index ]
41
- resources :storage_ops, path: "storage", only: [ :index ]
42
- resources :logs, only: [ :index ]
43
- resources :people, path: "users", only: [ :index, :show ]
44
- resources :deploys, only: [ :index, :show ]
45
- resources :releases, only: [ :index, :show ]
46
- resources :visits, only: [ :index ]
47
- resources :processes, only: [ :index ]
48
- resources :tenants, only: [ :index, :show ]
49
- resources :saved_views, only: [ :create, :update, :destroy ]
50
- resources :thresholds, only: [ :index, :create, :update, :destroy ]
51
- resources :anomaly_rules, only: [ :create, :update, :destroy ]
52
- resources :alerts, only: [ :index ]
53
- end
54
- end
55
-
56
- resources :issues, only: [ :index, :show, :update ] do
57
- resources :comments, only: [ :create ]
58
- post :bulk, on: :collection
59
- get :merge_candidates, on: :member
60
- end
61
- resources :alerts, only: [ :index ] do
62
- post :retry, on: :member
63
- end
64
5
  end
data/docs/ai-and-mcp.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # AI assistants and MCP
2
2
 
3
- Railwatch Cloud is an [MCP](https://modelcontextprotocol.io) server. Point
3
+ Railwatch Cloud, and any railwatch-rs server, is an
4
+ [MCP](https://modelcontextprotocol.io) server. Point
4
5
  Claude Code, Claude Desktop, Cursor, VS Code, or Zed at it and the assistant
5
6
  sitting in your editor can read the same production data your dashboards
6
7
  show: issues and their stack traces, slow routes, the queries and N+1s
@@ -9,13 +10,13 @@ crash-free rates per release. It can also write — resolve an issue, set a
9
10
  priority, leave a comment — and every write is signed with your user and the
10
11
  agent's name in the issue's activity feed.
11
12
 
12
- MCP is a Railwatch Cloud feature. The embedded dashboard at `/railwatch`
13
- does not serve it; an embedded install gets it by
14
- [exporting to the cloud](embedded.md#three-ways-to-run-it).
15
-
16
13
  The endpoint is `<your ingest host>/mcp`. For the hosted platform that's
17
14
  `https://railwatch.rebulk.com/mcp`; if you self-host, it is your own host (see
18
- [`self-hosting.md`](self-hosting.md)). The gem knows which one you're on:
15
+ [`self-hosting.md`](self-hosting.md)). With the `railwatch-server` gem the
16
+ server runs under the app's dashboard path, so the endpoint is the app's own
17
+ host plus `/railwatch/mcp`; see the
18
+ [railwatch-server README](https://github.com/Rebulk/railwatch-server#readme).
19
+ For Railwatch Cloud and a self-hosted server the gem knows which one you're on:
19
20
 
20
21
  ```sh
21
22
  bin/rails railwatch:mcp
@@ -225,9 +226,9 @@ Copy either into your own app's repo to give its agent the same context.
225
226
 
226
227
  ## See also
227
228
 
228
- - [`getting-started.md`](getting-started.md) — install, the cloud token,
229
+ - [`getting-started.md`](getting-started.md) — install, the token,
229
230
  first request.
230
231
  - [`self-hosting.md`](self-hosting.md) — pointing the gem, and this endpoint,
231
- at your own platform.
232
+ at your own server.
232
233
  - [`troubleshooting.md`](troubleshooting.md) — when something isn't
233
234
  reporting.