Files
michaelschiemer/scripts/ci/monitor-workflow-performance.sh
Michael Schiemer 72757954dc
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 33s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Successful in 32s
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Composer Security Audit (push) Has been skipped
🧊 Warm Docker Build Cache / Refresh Buildx Caches (push) Failing after 11s
📊 Monitor Workflow Performance / Monitor Workflow Performance (push) Failing after 20s
feat: optimize workflows with repository artifacts and add performance monitoring
- Use repository artifacts in test and build jobs (reduces 2-3 git clones per run)
- Add comprehensive workflow performance monitoring system
- Add monitoring playbook and Gitea workflow for automated metrics collection
- Add monitoring documentation and scripts

Optimizations:
- Repository artifact caching: changes job uploads repo, test/build jobs download it
- Reduces Gitea load by eliminating redundant git operations
- Faster job starts (artifact download is typically faster than git clone)

Monitoring:
- Script for local workflow metrics collection via Gitea API
- Ansible playbook for server-side system and Gitea metrics
- Automated Gitea workflow that runs every 6 hours
- Tracks workflow durations, system load, Gitea API response times, and more
2025-11-09 04:03:51 +01:00

181 lines
5.1 KiB
Bash
Executable File

#!/bin/bash
# Monitor Workflow Performance
# Collects metrics about workflow execution times, Gitea load, and resource usage
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
OUTPUT_DIR="${REPO_ROOT}/monitoring/workflow-metrics"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
METRICS_FILE="${OUTPUT_DIR}/workflow_metrics_${TIMESTAMP}.json"
# Create output directory
mkdir -p "$OUTPUT_DIR"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}📊 Workflow Performance Monitor${NC}"
echo "=================================="
echo ""
# Check if Gitea API credentials are available
GITEA_URL="${GITEA_URL:-https://git.michaelschiemer.de}"
GITEA_TOKEN="${GITEA_TOKEN:-${CI_TOKEN:-}}"
REPO="${GITHUB_REPOSITORY:-michael/michaelschiemer}"
if [ -z "$GITEA_TOKEN" ]; then
echo -e "${YELLOW}⚠️ GITEA_TOKEN not set, some metrics will be unavailable${NC}"
fi
# Function to get workflow runs from Gitea API
get_workflow_runs() {
local workflow_name="$1"
local limit="${2:-10}"
if [ -z "$GITEA_TOKEN" ]; then
echo "[]"
return
fi
local api_url="${GITEA_URL}/api/v1/repos/${REPO}/actions/runs"
if [ -n "$workflow_name" ]; then
api_url="${api_url}?workflow=${workflow_name}&limit=${limit}"
else
api_url="${api_url}?limit=${limit}"
fi
curl -sfL \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Accept: application/json" \
"$api_url" 2>/dev/null || echo "[]"
}
# Function to calculate average duration
calculate_average_duration() {
local runs_json="$1"
local total=0
local count=0
if [ "$runs_json" = "[]" ] || [ -z "$runs_json" ]; then
echo "0"
return
fi
# Extract durations (in seconds) from workflow runs
# Note: This is a simplified parser - in production, use jq
echo "$runs_json" | grep -o '"duration":[0-9]*' | grep -o '[0-9]*' | while read -r duration; do
if [ -n "$duration" ] && [ "$duration" -gt 0 ]; then
total=$((total + duration))
count=$((count + 1))
fi
done
if [ "$count" -eq 0 ]; then
echo "0"
else
echo "$((total / count))"
fi
}
# Collect metrics
echo -e "${BLUE}📥 Collecting workflow metrics...${NC}"
# Get recent workflow runs
BUILD_WORKFLOW_RUNS=$(get_workflow_runs "build-image.yml" 20)
DEPLOY_WORKFLOW_RUNS=$(get_workflow_runs "manual-deploy.yml" 10)
# Calculate metrics
BUILD_AVG_DURATION=$(calculate_average_duration "$BUILD_WORKFLOW_RUNS")
DEPLOY_AVG_DURATION=$(calculate_average_duration "$DEPLOY_WORKFLOW_RUNS")
# Get system metrics (if running on server)
SYSTEM_LOAD="unknown"
DOCKER_CONTAINERS="unknown"
GITEA_RUNNER_STATUS="unknown"
if command -v uptime >/dev/null 2>&1; then
SYSTEM_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ' ')
fi
if command -v docker >/dev/null 2>&1; then
DOCKER_CONTAINERS=$(docker ps --format '{{.Names}}' | wc -l)
if docker ps --format '{{.Names}}' | grep -q "gitea-runner"; then
GITEA_RUNNER_STATUS="running"
else
GITEA_RUNNER_STATUS="stopped"
fi
fi
# Create metrics JSON
cat > "$METRICS_FILE" <<EOF
{
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"workflow_metrics": {
"build_image": {
"average_duration_seconds": $BUILD_AVG_DURATION,
"recent_runs": 20
},
"manual_deploy": {
"average_duration_seconds": $DEPLOY_AVG_DURATION,
"recent_runs": 10
}
},
"system_metrics": {
"load_average": "$SYSTEM_LOAD",
"docker_containers": "$DOCKER_CONTAINERS",
"gitea_runner_status": "$GITEA_RUNNER_STATUS"
},
"optimizations": {
"repository_artifact_enabled": true,
"helper_script_caching_enabled": true,
"combined_deployment_playbook": true,
"exponential_backoff_health_checks": true,
"concurrency_groups": true
}
}
EOF
echo -e "${GREEN}✅ Metrics collected${NC}"
echo ""
echo -e "${BLUE}📈 Summary:${NC}"
echo " Build Workflow Avg Duration: ${BUILD_AVG_DURATION}s"
echo " Deploy Workflow Avg Duration: ${DEPLOY_AVG_DURATION}s"
echo " System Load: $SYSTEM_LOAD"
echo " Docker Containers: $DOCKER_CONTAINERS"
echo " Gitea Runner: $GITEA_RUNNER_STATUS"
echo ""
echo -e "${BLUE}💾 Metrics saved to:${NC} $METRICS_FILE"
echo ""
# Display recent workflow runs summary
if [ "$BUILD_WORKFLOW_RUNS" != "[]" ] && [ -n "$BUILD_WORKFLOW_RUNS" ]; then
echo -e "${BLUE}📋 Recent Build Workflow Runs:${NC}"
echo "$BUILD_WORKFLOW_RUNS" | grep -o '"status":"[^"]*"' | head -5 | sed 's/"status":"//g' | sed 's/"//g' | while read -r status; do
case "$status" in
success)
echo -e " ${GREEN}${NC} Success"
;;
failure)
echo -e " ${RED}${NC} Failed"
;;
running)
echo -e " ${YELLOW}${NC} Running"
;;
*)
echo -e " ${BLUE}?${NC} $status"
;;
esac
done
echo ""
fi
echo -e "${GREEN}✅ Monitoring complete${NC}"