railwatch 0.3.7 → 0.5.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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/app/controllers/railwatch/commands_controller.rb +1 -1
  4. data/app/controllers/railwatch/environment_scoped.rb +18 -36
  5. data/app/controllers/railwatch/exceptions_controller.rb +8 -9
  6. data/app/controllers/railwatch/processes_controller.rb +1 -1
  7. data/app/controllers/railwatch/releases_controller.rb +2 -2
  8. data/app/controllers/railwatch/tenants_controller.rb +2 -2
  9. data/app/controllers/railwatch/thresholds_controller.rb +8 -1
  10. data/{lib/generators/railwatch/install/templates → app/frontend/lib}/railwatch.ts +162 -42
  11. data/app/jobs/railwatch/detect_performance_issues_job.rb +12 -2
  12. data/app/models/railwatch/anomaly_rule.rb +20 -2
  13. data/app/models/railwatch/ingest/batch.rb +1 -0
  14. data/app/models/railwatch/ingest/mapper.rb +12 -0
  15. data/app/models/railwatch/telemetry/aggregations.rb +154 -19
  16. data/app/models/railwatch/telemetry/exception.rb +7 -0
  17. data/app/models/railwatch/telemetry/execution.rb +18 -0
  18. data/app/models/railwatch/telemetry/log.rb +6 -0
  19. data/app/models/railwatch/telemetry/query.rb +7 -0
  20. data/app/models/railwatch/telemetry/release_health.rb +12 -6
  21. data/app/models/railwatch/telemetry/rollup.rb +17 -2
  22. data/app/models/railwatch/telemetry/tenant.rb +8 -23
  23. data/app/models/railwatch/telemetry_record.rb +8 -6
  24. data/app/models/railwatch/threshold.rb +41 -4
  25. data/app/models/railwatch/window.rb +66 -0
  26. data/docs/embedded.md +11 -0
  27. data/lib/generators/railwatch/install/install_generator.rb +5 -1
  28. data/lib/railwatch/transport/http.rb +15 -5
  29. data/lib/railwatch/version.rb +1 -1
  30. data/lib/railwatch/wire_fixtures.json +856 -0
  31. data/lib/railwatch.rb +22 -0
  32. data/lib/tasks/railwatch_tasks.rake +7 -0
  33. data/public/railwatch/assets/app-layout-DDyQa72H.js +1 -0
  34. data/public/railwatch/assets/{app-wordmark-1SRllgHv.js → app-wordmark-o9CODKP0.js} +1 -1
  35. data/public/railwatch/assets/{appearance-DbwahDrc.js → appearance-BwuCXabr.js} +1 -1
  36. data/public/railwatch/assets/application-B7h1MIhi.css +1 -0
  37. data/public/railwatch/assets/{arrow-up-DwKQcab4.js → arrow-up-C6PxDiY3.js} +1 -1
  38. data/public/railwatch/assets/{auth-layout-DXfxXAN_.js → auth-layout-BRt8MGFD.js} +1 -1
  39. data/public/railwatch/assets/{badge-CApjyWcg.js → badge-CAxXV8za.js} +1 -1
  40. data/public/railwatch/assets/{braces-kGSgxWnS.js → braces-DgomTCNf.js} +1 -1
  41. data/public/railwatch/assets/{card-BaJ8kNkp.js → card-cAtqCxWl.js} +1 -1
  42. data/public/railwatch/assets/{chart-Xnrz1Nqw.js → chart-BBeBkkNa.js} +1 -1
  43. data/public/railwatch/assets/{chart-hover-XYPNE2CX.js → chart-hover-B1M9jc0y.js} +1 -1
  44. data/public/railwatch/assets/chart-panel-DUQTz_C8.js +1 -0
  45. data/public/railwatch/assets/{checkbox-Bf41R8W6.js → checkbox-CmhMHWZO.js} +1 -1
  46. data/public/railwatch/assets/{code-a-9sh36A.js → code-DESvxyTj.js} +1 -1
  47. data/public/railwatch/assets/{copy-block-zykZWQym.js → copy-block-BkSU5832.js} +1 -1
  48. data/public/railwatch/assets/{copy-id-b6CW5ESL.js → copy-id-D03GhN9F.js} +1 -1
  49. data/public/railwatch/assets/{cursor-load-more-0cHzbTPT.js → cursor-load-more-CRyuMeQb.js} +1 -1
  50. data/public/railwatch/assets/{data-table-IvA7xvrK.js → data-table-BIlt7Rtm.js} +1 -1
  51. data/public/railwatch/assets/{edit-DTtRV1fO.js → edit-Bb6MKoe4.js} +1 -1
  52. data/public/railwatch/assets/{edit-7lmf3k80.js → edit-DJ0D0wHN.js} +1 -1
  53. data/public/railwatch/assets/{edit-ZKE15r-F.js → edit-O0NSBWxo.js} +1 -1
  54. data/public/railwatch/assets/{empty-state-BFTnQ2oT.js → empty-state-C38il627.js} +1 -1
  55. data/public/railwatch/assets/env-layout-REF7OM4q.js +1 -0
  56. data/public/railwatch/assets/{execution-path-Di5uUHi-.js → execution-path-FYLq1TwC.js} +1 -1
  57. data/public/railwatch/assets/{filter-bar-Btm__gQi.js → filter-bar-CYog9Alp.js} +1 -1
  58. data/public/railwatch/assets/{flamegraph-C-mZdqa7.js → flamegraph-DSs69foN.js} +1 -1
  59. data/public/railwatch/assets/{frames-KZBsjg6-.js → frames-BUi2J5Mk.js} +1 -1
  60. data/public/railwatch/assets/{google-sign-in-button-DJRoD72g.js → google-sign-in-button-BQiIKFdd.js} +1 -1
  61. data/public/railwatch/assets/{index-9LL_C3eG.js → index-8-hnAhOD.js} +1 -1
  62. data/public/railwatch/assets/{index-Bjw4sTXU.js → index-BaR1U9An.js} +1 -1
  63. data/public/railwatch/assets/{index-BtSlLmkg.js → index-BeOh2t_S.js} +1 -1
  64. data/public/railwatch/assets/{index-DXUwhSCQ.js → index-BiiyMcA0.js} +1 -1
  65. data/public/railwatch/assets/{index-P_e_cI0O.js → index-BoUBioBP.js} +1 -1
  66. data/public/railwatch/assets/{index-kNhZPLVj.js → index-C-PmdhXA.js} +1 -1
  67. data/public/railwatch/assets/{index-DCAho97K.js → index-C3A_9imx.js} +1 -1
  68. data/public/railwatch/assets/{index-BsrCnQqg.js → index-C7OtLq_3.js} +1 -1
  69. data/public/railwatch/assets/{index-Bot7kHMA.js → index-CFFpnzIS.js} +1 -1
  70. data/public/railwatch/assets/{index-Z1c4nFL0.js → index-CFRLPs4J.js} +1 -1
  71. data/public/railwatch/assets/{index-BAkZNNEh.js → index-CGs4m_fa.js} +1 -1
  72. data/public/railwatch/assets/{index-CIUl9POV.js → index-CICUIFHL.js} +1 -1
  73. data/public/railwatch/assets/{index-wOj5j0KC.js → index-C_upSl_k.js} +1 -1
  74. data/public/railwatch/assets/{index-Cj3_jD1E.js → index-CiPo4Gob.js} +1 -1
  75. data/public/railwatch/assets/{index-EGU__DOB.js → index-CpkI015n.js} +1 -1
  76. data/public/railwatch/assets/{index-DEfu_YvU.js → index-CrZ3vHDL.js} +1 -1
  77. data/public/railwatch/assets/{index-CAzQkw-h.js → index-CsoN51vW.js} +1 -1
  78. data/public/railwatch/assets/{index-CeqMDByC.js → index-DDI_Zx5V.js} +1 -1
  79. data/public/railwatch/assets/index-DSvlZVWG.js +1 -0
  80. data/public/railwatch/assets/{index-CU6yhEyt.js → index-DW2CBbxU.js} +1 -1
  81. data/public/railwatch/assets/{index-uHBVO8Lh.js → index-Dh4IRLFI.js} +1 -1
  82. data/public/railwatch/assets/{index-HCJmFcZu.js → index-DqTFTP8p.js} +1 -1
  83. data/public/railwatch/assets/index-DrcKVG2f.js +1 -0
  84. data/public/railwatch/assets/{index-QyHE9WsU.js → index-DtHmuB9Q.js} +1 -1
  85. data/public/railwatch/assets/{index-CBJZQgHA.js → index-DvjY3dPD.js} +1 -1
  86. data/public/railwatch/assets/{index-Bo8hrjbs.js → index-FhUaPPab.js} +1 -1
  87. data/public/railwatch/assets/{index-BWSyQRZI.js → index-JdCVBrw8.js} +1 -1
  88. data/public/railwatch/assets/{index-DAEzO_vq.js → index-QpTtwFwu.js} +1 -1
  89. data/public/railwatch/assets/{index-D4968-TC.js → index-ZOGOB8SA.js} +1 -1
  90. data/public/railwatch/assets/{index-CP6jrrPT.js → index-ZSZg9rtq.js} +1 -1
  91. data/public/railwatch/assets/{index-DcItJxa5.js → index-r0tSIplE.js} +1 -1
  92. data/public/railwatch/assets/{index-CYYmZpZu.js → index-sTYvcbkh.js} +1 -1
  93. data/public/railwatch/assets/{index-B0VXzXYG.js → index-so4lRrRq.js} +1 -1
  94. data/public/railwatch/assets/{index-B-bSm1jB.js → index-tpz-OGUP.js} +1 -1
  95. data/public/railwatch/assets/{index-CX8Br7m9.js → index-umIAl-pL.js} +1 -1
  96. data/public/railwatch/assets/{inertia-Degv_G9N.js → inertia-DLew8ZNx.js} +3 -3
  97. data/public/railwatch/assets/{input-error-C6SqO_iU.js → input-error-cvM6_Jht.js} +1 -1
  98. data/public/railwatch/assets/{json-viewer-DcQIxT86.js → json-viewer-D922McGi.js} +1 -1
  99. data/public/railwatch/assets/{klass-WgQEfWpo.js → klass-CrwICqN8.js} +1 -1
  100. data/public/railwatch/assets/{label-B_vK19tR.js → label-GWl7I6sf.js} +1 -1
  101. data/public/railwatch/assets/{layout-C8q7GUlZ.js → layout-0ZAnD3zl.js} +1 -1
  102. data/public/railwatch/assets/{live-dot-DaXEbkXo.js → live-dot-D1n_BreY.js} +1 -1
  103. data/public/railwatch/assets/{nav-BnD5XArZ.js → nav-DPxr1NNC.js} +1 -1
  104. data/public/railwatch/assets/{new-BL9OqXHe.js → new-Cdl6pqST.js} +1 -1
  105. data/public/railwatch/assets/{new-uxMnBtoY.js → new-D-ZzUK9a.js} +1 -1
  106. data/public/railwatch/assets/{new-BqP0NhOF.js → new-DEVkYv-z.js} +1 -1
  107. data/public/railwatch/assets/{new-CWP3wtwt.js → new-DHAHDrN7.js} +1 -1
  108. data/public/railwatch/assets/{new-DIjwu2jF.js → new-Dz4lZf1L.js} +1 -1
  109. data/public/railwatch/assets/{new-BhRnQn4w.js → new-GMrRFurX.js} +1 -1
  110. data/public/railwatch/assets/{onboarding-C_Y3xTsH.js → onboarding-D1vwaHYT.js} +1 -1
  111. data/public/railwatch/assets/{origin-identity-CNhOnfBa.js → origin-identity-Bk9yHWZ1.js} +1 -1
  112. data/public/railwatch/assets/{percentile-picker-BujVEhP6.js → percentile-picker-DfSx9yJO.js} +1 -1
  113. data/public/railwatch/assets/{relative-time-6CoKr1lN.js → relative-time-CjIjb8Lg.js} +1 -1
  114. data/public/railwatch/assets/{release-health-1Qzc_XhT.js → release-health-4b3tivEf.js} +1 -1
  115. data/public/railwatch/assets/{route-xqgYjOwJ.js → route-C_5BUtHK.js} +1 -1
  116. data/public/railwatch/assets/{segmented-CVKq2Xpa.js → segmented-BgbT3wZa.js} +1 -1
  117. data/public/railwatch/assets/{select-CsmSXsJ4.js → select-DmunxCKE.js} +1 -1
  118. data/public/railwatch/assets/{separator-CrM10Oot.js → separator-BXzEdZ_8.js} +1 -1
  119. data/public/railwatch/assets/series-chart-Xf49v9cv.js +1 -0
  120. data/public/railwatch/assets/{show-zxVxhUel.js → show-B2zLAW83.js} +1 -1
  121. data/public/railwatch/assets/{show-BM-E2iYc.js → show-BLpWUHWD.js} +1 -1
  122. data/public/railwatch/assets/{show-CvNV23gH.js → show-CAl7xcex.js} +1 -1
  123. data/public/railwatch/assets/{show-BlNR3ZOZ.js → show-DI8IhNUH.js} +1 -1
  124. data/public/railwatch/assets/{show-B0nHy31L.js → show-DSP9Cq_C.js} +2 -2
  125. data/public/railwatch/assets/{show-rysBbvt-.js → show-DXs4deaC.js} +1 -1
  126. data/public/railwatch/assets/{show-DUwQlohF.js → show-DYskfl3-.js} +1 -1
  127. data/public/railwatch/assets/{show-ixK2r2f1.js → show-DcpTFiLi.js} +1 -1
  128. data/public/railwatch/assets/{show-CQ4Ze-Un.js → show-Dily73Xk.js} +1 -1
  129. data/public/railwatch/assets/{show-B3izvRdU.js → show-DlRVS18-.js} +1 -1
  130. data/public/railwatch/assets/{show-8H9WAGav.js → show-Dn-GwFZL.js} +1 -1
  131. data/public/railwatch/assets/{show-DZwcZZrz.js → show-DnR1Dnjd.js} +1 -1
  132. data/public/railwatch/assets/{show-CMisHNAI.js → show-SHwZjXb7.js} +1 -1
  133. data/public/railwatch/assets/{show-B7NhcWgp.js → show-SvLOcPrx.js} +1 -1
  134. data/public/railwatch/assets/{show-CJMeX75E.js → show-Y74rM0VT.js} +1 -1
  135. data/public/railwatch/assets/{show-DMZlwzL_.js → show-mU38uGTg.js} +1 -1
  136. data/public/railwatch/assets/{show-9jDeBNpc.js → show-vQ4bndYD.js} +1 -1
  137. data/public/railwatch/assets/{sort-header-CKj_7G3U.js → sort-header-Dcq9bzmo.js} +1 -1
  138. data/public/railwatch/assets/{sparkline-cell-Ckg29yVq.js → sparkline-cell-BON3qQUB.js} +1 -1
  139. data/public/railwatch/assets/{stat-TxvoBiC8.js → stat-DFEyFxkO.js} +1 -1
  140. data/public/railwatch/assets/{status-badge-5NCVJHjo.js → status-badge-BaUKP7Yo.js} +1 -1
  141. data/public/railwatch/assets/{tenant-path-B5ZRK4x3.js → tenant-path-DPZPc985.js} +1 -1
  142. data/public/railwatch/assets/{text-link-BPllRj0F.js → text-link-BO77t9Xk.js} +1 -1
  143. data/public/railwatch/assets/{textarea-DtD5yZp_.js → textarea-DTqrCiV0.js} +1 -1
  144. data/public/railwatch/assets/{timeline-DZz5ZnHN.js → timeline-D5rJ0es2.js} +1 -1
  145. data/public/railwatch/assets/{transition-Ds6Cakuc.js → transition-DMIrZVth.js} +1 -1
  146. data/public/railwatch/assets/{use-clipboard-BLjjYH8V.js → use-clipboard-ByoUGQqA.js} +1 -1
  147. data/public/railwatch/assets/{use-live-GKze1mNC.js → use-live-D7xKz2ma.js} +1 -1
  148. data/public/railwatch/manifest.json +1284 -1284
  149. metadata +119 -117
  150. data/public/railwatch/assets/app-layout-B5Fcdwfz.js +0 -1
  151. data/public/railwatch/assets/application-CwshqwM6.css +0 -1
  152. data/public/railwatch/assets/chart-panel-BYk68mJJ.js +0 -1
  153. data/public/railwatch/assets/env-layout-erSDpIXg.js +0 -1
  154. data/public/railwatch/assets/index-BoTOVM0v.js +0 -1
  155. data/public/railwatch/assets/index-DBTxQw77.js +0 -1
  156. data/public/railwatch/assets/series-chart-D33UhdG2.js +0 -1
data/docs/embedded.md CHANGED
@@ -44,6 +44,17 @@ an embedded install that has one configured still sends nothing.
44
44
  fails loudly if you ask for it and it cannot work. `railwatch:export:status`
45
45
  shows what is queued.
46
46
 
47
+ ## Railwatch Cloud runs the same models
48
+
49
+ The hosted platform is this engine's telemetry layer plus what hosting adds
50
+ (accounts, tokens, quotas, alert routing). It uses `Railwatch::Telemetry::*`,
51
+ `Railwatch::Ingest::Batch`, `Railwatch::Telemetry::Aggregations` and the rest
52
+ directly, with two seams: it tenants `Railwatch::TelemetryRecord` so each
53
+ monitored environment gets its own database, and its `Environment` is an
54
+ account-scoped Active Record row rather than the embedded singleton. Anything
55
+ those models need from an environment is the surface `Railwatch::Environment`
56
+ documents: `id`, `slug`, `name`, `with_telemetry`, and the display attributes.
57
+
47
58
  ## Install
48
59
 
49
60
  ```sh
@@ -119,9 +119,13 @@ module Railwatch
119
119
  chmod ".kamal/hooks/post-deploy", 0o755
120
120
  end
121
121
 
122
+ # The one browser client, the same file the gem's own dashboard bundle
123
+ # is built from (Railwatch.browser_client_path). Copied rather than
124
+ # templated: there is nothing to interpolate, and a copy means the host
125
+ # sees exactly what the gem tests.
122
126
  def create_browser_client
123
127
  return unless File.directory?("app/frontend")
124
- template "railwatch.ts", "app/frontend/lib/railwatch.ts"
128
+ copy_file Railwatch.browser_client_path.to_s, "app/frontend/lib/railwatch.ts"
125
129
  end
126
130
 
127
131
  # Adds the import and the call to the Inertia entrypoint, so page-visit
@@ -13,6 +13,16 @@ module Railwatch
13
13
  # Reporter owns retention and backoff between calls. A 401 marks the
14
14
  # transport unauthorized so no further requests are made.
15
15
  class Http
16
+ # The request headers a delivery carries besides the body. The receiver
17
+ # reads them by these names; Railwatch Cloud does so through this table.
18
+ HEADERS = {
19
+ dropped: "X-Railwatch-Dropped",
20
+ dropped_bytes: "X-Railwatch-Dropped-Bytes",
21
+ backpressure_factor: "X-Railwatch-Backpressure-Factor",
22
+ version: "X-Railwatch-Version",
23
+ batch_id: "X-Railwatch-Batch-Id"
24
+ }.freeze
25
+
16
26
  RETRYABLE_STATUSES = [ 402, 408, 429 ].freeze
17
27
  UNAUTHORIZED_STATUS = 401
18
28
 
@@ -143,17 +153,17 @@ module Railwatch
143
153
  headers.each { |name, value| req[name] = value.to_s }
144
154
  req["Content-Type"] = "application/x-ndjson"
145
155
  req["Content-Encoding"] = "gzip"
146
- req["X-Railwatch-Dropped"] = dropped.to_s if dropped.positive?
147
- req["X-Railwatch-Dropped-Bytes"] = dropped_bytes.to_s if dropped_bytes.positive?
156
+ req[HEADERS[:dropped]] = dropped.to_s if dropped.positive?
157
+ req[HEADERS[:dropped_bytes]] = dropped_bytes.to_s if dropped_bytes.positive?
148
158
  if backpressure_factor > 1.0
149
- req["X-Railwatch-Backpressure-Factor"] = backpressure_factor.to_s
159
+ req[HEADERS[:backpressure_factor]] = backpressure_factor.to_s
150
160
  end
151
161
  # The version this payload was built by, which for a stored delivery is
152
162
  # not the version running now. The receiver digests this header, so
153
163
  # sending today's value would turn an upgrade into a conflict and
154
164
  # destroy a delivery it had already accepted.
155
- req["X-Railwatch-Version"] = gem_version
156
- req["X-Railwatch-Batch-Id"] = batch_id
165
+ req[HEADERS[:version]] = gem_version
166
+ req[HEADERS[:batch_id]] = batch_id
157
167
  req.body = body
158
168
  request(req)
159
169
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Railwatch
4
- VERSION = "0.3.7"
4
+ VERSION = "0.5.0"
5
5
  end