Monitoring and Logging for Cloud Run Functions

Solution for Monitoring and Logging for Cloud Run Functions. 1 lab: GSP092. Fast copy-paste commands for Google Cloud.

GSP092 — Monitoring and Logging for Cloud Run Functions

Estimated time: 20 minutes

# 📊 Monitoring and Logging for Cloud Run Functions > ⚠️ **Disclaimer:** This is an independent, community-made walkthrough created to help you understand why each step works. Attempt the lab yourself first and use this guide as a learning aid rather than as a shortcut to skip the underlying concepts. This guide is intended for educational purposes, hands-on practice, and Google Cloud certification preparation. It is not affiliated with, endorsed by, or officially supported by Google, Google Cl

# ==============================================================================
# Color Variables & Branding
# ==============================================================================
GREEN='\e[1;32m'
CYAN='\e[1;36m'
YELLOW='\e[1;33m'
MAGENTA='\e[1;35m'
RED='\e[1;31m'
RESET='\e[0m'
BOLD='\e[1m'

clear
echo -e "${CYAN}${BOLD}"
cat << "EOF"
  ____       _     _ _            __    ___            
 / __ \     | |   (_) |          / _|  / _ \           
| |  | |_ __| |__  _| |_   ___  | |_  | | | |_ __  ___ 
| |  | | '__| '_ \| | __| / _ \ |  _| | | | | '_ \/ __|
| |__| | |  | |_) | | |_ | (_) || |   | |_| | |_) \__ \
 \____/|_|  |_.__/|_|\__| \___/ |_|    \___/| .__/|___/
                                            | |        
                                            |_|        
EOF
echo -e "${RESET}"
echo -e "${MAGENTA}${BOLD}>>> ORBIT OF OPS: GSP092 PART 1 INITIALIZED <<<${RESET}\n"

echo -e "${YELLOW}${BOLD}[Orbit of Ops] Auto-fetching Project, Zone, and Region...${RESET}"
export PROJECT_ID=$(gcloud config get-value project 2>/dev/null)
if [[ -z "$PROJECT_ID" ]]; then
    export PROJECT_ID=$DEVSHELL_PROJECT_ID
fi

export ZONE=$(gcloud compute project-info describe \
    --format="value(commonInstanceMetadata.items[google-compute-default-zone])" 2>/dev/null | tail -n 1)

if [[ -z "$ZONE" ]]; then
    read -p "⚠️ Could not auto-detect Zone. Please enter the lab Zone (e.g., us-east1-c): " ZONE
    export ZONE
fi

export REGION=${ZONE%-*}
gcloud config set compute/zone $ZONE 2>/dev/null
gcloud config set compute/region $REGION 2>/dev/null

echo -e "✅ Project ID: ${GREEN}$PROJECT_ID${RESET}"
echo -e "✅ Region:     ${GREEN}$REGION${RESET}\n"

echo -e "${CYAN}${BOLD}[Orbit of Ops] Enabling Required APIs...${RESET}"
gcloud services enable run.googleapis.com cloudfunctions.googleapis.com cloudbuild.googleapis.com artifactregistry.googleapis.com logging.googleapis.com || true

echo -e "${YELLOW}${BOLD}[Orbit of Ops] Creating Hello World Node.js Source...${RESET}"
mkdir -p ~/helloworld_func && cd ~/helloworld_func
cat <<EOF > index.js
const functions = require('@google-cloud/functions-framework');
functions.http('helloWorld', (req, res) => {
  res.send('Hello World!');
});
EOF
cat <<EOF > package.json
{
  "name": "helloworld",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0"
  }
}
EOF

echo -e "${CYAN}${BOLD}[Orbit of Ops] Task 1: Deploying Gen 2 Cloud Run Function...${RESET}"
DEPLOY_CMD="gcloud functions deploy helloworld --gen2 --runtime=nodejs22 --region=$REGION --source=. --entry-point=helloWorld --trigger-http --allow-unauthenticated --max-instances=1"
eval $DEPLOY_CMD || { echo -e "${RED}Initial deploy failed. Waiting 45s for IAM sync...${RESET}"; sleep 45; eval $DEPLOY_CMD; }

echo -e "${YELLOW}${BOLD}[Orbit of Ops] Setting up 'vegeta' Load Tester...${RESET}"
cd ~
curl -sLO 'https://github.com/tsenart/vegeta/releases/download/v12.12.0/vegeta_12.12.0_linux_386.tar.gz'
tar -xzf vegeta_12.12.0_linux_386.tar.gz vegeta

export CLOUD_RUN_URL=$(gcloud run services describe helloworld --region=$REGION --format='value(status.url)')
echo -e "✅ Target URL: ${GREEN}$CLOUD_RUN_URL${RESET}"

echo -e "${CYAN}${BOLD}[Orbit of Ops] Generating traffic in the background for 5 minutes...${RESET}"
echo "GET $CLOUD_RUN_URL" | ./vegeta attack -duration=300s -rate=200 > results.bin &

echo -e "\n${GREEN}${BOLD}✅ Part 1 Complete. Check Task 1 progress in the lab window!${RESET}"
# ==============================================================================
# Color Variables & Branding
# ==============================================================================
GREEN='\e[1;32m'
CYAN='\e[1;36m'
YELLOW='\e[1;33m'
MAGENTA='\e[1;35m'
RESET='\e[0m'
BOLD='\e[1m'

echo -e "\n${MAGENTA}${BOLD}>>> ORBIT OF OPS: GSP092 PART 2 (METRIC FIX) <<<${RESET}\n"

echo -e "${YELLOW}${BOLD}[Orbit of Ops] Task 2: Building Distribution Metric Config (with Bucket Options)...${RESET}"
cd ~
cat <<EOF > metric-config.json
{
  "name": "CloudRunFunctionLatency-Logs",
  "description": "Distribution metric for Cloud Run Function Latency",
  "filter": "resource.type=\"cloud_run_revision\" AND resource.labels.service_name=\"helloworld\"",
  "metricDescriptor": {
    "metricKind": "DELTA",
    "valueType": "DISTRIBUTION",
    "unit": "s"
  },
  "valueExtractor": "EXTRACT(httpRequest.latency)",
  "bucketOptions": {
    "exponentialBuckets": {
      "numFiniteBuckets": 64,
      "growthFactor": 2.0,
      "scale": 0.01
    }
  }
}
EOF

echo -e "${CYAN}${BOLD}[Orbit of Ops] Pushing Metric to Cloud Logging...${RESET}"
gcloud logging metrics create CloudRunFunctionLatency-Logs --config-from-file=metric-config.json || true

echo -e "\n${GREEN}${BOLD}🎉 Fix applied! The metric has been created. Please click 'Check my progress' on Task 2!${RESET}"