Repository navigation
v0.52.0
Cloud Monitoring's alert policies and snoozes: read the policies behind the incidents, enable or disable one, and silence policies for a while, each write with a twin that builds its exact request without sending it. The writes are experimental on their own. No breaking change: the calls and types are new, FakeMonitoring.Options gains project_number and caller (both with defaults), and the default user agents changed.
// Silence a policy for an hour, confirmed first.
const now = std.Io.Clock.real.now(io);
const spec: monitoring.NewSnooze = .{
.display_name = "deploy window",
.policies = &.{policy_name},
.start = now,
.end = .{ .nanoseconds = now.nanoseconds + std.time.ns_per_hour },
};
var request = try client.createSnoozeRequest(spec);
defer request.deinit();
if (try confirm(request.value.method, request.value.url, request.value.body)) {
var snooze = try client.createSnooze(spec);
defer snooze.deinit();
}Alert policies
| Call | What it does |
|---|---|
Client.listAlertPolicies(options), Client.getAlertPolicy(id) |
The policies, filtered and ordered as written; totalSize on every page |
Client.setAlertPolicyEnabled(id, enabled) |
Enables or disables one; setAlertPolicyEnabledRequest builds its exact request |
- Each
Conditionis decoded by kind (threshold, absence, log match, MQL, PromQL, SQL): the filter or query, comparison, threshold, duration, aggregations and trigger. Its raw JSON is kept beside for everything else, and for kinds Google adds later. - A patch without a mask replaces the whole policy, so
updateMask=enabledalways goes, with the field set. A repeat answers 200, so the patch retries like a read. severityis not a policy filter field (production refuses it). Withoutorder_by, policies come back sorted by name.
Snoozes
| Call | What it does |
|---|---|
Client.createSnooze(spec) |
Makes one; never sent twice once it may have reached Google, since snoozes can't be deleted |
Client.listSnoozes(options), Client.getSnooze(id) |
Newest start first; active_at asks for the ones holding at a time |
Client.endSnooze(snooze, at) |
Ends one early, in the form production takes for its state |
Client.createSnoozeRequest(spec), Client.endSnoozeRequest(snooze, at) |
The writes' exact requests |
- Production needs a different request to end a snooze depending on its state. Active for a minute or more: the end at now. Active for less: the end at its start (a cancel). Upcoming: both times now.
endSnoozetakes the snooze as read and sends the right one. Production refuses any change to an ended snooze, a repeat included, so a lost answer is read back.
What production showed
Measured on 2026-10-20 in a test project:
- A snooze closed a real open alert one second after its start and kept new ones from opening. After it ended, a new alert opened about 77 s later, the condition still true.
- Snooze lists lag behind a create: a get shows a new snooze at once, but a list took 91 s once and 79 s in the production test. Keep the create's answer rather than re-listing.
- Production doesn't check that a snooze's policies exist, and has no whole-minutes rule. The filter takes only
>=and<=on the interval's times. monitoring.readserves every read and is refused every write, which needsmonitoringorcloud-platform;monitoring.writeis refused all of these calls. On the IAM side:alertPolicyViewer/alertPolicyEditorandsnoozeViewer/snoozeEditor.- SQL conditions need a Log Analytics view; production refused one without.
Testing
FakeMonitoring.putAlertPolicy puts policies in, read, filtered, ordered and patched as production answered, refusals in its words. Snoozes go through the API, checked in production's order and words, and an active snooze closes the open alerts of its policies. A slow fuzz property holds snoozes and alerts to a model. The gated production test (MONITORING_TEST_POLICIES=1) agreed with the fake on every step, and all 10 previews matched what was sent, byte for byte.
The guides: Alert policies, Snoozes and Testing. examples/monitoring_policies.zig --fake --snooze ID --yes shows the confirm-then-write flow offline.
The changelog has each module's entry.
zig fetch --save git+https://github.com/kmoneil/zig-gcp#v0.52.0