tutorial

Monitoring Google Cloud Functions with Vigilmon: Serverless Health Checks, Invocation Heartbeats & Cold Start Alerting

Practical guide to uptime monitoring for Google Cloud Functions — HTTP health endpoints, invocation heartbeats, cold start alerting, and multi-region serverless uptime with Vigilmon.

Google Cloud Functions lets you deploy code without managing infrastructure — but that invisibility cuts both ways. A function that returns 500s, a scheduled function that stops firing, or a deployment that silently broke a dependency: none of these produce an external signal unless you've wired one up. Cloud Monitoring can alert on internal metrics, but Vigilmon gives you an external, independent check that fires even when your GCP project or region has a problem.

This tutorial shows you how to wire Cloud Functions into Vigilmon for availability monitoring, invocation heartbeats, and cold-start-aware alerting.

What You'll Build

  • A health-check HTTP function that validates your function environment and dependencies
  • A Vigilmon HTTP monitor for function availability
  • A heartbeat ping at the end of scheduled Cloud Functions
  • A cold-start-aware alerting strategy

Prerequisites

  • A GCP project with at least one deployed Cloud Function (1st or 2nd gen)
  • gcloud CLI configured locally
  • A free account at vigilmon.online

Step 1: Deploy a Health-Check Function

Deploy a dedicated HTTP function that validates your runtime environment, checks downstream dependencies, and returns a structured health response that Vigilmon can probe.

# main.py
import os
import json
import functions_framework
import google.cloud.storage as gcs

@functions_framework.http
def health(request):
    checks = {}
    ok = True

    # Check environment variables are set
    required_vars = ["DB_HOST", "PUBSUB_TOPIC", "GCS_BUCKET"]
    for var in required_vars:
        if os.environ.get(var):
            checks[var] = "set"
        else:
            checks[var] = "missing"
            ok = False

    # Check GCS bucket reachability
    try:
        client = gcs.Client()
        bucket_name = os.environ.get("GCS_BUCKET", "")
        if bucket_name:
            client.get_bucket(bucket_name)
            checks["gcs"] = "reachable"
        else:
            checks["gcs"] = "bucket_not_configured"
    except Exception as e:
        checks["gcs"] = f"error: {str(e)[:80]}"
        ok = False

    status_code = 200 if ok else 503
    return (
        json.dumps({"status": "ok" if ok else "degraded", "checks": checks}),
        status_code,
        {"Content-Type": "application/json"},
    )

Deploy the health function:

gcloud functions deploy health-check \
  --gen2 \
  --runtime python311 \
  --region us-central1 \
  --source . \
  --entry-point health \
  --trigger-http \
  --allow-unauthenticated \
  --set-env-vars DB_HOST=your-db-host,PUBSUB_TOPIC=your-topic,GCS_BUCKET=your-bucket

Step 2: Configure the Vigilmon HTTP Monitor

  1. Log in to VigilmonAdd Monitor → HTTP.
  2. URL: https://us-central1-<project-id>.cloudfunctions.net/health-check
  3. Check interval: 60 seconds.
  4. Response timeout: 15 seconds (Cloud Functions may have cold start latency on first probe).
  5. Expected status: 200.
  6. JSON assertion: path status, expected value ok.

Tip: 2nd-gen Cloud Functions (Cloud Run–backed) support minimum instance configuration. Setting --min-instances 1 eliminates cold starts for your health function and keeps Vigilmon probe times consistently fast.


Step 3: Heartbeat at the End of Scheduled Functions

For Cloud Functions triggered on a schedule by Cloud Scheduler, add a Vigilmon heartbeat ping as the last action. This confirms the function ran to completion, not just that Cloud Scheduler fired the trigger.

# main.py (scheduled function example)
import os
import urllib.request
import functions_framework

@functions_framework.http
def nightly_export(request):
    # Your business logic here
    run_export()
    aggregate_metrics()
    write_report()

    # Heartbeat: signal Vigilmon the job completed
    _ping_vigilmon()

    return ("ok", 200)


def _ping_vigilmon():
    heartbeat_url = os.environ.get("VIGILMON_HEARTBEAT_URL")
    if not heartbeat_url:
        return
    try:
        req = urllib.request.Request(heartbeat_url, method="POST")
        urllib.request.urlopen(req, timeout=5)
    except Exception as e:
        # Don't let a monitoring failure break the main function
        print(f"Vigilmon heartbeat failed: {e}")

Store the heartbeat URL as a Secret Manager secret and inject it as an environment variable:

# Store the secret
echo -n "https://vigilmon.online/api/heartbeat/<your-id>" | \
  gcloud secrets create vigilmon-heartbeat-url --data-file=-

# Deploy with Secret Manager binding
gcloud functions deploy nightly-export \
  --gen2 \
  --runtime python311 \
  --region us-central1 \
  --entry-point nightly_export \
  --trigger-http \
  --set-secrets VIGILMON_HEARTBEAT_URL=vigilmon-heartbeat-url:latest

In Vigilmon, create a Heartbeat monitor with a grace period matching your Cloud Scheduler cron:

| Cloud Scheduler frequency | Recommended grace period | |---|---| | Every 15 minutes | 20 minutes | | Hourly | 75 minutes | | Daily at 2 AM UTC | 26 hours | | Weekly | 8 days |


Step 4: Cold-Start-Aware Alert Thresholds

Cloud Functions cold starts are normal — a new instance spins up when the previous container has been idle. A single slow probe does not mean your function is unhealthy.

Configure Vigilmon to require 2 consecutive failures before sending an alert:

  1. Open your HTTP monitor → Alert settings.
  2. Set Failures before alert: 2.
  3. Set Recovery confirmations: 1.

This eliminates cold-start false positives (a ~1–3 s startup delay causes one probe timeout, then subsequent probes are fast) while still alerting on genuine outages within two check intervals.

For latency-sensitive functions, also add a response time assertion:

| Function tier | Max acceptable p95 latency | Vigilmon timeout | |---|---|---| | Interactive (HTTP trigger, user-facing) | 2 000 ms | 3 000 ms | | Background (Pub/Sub, GCS trigger) | 10 000 ms | 12 000 ms | | Scheduled (nightly batch) | 30 000 ms | use heartbeat instead |


Step 5: Multi-Region Cloud Functions Monitoring

If you deploy the same function to multiple regions for latency or redundancy, monitor each independently so a regional GCP incident doesn't hide behind an aggregated status.

# Deploy to a second region
gcloud functions deploy health-check \
  --gen2 \
  --runtime python311 \
  --region europe-west1 \
  --source . \
  --entry-point health \
  --trigger-http \
  --allow-unauthenticated

Create one Vigilmon monitor per region:

| Region | Monitor name | URL | |---|---|---| | us-central1 | Cloud Functions US | https://us-central1-<project>.cloudfunctions.net/health-check | | europe-west1 | Cloud Functions EU | https://europe-west1-<project>.cloudfunctions.net/health-check | | asia-northeast1 | Cloud Functions AP | https://asia-northeast1-<project>.cloudfunctions.net/health-check |

Group regional monitors under a single Status Page so stakeholders see one aggregate view.


What Vigilmon Catches That Cloud Monitoring Misses

| Scenario | Cloud Monitoring | Vigilmon | |---|---|---| | Function returns 500 | Error rate metric fires | HTTP monitor catches non-200 response | | Scheduled function stops running | No metric by default | Heartbeat grace period fires alert | | GCP regional outage | Alarms may not fire (metrics ingest affected) | External check — fully independent | | Deployment broke a dependency | No alarm by default | Health check detects missing env vars | | Cold start spikes | Latency percentile metric | Response time assertion + consecutive failure threshold |


Cloud Functions makes event-driven code feel effortless — until a silent deployment or a Cloud Scheduler hiccup takes down a nightly pipeline. External monitoring from Vigilmon gives your team the independent signal that catches failures before they become business-visible outages.

Start monitoring your Cloud Functions in under 5 minutes — register free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →