watchfor 0.10.0 → 0.12.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/README.md +13 -0
- data/exe/watchfor +6 -1
- data/lib/watchfor/client.rb +40 -3
- data/lib/watchfor/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3d7fc66146ff02aa81bb3517188f14d8ce8c04b9b643b869aba9793610560b6
|
|
4
|
+
data.tar.gz: 19c2c8f08062072d54a90fe7d848b30ae24b5997a6179ba3aac6ddd5e31008be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c53ae17ddbc628f745c8099df3d1425627c1da778e616fd2a4cfc8bfca0680b56ff188881383d8f1f6cc10b68f42f53264b1cbc3ebf5f33cc4f8fb069045a703
|
|
7
|
+
data.tar.gz: b2214618bce3e48a10c5c8bbac5c4ee60f79281445472bde3fe225e82606297b21c7e087d12da41f68a0e20c15d8e6863846608165064add64511a8562940dd2
|
data/README.md
CHANGED
|
@@ -43,6 +43,11 @@ wf.monitors.reset(mon["id"])
|
|
|
43
43
|
# Page integrity: after a deploy, accept what the newest check saw as the new baseline
|
|
44
44
|
wf.monitors.accept_baseline(integrity_monitor_id)
|
|
45
45
|
|
|
46
|
+
# Browser checks: try a Playwright script once (nothing saved), then read the result
|
|
47
|
+
run = wf.playwright.test_run(script: script, target: "https://shop.example.com")
|
|
48
|
+
wf.playwright.get_test_run(run["id"]) # status: queued | running | done | error
|
|
49
|
+
wf.variables.put("LOGIN_PASSWORD", value: password, secret: true)
|
|
50
|
+
|
|
46
51
|
# Older checks: pass next_cursor back as cursor (keep the same hours/success)
|
|
47
52
|
page = wf.monitors.checks(mon["id"], hours: 24, limit: 100)
|
|
48
53
|
wf.monitors.checks(mon["id"], hours: 24, limit: 100, cursor: page["next_cursor"]) if page["next_cursor"]
|
|
@@ -85,6 +90,14 @@ Namespaces: `wf.monitors`, `wf.alert_rules`, `wf.incidents`,
|
|
|
85
90
|
`wf.incident_stats(period)`, `wf.notifications`, `wf.activity`. Errors raise
|
|
86
91
|
`Watchfor::Error` with `#status`, `#code`, `#message`.
|
|
87
92
|
|
|
93
|
+
## Prometheus metrics (Pro plan and above)
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
text = wf.metrics(tag: "production") # Prometheus text format
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Usually you point Prometheus at `https://watchfor.io/api/v1/metrics` directly; this is for scripts and one-off checks. See https://watchfor.io/docs/api/prometheus.
|
|
100
|
+
|
|
88
101
|
## CLI
|
|
89
102
|
|
|
90
103
|
```bash
|
data/exe/watchfor
CHANGED
|
@@ -36,8 +36,13 @@ begin
|
|
|
36
36
|
cursor = args.include?("--cursor") ? args[args.index("--cursor") + 1] : nil
|
|
37
37
|
wf.monitors.checks(monitor_id, cursor: cursor)
|
|
38
38
|
when "report" then wf.report(period: args.include?("--period") ? args[args.index("--period") + 1] : nil)
|
|
39
|
+
when "metrics"
|
|
40
|
+
tag = args.include?("--tag") ? args[args.index("--tag") + 1] : nil
|
|
41
|
+
type = args.include?("--type") ? args[args.index("--type") + 1] : nil
|
|
42
|
+
print wf.metrics(tag: tag, type: type)
|
|
43
|
+
exit 0
|
|
39
44
|
else
|
|
40
|
-
warn "Usage: watchfor [summary|plan|monitors|locations|monitor-types|incidents|checks <monitor_id> [--cursor c]|report [--period 7d|30d]]"
|
|
45
|
+
warn "Usage: watchfor [summary|plan|monitors|locations|monitor-types|incidents|checks <monitor_id> [--cursor c]|report [--period 7d|30d]|metrics [--tag t] [--type t]]"
|
|
41
46
|
exit 2
|
|
42
47
|
end
|
|
43
48
|
puts JSON.pretty_generate(result)
|
data/lib/watchfor/client.rb
CHANGED
|
@@ -27,7 +27,7 @@ module Watchfor
|
|
|
27
27
|
class Client
|
|
28
28
|
attr_reader :monitors, :alert_rules, :incidents, :hosts, :status_pages, :on_call, :notification_channels,
|
|
29
29
|
:maintenance_windows, :contacts, :contact_groups,
|
|
30
|
-
:diagnostics
|
|
30
|
+
:diagnostics, :playwright, :variables
|
|
31
31
|
|
|
32
32
|
def initialize(api_key:, base_url: DEFAULT_BASE_URL, timeout: 30)
|
|
33
33
|
raise ArgumentError, "api_key is required" if api_key.nil? || api_key.empty?
|
|
@@ -46,10 +46,12 @@ module Watchfor
|
|
|
46
46
|
@contacts = Contacts.new(self)
|
|
47
47
|
@contact_groups = ContactGroups.new(self)
|
|
48
48
|
@diagnostics = Diagnostics.new(self)
|
|
49
|
+
@playwright = Playwright.new(self)
|
|
50
|
+
@variables = Variables.new(self)
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
# Core request. +query+ and +body+ are optional hashes.
|
|
52
|
-
def request(method, path, query: nil, body: nil, idempotency_key: nil)
|
|
54
|
+
def request(method, path, query: nil, body: nil, idempotency_key: nil, text: false)
|
|
53
55
|
uri = URI("#{@base_url}#{path}")
|
|
54
56
|
unless query.nil? || query.empty?
|
|
55
57
|
cleaned = query.reject { |_, v| v.nil? || v == "" }
|
|
@@ -63,7 +65,7 @@ module Watchfor
|
|
|
63
65
|
}.fetch(method)
|
|
64
66
|
req = klass.new(uri)
|
|
65
67
|
req["Authorization"] = "Bearer #{@api_key}"
|
|
66
|
-
req["Accept"] = "application/json"
|
|
68
|
+
req["Accept"] = text ? "text/plain, application/json" : "application/json"
|
|
67
69
|
req["User-Agent"] = "watchfor-ruby/#{Watchfor::VERSION}"
|
|
68
70
|
req["Idempotency-Key"] = idempotency_key if idempotency_key
|
|
69
71
|
unless body.nil?
|
|
@@ -78,6 +80,8 @@ module Watchfor
|
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
raw = res.body.to_s
|
|
83
|
+
return raw if text && res.code.to_i.between?(200, 299)
|
|
84
|
+
|
|
81
85
|
parsed = raw.empty? ? nil : (JSON.parse(raw) rescue nil)
|
|
82
86
|
unless res.code.to_i.between?(200, 299)
|
|
83
87
|
err = parsed.is_a?(Hash) ? (parsed["error"] || {}) : {}
|
|
@@ -90,6 +94,14 @@ module Watchfor
|
|
|
90
94
|
# Top-level reads
|
|
91
95
|
def me = request("GET", "/me")
|
|
92
96
|
def summary = request("GET", "/summary")
|
|
97
|
+
|
|
98
|
+
# The organization in Prometheus text format (Pro plan and above):
|
|
99
|
+
# status, uptime, response times, expiry, heartbeats, hosts. Cached 60 s.
|
|
100
|
+
def metrics(tag: nil, type: nil, monitor_id: nil, include_hosts: nil)
|
|
101
|
+
query = { tag: tag, type: type, monitor_id: monitor_id,
|
|
102
|
+
include_hosts: include_hosts.nil? ? nil : include_hosts.to_s }
|
|
103
|
+
request("GET", "/metrics", query: query, text: true)
|
|
104
|
+
end
|
|
93
105
|
def plan = request("GET", "/plan")
|
|
94
106
|
def incident_stats(period = nil) = request("GET", "/incidents/stats", query: { period: period })
|
|
95
107
|
|
|
@@ -141,6 +153,14 @@ module Watchfor
|
|
|
141
153
|
end
|
|
142
154
|
# One check in full detail (redacted).
|
|
143
155
|
def check_detail(id, run_id) = @c.request("GET", "/monitors/#{id}/checks/#{run_id}")
|
|
156
|
+
# Browser checks: runs, newest first (status: "failed" | "flaky").
|
|
157
|
+
def runs(id, status: nil, limit: nil, cursor: nil)
|
|
158
|
+
@c.request("GET", "/monitors/#{id}/runs", query: { status: status, limit: limit, cursor: cursor })
|
|
159
|
+
end
|
|
160
|
+
# Browser checks: one run — steps, errors, Web Vitals, screenshots, trace link.
|
|
161
|
+
def run(id, run_id) = @c.request("GET", "/monitors/#{id}/runs/#{run_id}")
|
|
162
|
+
def script_versions(id) = @c.request("GET", "/monitors/#{id}/script/versions")
|
|
163
|
+
def script_version(id, version) = @c.request("GET", "/monitors/#{id}/script/versions/#{version}")
|
|
144
164
|
# Page integrity monitors: the accepted baseline of every watched page.
|
|
145
165
|
def baseline(id) = @c.request("GET", "/monitors/#{id}/baseline")
|
|
146
166
|
# Page integrity monitors: accept what the newest check saw as the new
|
|
@@ -152,6 +172,23 @@ module Watchfor
|
|
|
152
172
|
end
|
|
153
173
|
end
|
|
154
174
|
|
|
175
|
+
# Browser checks: run a Playwright script once without saving it.
|
|
176
|
+
class Playwright < Namespace
|
|
177
|
+
def test_run(body) = @c.request("POST", "/playwright/test-runs", body: body)
|
|
178
|
+
def get_test_run(id) = @c.request("GET", "/playwright/test-runs/#{id}")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Org variables and secrets (process.env.NAME); secrets are write-only.
|
|
182
|
+
class Variables < Namespace
|
|
183
|
+
def list = @c.request("GET", "/variables")
|
|
184
|
+
def put(name, value: nil, secret: false)
|
|
185
|
+
body = { secret: secret }
|
|
186
|
+
body[:value] = value unless value.nil?
|
|
187
|
+
@c.request("PUT", "/variables/#{name}", body: body)
|
|
188
|
+
end
|
|
189
|
+
def delete(name) = @c.request("DELETE", "/variables/#{name}")
|
|
190
|
+
end
|
|
191
|
+
|
|
155
192
|
class AlertRules < Namespace
|
|
156
193
|
def list(monitor_id) = @c.request("GET", "/monitors/#{monitor_id}/alert-rules")
|
|
157
194
|
def get(monitor_id, rule_id) = @c.request("GET", "/monitors/#{monitor_id}/alert-rules/#{rule_id}")
|
data/lib/watchfor/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: watchfor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- WatchFor
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Zero-dependency Ruby client for the WatchFor REST API (monitors, alert
|
|
14
14
|
rules, incidents, maintenance windows) plus a `watchfor` CLI.
|