Skip to content
Get started

How to monitor Google Cloud Scheduler jobs

To monitor a Cloud Scheduler job, watch its execution logs in Cloud Logging: Cloud Scheduler publishes a log at the start and end of every execution, so pair each AttemptStarted entry with its matching AttemptFinished entry and alert when the finish is missing or has a non-2xx status. Create a log-based metric and a Cloud Monitoring alerting policy for failed executions, or route the logs to a Pub/Sub topic for real-time processing.

What does Cloud Scheduler log for each execution?

Cloud Scheduler writes two log entries per HTTP execution to Cloud Logging:

  • AttemptStarted: written when the scheduler dispatches the HTTP request to your target.
  • AttemptFinished: written when the target responds. Includes the HTTP status code — 2xx is success, anything else is a failure.
  • A job that never gets an AttemptFinished (target timed out) or gets a non-2xx status is a failed execution.

How do I create a Cloud Monitoring alert for failed executions?

Create a log-based metric that counts failed AttemptFinished entries, then an alerting policy that fires when the count is above zero:

gcloud CLI
# Create a log-based metric for failed Cloud Scheduler executions
gcloud logging metrics create cloud_scheduler_failures \
  --description="Cloud Scheduler job failures" \
  --log-filter='resource.type="cloud_scheduler_job"
    jsonPayload.@type="type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jsonPayload.status!="OK"'

# Then create an alerting policy in Cloud Monitoring that fires when
# cloud_scheduler_failures > 0 over the past 5 minutes.

How do I detect a job that never ran at all?

A job that was never attempted — disabled state, bad schedule expression, or a quota error — produces no AttemptStarted log entry. The log-based metric above counts failures, not absences. To detect a missing run, add a heartbeat from inside your target endpoint: if no ping arrives in the expected window, your external monitor alerts regardless of what Cloud Logging shows.

Cloud Run / App Engine target endpoint
import httpx
from flask import Flask, jsonify

app = Flask(__name__)
PING_URL = "https://ping.cronshield.com/<your-check-id>"

@app.route("/cron/nightly")
def nightly():
    try:
        run_nightly_job()
        httpx.get(PING_URL, timeout=10)
        return jsonify({"status": "ok"})
    except Exception as exc:
        return jsonify({"error": str(exc)}), 500
PING_URL is a placeholder for the endpoint you get when you create a monitor. The CronShield receiver ships in an upcoming release.

Add a missed-run alert to this job

The free tier gives you a heartbeat endpoint and an email alert when an expected ping doesn't arrive. Paid tiers add the log-aware diagnosis — the last log line and a likely cause in the alert. The heartbeat receiver ships in an upcoming release; see the plans to learn what each tier adds.

Frequently asked questions

Does Cloud Scheduler retry a failed invocation?
Yes. You can configure a retry config on the job with a maximum retry count and minimum/maximum backoff. Each retry attempt is logged as a separate AttemptStarted/AttemptFinished pair. If all retries are exhausted, the job is counted as failed.
How do I view Cloud Scheduler logs in Cloud Logging?
In the Google Cloud Console, go to Logging > Logs Explorer and filter by resource type 'cloud_scheduler_job'. Filter by your job name to see its execution history. Each entry includes the HTTP request, response status code, and execution duration.