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],
});

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",
});