Skip to content

Logging & Monitoring

Cloud Run sends everything your service logs to Cloud Logging, with no setup. Declare the checks and alerts that watch it next to the service itself.

Effect.log goes to Cloud Logging:

yield* Effect.log(`order ${id} confirmed`);
yield* Effect.logWarning(`retrying ${id}`);

An uptime check probes a URL from several regions:

Effect.gen(function* () {
const api = yield* Api;
const check = yield* GCP.Monitoring.UptimeCheckConfig("ApiUp", {
httpCheck: { path: "/", useSsl: true, validateSsl: true },
monitoredResource: {
type: "uptime_url",
labels: { host: Output.map(api.uri, (uri) => new URL(uri!).host) },
},
period: "300s",
});
}),

Create a channel to send alerts to:

const oncall = yield* GCP.Monitoring.NotificationChannel("Oncall", {
type: "email",
labels: { email_address: "oncall@example.com" },
});

An alert policy opens an incident when a condition holds. This one fires when the service answers with 5xx errors:

yield* GCP.Monitoring.AlertPolicy("ApiErrors", {
combiner: "OR",
conditions: [
{
displayName: "5xx responses",
conditionThreshold: {
filter:
'resource.type = "cloud_run_revision" AND metric.type = "run.googleapis.com/request_count" AND metric.labels.response_code_class = "5xx"',
comparison: "COMPARISON_GT",
thresholdValue: 5,
duration: "60s",
aggregations: [{ alignmentPeriod: "60s", perSeriesAligner: "ALIGN_RATE" }],
},
},
],
notificationChannels: [oncall.name],
});
5xx > 5/sthe conditioncondition holdsApiErrorsincidentopenheld 60s: oncall notifiedclears: closes
The condition has to hold for its whole duration before the policy opens an incident and notifies the channel. When the errors stop, the incident closes.

A logs-based metric turns matching log entries into a metric you can chart and alert on:

const errors = yield* GCP.Logging.Metric("Errors", {
filter: 'resource.type = "cloud_run_revision" AND severity >= ERROR',
description: "error log entries",
});

A sink copies matching entries to another destination, such as a log bucket or BigQuery:

yield* GCP.Logging.Sink("ErrorArchive", {
destination:
"logging.googleapis.com/projects/my-project/locations/global/buckets/_Default",
filter: "severity >= ERROR",
});