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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -0
- data/app/controllers/railwatch/commands_controller.rb +1 -1
- data/app/controllers/railwatch/environment_scoped.rb +18 -36
- data/app/controllers/railwatch/exceptions_controller.rb +8 -9
- data/app/controllers/railwatch/processes_controller.rb +1 -1
- data/app/controllers/railwatch/releases_controller.rb +2 -2
- data/app/controllers/railwatch/tenants_controller.rb +2 -2
- data/app/controllers/railwatch/thresholds_controller.rb +8 -1
- data/{lib/generators/railwatch/install/templates → app/frontend/lib}/railwatch.ts +162 -42
- data/app/jobs/railwatch/detect_performance_issues_job.rb +12 -2
- data/app/models/railwatch/anomaly_rule.rb +20 -2
- data/app/models/railwatch/ingest/batch.rb +1 -0
- data/app/models/railwatch/ingest/mapper.rb +12 -0
- data/app/models/railwatch/telemetry/aggregations.rb +154 -19
- data/app/models/railwatch/telemetry/exception.rb +7 -0
- data/app/models/railwatch/telemetry/execution.rb +18 -0
- data/app/models/railwatch/telemetry/log.rb +6 -0
- data/app/models/railwatch/telemetry/query.rb +7 -0
- data/app/models/railwatch/telemetry/release_health.rb +12 -6
- data/app/models/railwatch/telemetry/rollup.rb +17 -2
- data/app/models/railwatch/telemetry/tenant.rb +8 -23
- data/app/models/railwatch/telemetry_record.rb +8 -6
- data/app/models/railwatch/threshold.rb +41 -4
- data/app/models/railwatch/window.rb +66 -0
- data/docs/embedded.md +11 -0
- data/lib/generators/railwatch/install/install_generator.rb +5 -1
- data/lib/railwatch/transport/http.rb +15 -5
- data/lib/railwatch/version.rb +1 -1
- data/lib/railwatch/wire_fixtures.json +856 -0
- data/lib/railwatch.rb +22 -0
- data/lib/tasks/railwatch_tasks.rake +7 -0
- data/public/railwatch/assets/app-layout-DDyQa72H.js +1 -0
- data/public/railwatch/assets/{app-wordmark-1SRllgHv.js → app-wordmark-o9CODKP0.js} +1 -1
- data/public/railwatch/assets/{appearance-DbwahDrc.js → appearance-BwuCXabr.js} +1 -1
- data/public/railwatch/assets/application-B7h1MIhi.css +1 -0
- data/public/railwatch/assets/{arrow-up-DwKQcab4.js → arrow-up-C6PxDiY3.js} +1 -1
- data/public/railwatch/assets/{auth-layout-DXfxXAN_.js → auth-layout-BRt8MGFD.js} +1 -1
- data/public/railwatch/assets/{badge-CApjyWcg.js → badge-CAxXV8za.js} +1 -1
- data/public/railwatch/assets/{braces-kGSgxWnS.js → braces-DgomTCNf.js} +1 -1
- data/public/railwatch/assets/{card-BaJ8kNkp.js → card-cAtqCxWl.js} +1 -1
- data/public/railwatch/assets/{chart-Xnrz1Nqw.js → chart-BBeBkkNa.js} +1 -1
- data/public/railwatch/assets/{chart-hover-XYPNE2CX.js → chart-hover-B1M9jc0y.js} +1 -1
- data/public/railwatch/assets/chart-panel-DUQTz_C8.js +1 -0
- data/public/railwatch/assets/{checkbox-Bf41R8W6.js → checkbox-CmhMHWZO.js} +1 -1
- data/public/railwatch/assets/{code-a-9sh36A.js → code-DESvxyTj.js} +1 -1
- data/public/railwatch/assets/{copy-block-zykZWQym.js → copy-block-BkSU5832.js} +1 -1
- data/public/railwatch/assets/{copy-id-b6CW5ESL.js → copy-id-D03GhN9F.js} +1 -1
- data/public/railwatch/assets/{cursor-load-more-0cHzbTPT.js → cursor-load-more-CRyuMeQb.js} +1 -1
- data/public/railwatch/assets/{data-table-IvA7xvrK.js → data-table-BIlt7Rtm.js} +1 -1
- data/public/railwatch/assets/{edit-DTtRV1fO.js → edit-Bb6MKoe4.js} +1 -1
- data/public/railwatch/assets/{edit-7lmf3k80.js → edit-DJ0D0wHN.js} +1 -1
- data/public/railwatch/assets/{edit-ZKE15r-F.js → edit-O0NSBWxo.js} +1 -1
- data/public/railwatch/assets/{empty-state-BFTnQ2oT.js → empty-state-C38il627.js} +1 -1
- data/public/railwatch/assets/env-layout-REF7OM4q.js +1 -0
- data/public/railwatch/assets/{execution-path-Di5uUHi-.js → execution-path-FYLq1TwC.js} +1 -1
- data/public/railwatch/assets/{filter-bar-Btm__gQi.js → filter-bar-CYog9Alp.js} +1 -1
- data/public/railwatch/assets/{flamegraph-C-mZdqa7.js → flamegraph-DSs69foN.js} +1 -1
- data/public/railwatch/assets/{frames-KZBsjg6-.js → frames-BUi2J5Mk.js} +1 -1
- data/public/railwatch/assets/{google-sign-in-button-DJRoD72g.js → google-sign-in-button-BQiIKFdd.js} +1 -1
- data/public/railwatch/assets/{index-9LL_C3eG.js → index-8-hnAhOD.js} +1 -1
- data/public/railwatch/assets/{index-Bjw4sTXU.js → index-BaR1U9An.js} +1 -1
- data/public/railwatch/assets/{index-BtSlLmkg.js → index-BeOh2t_S.js} +1 -1
- data/public/railwatch/assets/{index-DXUwhSCQ.js → index-BiiyMcA0.js} +1 -1
- data/public/railwatch/assets/{index-P_e_cI0O.js → index-BoUBioBP.js} +1 -1
- data/public/railwatch/assets/{index-kNhZPLVj.js → index-C-PmdhXA.js} +1 -1
- data/public/railwatch/assets/{index-DCAho97K.js → index-C3A_9imx.js} +1 -1
- data/public/railwatch/assets/{index-BsrCnQqg.js → index-C7OtLq_3.js} +1 -1
- data/public/railwatch/assets/{index-Bot7kHMA.js → index-CFFpnzIS.js} +1 -1
- data/public/railwatch/assets/{index-Z1c4nFL0.js → index-CFRLPs4J.js} +1 -1
- data/public/railwatch/assets/{index-BAkZNNEh.js → index-CGs4m_fa.js} +1 -1
- data/public/railwatch/assets/{index-CIUl9POV.js → index-CICUIFHL.js} +1 -1
- data/public/railwatch/assets/{index-wOj5j0KC.js → index-C_upSl_k.js} +1 -1
- data/public/railwatch/assets/{index-Cj3_jD1E.js → index-CiPo4Gob.js} +1 -1
- data/public/railwatch/assets/{index-EGU__DOB.js → index-CpkI015n.js} +1 -1
- data/public/railwatch/assets/{index-DEfu_YvU.js → index-CrZ3vHDL.js} +1 -1
- data/public/railwatch/assets/{index-CAzQkw-h.js → index-CsoN51vW.js} +1 -1
- data/public/railwatch/assets/{index-CeqMDByC.js → index-DDI_Zx5V.js} +1 -1
- data/public/railwatch/assets/index-DSvlZVWG.js +1 -0
- data/public/railwatch/assets/{index-CU6yhEyt.js → index-DW2CBbxU.js} +1 -1
- data/public/railwatch/assets/{index-uHBVO8Lh.js → index-Dh4IRLFI.js} +1 -1
- data/public/railwatch/assets/{index-HCJmFcZu.js → index-DqTFTP8p.js} +1 -1
- data/public/railwatch/assets/index-DrcKVG2f.js +1 -0
- data/public/railwatch/assets/{index-QyHE9WsU.js → index-DtHmuB9Q.js} +1 -1
- data/public/railwatch/assets/{index-CBJZQgHA.js → index-DvjY3dPD.js} +1 -1
- data/public/railwatch/assets/{index-Bo8hrjbs.js → index-FhUaPPab.js} +1 -1
- data/public/railwatch/assets/{index-BWSyQRZI.js → index-JdCVBrw8.js} +1 -1
- data/public/railwatch/assets/{index-DAEzO_vq.js → index-QpTtwFwu.js} +1 -1
- data/public/railwatch/assets/{index-D4968-TC.js → index-ZOGOB8SA.js} +1 -1
- data/public/railwatch/assets/{index-CP6jrrPT.js → index-ZSZg9rtq.js} +1 -1
- data/public/railwatch/assets/{index-DcItJxa5.js → index-r0tSIplE.js} +1 -1
- data/public/railwatch/assets/{index-CYYmZpZu.js → index-sTYvcbkh.js} +1 -1
- data/public/railwatch/assets/{index-B0VXzXYG.js → index-so4lRrRq.js} +1 -1
- data/public/railwatch/assets/{index-B-bSm1jB.js → index-tpz-OGUP.js} +1 -1
- data/public/railwatch/assets/{index-CX8Br7m9.js → index-umIAl-pL.js} +1 -1
- data/public/railwatch/assets/{inertia-Degv_G9N.js → inertia-DLew8ZNx.js} +3 -3
- data/public/railwatch/assets/{input-error-C6SqO_iU.js → input-error-cvM6_Jht.js} +1 -1
- data/public/railwatch/assets/{json-viewer-DcQIxT86.js → json-viewer-D922McGi.js} +1 -1
- data/public/railwatch/assets/{klass-WgQEfWpo.js → klass-CrwICqN8.js} +1 -1
- data/public/railwatch/assets/{label-B_vK19tR.js → label-GWl7I6sf.js} +1 -1
- data/public/railwatch/assets/{layout-C8q7GUlZ.js → layout-0ZAnD3zl.js} +1 -1
- data/public/railwatch/assets/{live-dot-DaXEbkXo.js → live-dot-D1n_BreY.js} +1 -1
- data/public/railwatch/assets/{nav-BnD5XArZ.js → nav-DPxr1NNC.js} +1 -1
- data/public/railwatch/assets/{new-BL9OqXHe.js → new-Cdl6pqST.js} +1 -1
- data/public/railwatch/assets/{new-uxMnBtoY.js → new-D-ZzUK9a.js} +1 -1
- data/public/railwatch/assets/{new-BqP0NhOF.js → new-DEVkYv-z.js} +1 -1
- data/public/railwatch/assets/{new-CWP3wtwt.js → new-DHAHDrN7.js} +1 -1
- data/public/railwatch/assets/{new-DIjwu2jF.js → new-Dz4lZf1L.js} +1 -1
- data/public/railwatch/assets/{new-BhRnQn4w.js → new-GMrRFurX.js} +1 -1
- data/public/railwatch/assets/{onboarding-C_Y3xTsH.js → onboarding-D1vwaHYT.js} +1 -1
- data/public/railwatch/assets/{origin-identity-CNhOnfBa.js → origin-identity-Bk9yHWZ1.js} +1 -1
- data/public/railwatch/assets/{percentile-picker-BujVEhP6.js → percentile-picker-DfSx9yJO.js} +1 -1
- data/public/railwatch/assets/{relative-time-6CoKr1lN.js → relative-time-CjIjb8Lg.js} +1 -1
- data/public/railwatch/assets/{release-health-1Qzc_XhT.js → release-health-4b3tivEf.js} +1 -1
- data/public/railwatch/assets/{route-xqgYjOwJ.js → route-C_5BUtHK.js} +1 -1
- data/public/railwatch/assets/{segmented-CVKq2Xpa.js → segmented-BgbT3wZa.js} +1 -1
- data/public/railwatch/assets/{select-CsmSXsJ4.js → select-DmunxCKE.js} +1 -1
- data/public/railwatch/assets/{separator-CrM10Oot.js → separator-BXzEdZ_8.js} +1 -1
- data/public/railwatch/assets/series-chart-Xf49v9cv.js +1 -0
- data/public/railwatch/assets/{show-zxVxhUel.js → show-B2zLAW83.js} +1 -1
- data/public/railwatch/assets/{show-BM-E2iYc.js → show-BLpWUHWD.js} +1 -1
- data/public/railwatch/assets/{show-CvNV23gH.js → show-CAl7xcex.js} +1 -1
- data/public/railwatch/assets/{show-BlNR3ZOZ.js → show-DI8IhNUH.js} +1 -1
- data/public/railwatch/assets/{show-B0nHy31L.js → show-DSP9Cq_C.js} +2 -2
- data/public/railwatch/assets/{show-rysBbvt-.js → show-DXs4deaC.js} +1 -1
- data/public/railwatch/assets/{show-DUwQlohF.js → show-DYskfl3-.js} +1 -1
- data/public/railwatch/assets/{show-ixK2r2f1.js → show-DcpTFiLi.js} +1 -1
- data/public/railwatch/assets/{show-CQ4Ze-Un.js → show-Dily73Xk.js} +1 -1
- data/public/railwatch/assets/{show-B3izvRdU.js → show-DlRVS18-.js} +1 -1
- data/public/railwatch/assets/{show-8H9WAGav.js → show-Dn-GwFZL.js} +1 -1
- data/public/railwatch/assets/{show-DZwcZZrz.js → show-DnR1Dnjd.js} +1 -1
- data/public/railwatch/assets/{show-CMisHNAI.js → show-SHwZjXb7.js} +1 -1
- data/public/railwatch/assets/{show-B7NhcWgp.js → show-SvLOcPrx.js} +1 -1
- data/public/railwatch/assets/{show-CJMeX75E.js → show-Y74rM0VT.js} +1 -1
- data/public/railwatch/assets/{show-DMZlwzL_.js → show-mU38uGTg.js} +1 -1
- data/public/railwatch/assets/{show-9jDeBNpc.js → show-vQ4bndYD.js} +1 -1
- data/public/railwatch/assets/{sort-header-CKj_7G3U.js → sort-header-Dcq9bzmo.js} +1 -1
- data/public/railwatch/assets/{sparkline-cell-Ckg29yVq.js → sparkline-cell-BON3qQUB.js} +1 -1
- data/public/railwatch/assets/{stat-TxvoBiC8.js → stat-DFEyFxkO.js} +1 -1
- data/public/railwatch/assets/{status-badge-5NCVJHjo.js → status-badge-BaUKP7Yo.js} +1 -1
- data/public/railwatch/assets/{tenant-path-B5ZRK4x3.js → tenant-path-DPZPc985.js} +1 -1
- data/public/railwatch/assets/{text-link-BPllRj0F.js → text-link-BO77t9Xk.js} +1 -1
- data/public/railwatch/assets/{textarea-DtD5yZp_.js → textarea-DTqrCiV0.js} +1 -1
- data/public/railwatch/assets/{timeline-DZz5ZnHN.js → timeline-D5rJ0es2.js} +1 -1
- data/public/railwatch/assets/{transition-Ds6Cakuc.js → transition-DMIrZVth.js} +1 -1
- data/public/railwatch/assets/{use-clipboard-BLjjYH8V.js → use-clipboard-ByoUGQqA.js} +1 -1
- data/public/railwatch/assets/{use-live-GKze1mNC.js → use-live-D7xKz2ma.js} +1 -1
- data/public/railwatch/manifest.json +1284 -1284
- metadata +119 -117
- data/public/railwatch/assets/app-layout-B5Fcdwfz.js +0 -1
- data/public/railwatch/assets/application-CwshqwM6.css +0 -1
- data/public/railwatch/assets/chart-panel-BYk68mJJ.js +0 -1
- data/public/railwatch/assets/env-layout-erSDpIXg.js +0 -1
- data/public/railwatch/assets/index-BoTOVM0v.js +0 -1
- data/public/railwatch/assets/index-DBTxQw77.js +0 -1
- 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
|
-
|
|
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[
|
|
147
|
-
req[
|
|
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[
|
|
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[
|
|
156
|
-
req[
|
|
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
|
data/lib/railwatch/version.rb
CHANGED