glam/infrastructure/scripts/monitor-chunk-404s.sh
kempersc 3820f2fc92 chore: Add data reports, infra scripts, and API updates
- Data quality reports for Dutch custodians
- Name mismatch detection reports
- Failed crawl URL tracking
- Caddy configuration updates
- Monitor script for chunk 404 errors
- API endpoint improvements
2025-12-15 01:48:08 +01:00

109 lines
3.7 KiB
Bash
Executable file

#!/bin/bash
# Monitor for 404 errors on JavaScript chunks (stale cache detection)
# Usage: ./monitor-chunk-404s.sh [--tail] [--count] [--last-hour]
set -e
SERVER="root@91.98.224.44"
LOG_FILE="/var/log/caddy/bronhouder.log"
# Colors for output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
show_help() {
echo "Monitor chunk load 404 errors from Caddy logs"
echo ""
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " --tail Live tail of 404 errors on /assets/*.js"
echo " --count Count 404s by URI (grouped)"
echo " --last-hour Show 404s from the last hour only"
echo " --all-404s Show all 404 errors (not just assets)"
echo " --summary Quick summary of chunk 404s"
echo " -h, --help Show this help"
echo ""
echo "Examples:"
echo " $0 --summary # Quick overview"
echo " $0 --tail # Watch live 404s"
echo " $0 --count # See which chunks are missing most"
}
# Quick summary
summary() {
echo -e "${YELLOW}=== Chunk 404 Summary ===${NC}"
# Total 404s on assets
TOTAL=$(ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/.*\\.js\")))' 2>/dev/null | wc -l" || echo "0")
echo -e "Total JS chunk 404s: ${RED}$TOTAL${NC}"
# Unique chunks
UNIQUE=$(ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/.*\\.js\"))) | .request.uri' 2>/dev/null | sort -u | wc -l" || echo "0")
echo -e "Unique missing chunks: ${YELLOW}$UNIQUE${NC}"
# Last 404 timestamp
LAST=$(ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/.*\\.js\"))) | .ts' 2>/dev/null | tail -1" || echo "")
if [ -n "$LAST" ]; then
LAST_DATE=$(date -r ${LAST%.*} 2>/dev/null || echo "unknown")
echo -e "Last chunk 404: $LAST_DATE"
fi
echo ""
echo -e "${GREEN}Top 5 missing chunks:${NC}"
ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/.*\\.js\"))) | .request.uri' 2>/dev/null | sort | uniq -c | sort -rn | head -5" || echo " (none)"
}
# Live tail
tail_logs() {
echo -e "${YELLOW}=== Watching for chunk 404s (Ctrl+C to stop) ===${NC}"
ssh $SERVER "tail -f $LOG_FILE" | jq -r --unbuffered 'select(.status == 404 and (.request.uri | test("/assets/"))) | "\(.ts | todate) | \(.status) | \(.request.uri) | \(.request.remote_ip)"'
}
# Count by URI
count_by_uri() {
echo -e "${YELLOW}=== 404 Counts by URI ===${NC}"
ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/\"))) | .request.uri'" | sort | uniq -c | sort -rn | head -20
}
# Last hour only
last_hour() {
HOUR_AGO=$(date -v-1H +%s 2>/dev/null || date -d '1 hour ago' +%s)
echo -e "${YELLOW}=== Chunk 404s in the last hour ===${NC}"
ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404 and (.request.uri | test(\"/assets/\")) and .ts > $HOUR_AGO) | \"\(.ts | todate) | \(.request.uri) | \(.request.remote_ip)\"'" | head -50
}
# All 404s
all_404s() {
echo -e "${YELLOW}=== All 404 Errors (last 50) ===${NC}"
ssh $SERVER "cat $LOG_FILE 2>/dev/null | jq -r 'select(.status == 404) | \"\(.ts | todate) | \(.request.uri)\"'" | tail -50
}
# Parse arguments
case "${1:-}" in
--tail)
tail_logs
;;
--count)
count_by_uri
;;
--last-hour)
last_hour
;;
--all-404s)
all_404s
;;
--summary|"")
summary
;;
-h|--help)
show_help
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac