Error Rate Monitor - Hooks
Tracks error patterns and alerts when error rates spike. This Notification hook provides comprehensive error rate monitoring across log files, Docker containers, and application logs, automatically detecting error patterns and alerting when error rates exceed configurable thresholds.
Open the source and read safety notes before installing.
Schema details
- Install type
- cli
- Reading time
- 1 min
- Difficulty score
- 0
- Troubleshooting
- Yes
- Breaking changes
- No
- Trigger
- Notification
- Script language
- bash
Script body
#!/usr/bin/env bash
echo "🔍 Monitoring error rates across log files..." >&2
# Configurable thresholds (can be overridden by environment variables)
ERROR_THRESHOLD_PER_FILE=${ERROR_THRESHOLD_PER_FILE:-5}
TOTAL_ERROR_THRESHOLD=${TOTAL_ERROR_THRESHOLD:-10}
LOG_LINES_TO_CHECK=${LOG_LINES_TO_CHECK:-100}
MAX_SAMPLE_ERRORS=${MAX_SAMPLE_ERRORS:-3}
# Initialize counters
TOTAL_ERRORS=0
FILES_WITH_ERRORS=0
CRITICAL_FILES=()
ERROR_SAMPLES=()
# Define error patterns with severity levels
FATAL_PATTERNS=("fatal" "critical" "panic" "abort" "segfault")
ERROR_PATTERNS=("error" "exception" "failed" "failure" "timeout")
WARNING_PATTERNS=("warning" "warn" "deprecated" "notice")
# Function to count errors by severity
count_errors_by_severity() {
local log_file="$1"
local fatal_count=0
local error_count=0
local warning_count=0
if [ ! -f "$log_file" ]; then
return
fi
# Check last N lines of the log file
local recent_logs=$(tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null || echo "")
if [ -z "$recent_logs" ]; then
return
fi
# Count fatal errors
for pattern in "${FATAL_PATTERNS[@]}"; do
fatal_count=$((fatal_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
# Count errors (excluding fatals already counted)
for pattern in "${ERROR_PATTERNS[@]}"; do
error_count=$((error_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
# Count warnings
for pattern in "${WARNING_PATTERNS[@]}"; do
warning_count=$((warning_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
echo "$fatal_count $error_count $warning_count"
}
# Function to extract error samples
extract_error_samples() {
local log_file="$1"
local sample_count="$2"
if [ ! -f "$log_file" ]; then
return
fi
# Get recent error lines with timestamps if available
tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null | \
grep -iE '(fatal|critical|error|exception|failed)' | \
head -"$sample_count" | \
while IFS= read -r line; do
# Truncate very long lines
if [ ${#line} -gt 120 ]; then
echo "${line:0:120}..."
else
echo "$line"
fi
done
}
# Function to check log files in a directory
check_log_directory() {
local dir="$1"
local pattern="$2"
if [ ! -d "$dir" ]; then
return
fi
find "$dir" -name "$pattern" -type f 2>/dev/null | while read -r log_file; do
echo "$log_file"
done
}
# Collect all log files to check
LOG_FILES=()
# Standard log locations
for pattern in "*.log" "*.out" "*.err"; do
while IFS= read -r -d '' file; do
LOG_FILES+=("$file")
done < <(find . -maxdepth 1 -name "$pattern" -type f -print0 2>/dev/null)
done
# Common log directories
LOG_DIRS=("logs" "log" "var/log" ".logs" "tmp/logs")
for log_dir in "${LOG_DIRS[@]}"; do
if [ -d "$log_dir" ]; then
while IFS= read -r -d '' file; do
LOG_FILES+=("$file")
done < <(find "$log_dir" -name "*.log" -o -name "*.out" -o -name "*.err" -type f -print0 2>/dev/null)
fi
done
# Framework-specific log locations
if [ -f "package.json" ]; then
# Node.js specific logs
for pattern in "npm-debug.log" "yarn-error.log" "pnpm-debug.log"; do
[ -f "$pattern" ] && LOG_FILES+=("$pattern")
done
# Next.js logs
[ -d ".next" ] && find .next -name "*.log" -type f 2>/dev/null | while read -r file; do
LOG_FILES+=("$file")
done
fi
# Python specific logs
if [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
for pattern in "django.log" "flask.log" "celery.log" "pytest.log"; do
[ -f "$pattern" ] && LOG_FILES+=("$pattern")
done
fi
# Docker logs if Docker is available
if command -v docker &> /dev/null && docker info &> /dev/null 2>&1; then
# Check for recent container logs with errors
CONTAINERS=$(docker ps --format "{{.Names}}" 2>/dev/null | head -5)
for container in $CONTAINERS; do
if [ -n "$container" ]; then
ERROR_COUNT=$(docker logs "$container" --since=10m 2>&1 | grep -icE '(fatal|critical|error|exception)' || echo "0")
if [ "$ERROR_COUNT" -gt 0 ]; then
echo "🐳 Container '$container' has $ERROR_COUNT recent errors" >&2
TOTAL_ERRORS=$((TOTAL_ERRORS + ERROR_COUNT))
# Get error samples from container logs
CONTAINER_ERRORS=$(docker logs "$container" --since=10m 2>&1 | grep -iE '(fatal|critical|error|exception)' | head -2)
if [ -n "$CONTAINER_ERRORS" ]; then
echo "📝 Sample from $container:" >&2
echo "$CONTAINER_ERRORS" | head -1 >&2
fi
fi
fi
done
fi
# Remove duplicates from LOG_FILES array
readarray -t UNIQUE_LOG_FILES < <(printf '%s\n' "${LOG_FILES[@]}" | sort -u)
echo "📊 Checking ${#UNIQUE_LOG_FILES[@]} log files for error patterns..." >&2
# Check each log file
for log_file in "${UNIQUE_LOG_FILES[@]}"; do
if [ ! -f "$log_file" ]; then
continue
fi
# Get error counts by severity
read -r fatal_count error_count warning_count <<< "$(count_errors_by_severity "$log_file")"
file_total_errors=$((fatal_count + error_count))
TOTAL_ERRORS=$((TOTAL_ERRORS + file_total_errors))
if [ "$file_total_errors" -gt 0 ]; then
FILES_WITH_ERRORS=$((FILES_WITH_ERRORS + 1))
log_basename=$(basename "$log_file")
# Report file-level errors
if [ "$fatal_count" -gt 0 ]; then
echo "🚨 CRITICAL: $log_basename has $fatal_count fatal errors" >&2
CRITICAL_FILES+=("$log_file")
fi
if [ "$file_total_errors" -gt "$ERROR_THRESHOLD_PER_FILE" ]; then
echo "⚠️ ERROR SPIKE: $log_basename has $file_total_errors errors (fatal: $fatal_count, error: $error_count)" >&2
# Extract error samples
echo "📝 Recent error samples from $log_basename:" >&2
extract_error_samples "$log_file" "$MAX_SAMPLE_ERRORS" | while IFS= read -r sample; do
echo " → $sample" >&2
done
elif [ "$file_total_errors" -gt 0 ]; then
echo "ℹ️ $log_basename: $file_total_errors errors detected" >&2
fi
if [ "$warning_count" -gt 0 ]; then
echo "⚠️ $log_basename: $warning_count warnings" >&2
fi
fi
done
# Overall error rate analysis
echo "" >&2
echo "📋 Error Rate Summary:" >&2
echo " 📁 Files checked: ${#UNIQUE_LOG_FILES[@]}" >&2
echo " 📄 Files with errors: $FILES_WITH_ERRORS" >&2
echo " 🔢 Total errors: $TOTAL_ERRORS" >&2
echo " 🚨 Critical files: ${#CRITICAL_FILES[@]}" >&2
# Alert on high error rates
if [ "$TOTAL_ERRORS" -gt "$TOTAL_ERROR_THRESHOLD" ]; then
echo "" >&2
echo "🚨 HIGH ERROR RATE DETECTED!" >&2
echo "⚠️ Total errors ($TOTAL_ERRORS) exceed threshold ($TOTAL_ERROR_THRESHOLD)" >&2
if [ ${#CRITICAL_FILES[@]} -gt 0 ]; then
echo "🔥 Critical files requiring immediate attention:" >&2
for critical_file in "${CRITICAL_FILES[@]}"; do
echo " → $(basename "$critical_file")" >&2
done
fi
elif [ "$TOTAL_ERRORS" -gt 0 ]; then
echo "ℹ️ Errors detected but within acceptable threshold" >&2
else
echo "✅ No errors detected in monitored log files" >&2
fi
# Performance recommendations
if [ ${#UNIQUE_LOG_FILES[@]} -gt 20 ]; then
echo "" >&2
echo "💡 Performance tip: Consider log rotation or filtering for faster monitoring" >&2
fi
echo "" >&2
echo "🔧 Monitoring Configuration:" >&2
echo " • Error threshold per file: $ERROR_THRESHOLD_PER_FILE" >&2
echo " • Total error threshold: $TOTAL_ERROR_THRESHOLD" >&2
echo " • Lines checked per file: $LOG_LINES_TO_CHECK" >&2
echo "" >&2
echo "💡 Customize thresholds with environment variables:" >&2
echo " export ERROR_THRESHOLD_PER_FILE=10" >&2
echo " export TOTAL_ERROR_THRESHOLD=25" >&2
exit 0Full copyable content
{
"hooks": {
"notification": {
"script": "./.claude/hooks/error-rate-monitor.sh"
}
}
}About this resource
Features
- Real-time error pattern detection in log files with automatic log file discovery across standard locations (logs/, var/log/, .logs/) and framework-specific locations (Next.js .next/, Node.js npm-debug.log, Python django.log)
- Configurable error rate thresholds and alerting with environment variable configuration (ERROR_THRESHOLD_PER_FILE, TOTAL_ERROR_THRESHOLD) and customizable alert levels
- Multi-log file monitoring (.log, logs/, custom paths) with recursive directory scanning and support for multiple log file formats (_.log, _.out, *.err)
- Error severity classification (fatal, error, warning) with pattern-based severity detection including fatal patterns (fatal, critical, panic, abort, segfault), error patterns (error, exception, failed, failure, timeout), and warning patterns (warning, warn, deprecated, notice)
- Recent error sample display for quick debugging with truncated error messages (120 character limit) and configurable sample count (MAX_SAMPLE_ERRORS)
- Time-based error rate calculations with configurable time windows (LOG_LINES_TO_CHECK) and Docker container log monitoring with --since time window support
- Framework-specific error pattern recognition for Node.js (npm-debug.log, yarn-error.log, pnpm-debug.log), Python (django.log, flask.log, celery.log), Next.js (.next/logs), and Docker container logs
- Docker container log monitoring with Docker Engine 24.0+ support including automatic container discovery, recent error detection (--since=10m), and container-specific error sampling
Use Cases
- Real-time error monitoring during development providing immediate feedback when errors occur in log files or Docker containers during active development
- Automated error rate alerting for CI/CD pipelines automatically detecting error spikes in build logs and test outputs to prevent deployment of broken code
- Multi-service application error tracking monitoring errors across multiple services and containers in microservices architectures with centralized error reporting
- Docker container log monitoring automatically monitoring Docker container logs for errors and providing container-specific error samples for debugging
- Framework-specific error pattern detection automatically recognizing framework-specific error patterns in Node.js, Python, Next.js, and other application frameworks
- Development workflow integration seamlessly integrating error monitoring into development workflows without manual log file inspection or separate monitoring tools
Installation
- Create hooks directory: mkdir -p .claude/hooks
- Create hook file: touch .claude/hooks/error-rate-monitor.sh
- Make executable: chmod +x .claude/hooks/error-rate-monitor.sh
- Add configuration from Hook Configuration section above to .claude/settings.json or ~/.claude/settings.json
- Alternative: Use the interactive /hooks command in Claude Code
Config paths
- Local (not committed):
.claude/settings.local.json - User settings (global):
~/.claude/settings.json - Project-wide (committed):
.claude/settings.json
Requirements
- Claude Code CLI installed
- Project directory initialized
- Bash shell available
- Docker Engine 24.0+ (optional, for Docker container log monitoring)
- grep and find utilities (standard Unix tools)
- File system read access for log files in project directories (logs/, var/log/, .logs/, .next/logs/) and Docker container log access when Docker is available
Hook Configuration
{
"hooks": {
"notification": {
"script": "./.claude/hooks/error-rate-monitor.sh"
}
}
}
Hook Script
#!/usr/bin/env bash
echo "🔍 Monitoring error rates across log files..." >&2
# Configurable thresholds (can be overridden by environment variables)
ERROR_THRESHOLD_PER_FILE=${ERROR_THRESHOLD_PER_FILE:-5}
TOTAL_ERROR_THRESHOLD=${TOTAL_ERROR_THRESHOLD:-10}
LOG_LINES_TO_CHECK=${LOG_LINES_TO_CHECK:-100}
MAX_SAMPLE_ERRORS=${MAX_SAMPLE_ERRORS:-3}
# Initialize counters
TOTAL_ERRORS=0
FILES_WITH_ERRORS=0
CRITICAL_FILES=()
ERROR_SAMPLES=()
# Define error patterns with severity levels
FATAL_PATTERNS=("fatal" "critical" "panic" "abort" "segfault")
ERROR_PATTERNS=("error" "exception" "failed" "failure" "timeout")
WARNING_PATTERNS=("warning" "warn" "deprecated" "notice")
# Function to count errors by severity
count_errors_by_severity() {
local log_file="$1"
local fatal_count=0
local error_count=0
local warning_count=0
if [ ! -f "$log_file" ]; then
return
fi
# Check last N lines of the log file
local recent_logs=$(tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null || echo "")
if [ -z "$recent_logs" ]; then
return
fi
# Count fatal errors
for pattern in "${FATAL_PATTERNS[@]}"; do
fatal_count=$((fatal_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
# Count errors (excluding fatals already counted)
for pattern in "${ERROR_PATTERNS[@]}"; do
error_count=$((error_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
# Count warnings
for pattern in "${WARNING_PATTERNS[@]}"; do
warning_count=$((warning_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
echo "$fatal_count $error_count $warning_count"
}
# Function to extract error samples
extract_error_samples() {
local log_file="$1"
local sample_count="$2"
if [ ! -f "$log_file" ]; then
return
fi
# Get recent error lines with timestamps if available
tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null | \
grep -iE '(fatal|critical|error|exception|failed)' | \
head -"$sample_count" | \
while IFS= read -r line; do
# Truncate very long lines
if [ ${#line} -gt 120 ]; then
echo "${line:0:120}..."
else
echo "$line"
fi
done
}
# Function to check log files in a directory
check_log_directory() {
local dir="$1"
local pattern="$2"
if [ ! -d "$dir" ]; then
return
fi
find "$dir" -name "$pattern" -type f 2>/dev/null | while read -r log_file; do
echo "$log_file"
done
}
# Collect all log files to check
LOG_FILES=()
# Standard log locations
for pattern in "*.log" "*.out" "*.err"; do
while IFS= read -r -d '' file; do
LOG_FILES+=("$file")
done < <(find . -maxdepth 1 -name "$pattern" -type f -print0 2>/dev/null)
done
# Common log directories
LOG_DIRS=("logs" "log" "var/log" ".logs" "tmp/logs")
for log_dir in "${LOG_DIRS[@]}"; do
if [ -d "$log_dir" ]; then
while IFS= read -r -d '' file; do
LOG_FILES+=("$file")
done < <(find "$log_dir" -name "*.log" -o -name "*.out" -o -name "*.err" -type f -print0 2>/dev/null)
fi
done
# Framework-specific log locations
if [ -f "package.json" ]; then
# Node.js specific logs
for pattern in "npm-debug.log" "yarn-error.log" "pnpm-debug.log"; do
[ -f "$pattern" ] && LOG_FILES+=("$pattern")
done
# Next.js logs
[ -d ".next" ] && find .next -name "*.log" -type f 2>/dev/null | while read -r file; do
LOG_FILES+=("$file")
done
fi
# Python specific logs
if [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
for pattern in "django.log" "flask.log" "celery.log" "pytest.log"; do
[ -f "$pattern" ] && LOG_FILES+=("$pattern")
done
fi
# Docker logs if Docker is available
if command -v docker &> /dev/null && docker info &> /dev/null 2>&1; then
# Check for recent container logs with errors
CONTAINERS=$(docker ps --format "{{.Names}}" 2>/dev/null | head -5)
for container in $CONTAINERS; do
if [ -n "$container" ]; then
ERROR_COUNT=$(docker logs "$container" --since=10m 2>&1 | grep -icE '(fatal|critical|error|exception)' || echo "0")
if [ "$ERROR_COUNT" -gt 0 ]; then
echo "🐳 Container '$container' has $ERROR_COUNT recent errors" >&2
TOTAL_ERRORS=$((TOTAL_ERRORS + ERROR_COUNT))
# Get error samples from container logs
CONTAINER_ERRORS=$(docker logs "$container" --since=10m 2>&1 | grep -iE '(fatal|critical|error|exception)' | head -2)
if [ -n "$CONTAINER_ERRORS" ]; then
echo "📝 Sample from $container:" >&2
echo "$CONTAINER_ERRORS" | head -1 >&2
fi
fi
fi
done
fi
# Remove duplicates from LOG_FILES array
readarray -t UNIQUE_LOG_FILES < <(printf '%s\n' "${LOG_FILES[@]}" | sort -u)
echo "📊 Checking ${#UNIQUE_LOG_FILES[@]} log files for error patterns..." >&2
# Check each log file
for log_file in "${UNIQUE_LOG_FILES[@]}"; do
if [ ! -f "$log_file" ]; then
continue
fi
# Get error counts by severity
read -r fatal_count error_count warning_count <<< "$(count_errors_by_severity "$log_file")"
file_total_errors=$((fatal_count + error_count))
TOTAL_ERRORS=$((TOTAL_ERRORS + file_total_errors))
if [ "$file_total_errors" -gt 0 ]; then
FILES_WITH_ERRORS=$((FILES_WITH_ERRORS + 1))
log_basename=$(basename "$log_file")
# Report file-level errors
if [ "$fatal_count" -gt 0 ]; then
echo "🚨 CRITICAL: $log_basename has $fatal_count fatal errors" >&2
CRITICAL_FILES+=("$log_file")
fi
if [ "$file_total_errors" -gt "$ERROR_THRESHOLD_PER_FILE" ]; then
echo "⚠️ ERROR SPIKE: $log_basename has $file_total_errors errors (fatal: $fatal_count, error: $error_count)" >&2
# Extract error samples
echo "📝 Recent error samples from $log_basename:" >&2
extract_error_samples "$log_file" "$MAX_SAMPLE_ERRORS" | while IFS= read -r sample; do
echo " → $sample" >&2
done
elif [ "$file_total_errors" -gt 0 ]; then
echo "ℹ️ $log_basename: $file_total_errors errors detected" >&2
fi
if [ "$warning_count" -gt 0 ]; then
echo "⚠️ $log_basename: $warning_count warnings" >&2
fi
fi
done
# Overall error rate analysis
echo "" >&2
echo "📋 Error Rate Summary:" >&2
echo " 📁 Files checked: ${#UNIQUE_LOG_FILES[@]}" >&2
echo " 📄 Files with errors: $FILES_WITH_ERRORS" >&2
echo " 🔢 Total errors: $TOTAL_ERRORS" >&2
echo " 🚨 Critical files: ${#CRITICAL_FILES[@]}" >&2
# Alert on high error rates
if [ "$TOTAL_ERRORS" -gt "$TOTAL_ERROR_THRESHOLD" ]; then
echo "" >&2
echo "🚨 HIGH ERROR RATE DETECTED!" >&2
echo "⚠️ Total errors ($TOTAL_ERRORS) exceed threshold ($TOTAL_ERROR_THRESHOLD)" >&2
if [ ${#CRITICAL_FILES[@]} -gt 0 ]; then
echo "🔥 Critical files requiring immediate attention:" >&2
for critical_file in "${CRITICAL_FILES[@]}"; do
echo " → $(basename "$critical_file")" >&2
done
fi
elif [ "$TOTAL_ERRORS" -gt 0 ]; then
echo "ℹ️ Errors detected but within acceptable threshold" >&2
else
echo "✅ No errors detected in monitored log files" >&2
fi
# Performance recommendations
if [ ${#UNIQUE_LOG_FILES[@]} -gt 20 ]; then
echo "" >&2
echo "💡 Performance tip: Consider log rotation or filtering for faster monitoring" >&2
fi
echo "" >&2
echo "🔧 Monitoring Configuration:" >&2
echo " • Error threshold per file: $ERROR_THRESHOLD_PER_FILE" >&2
echo " • Total error threshold: $TOTAL_ERROR_THRESHOLD" >&2
echo " • Lines checked per file: $LOG_LINES_TO_CHECK" >&2
echo "" >&2
echo "💡 Customize thresholds with environment variables:" >&2
echo " export ERROR_THRESHOLD_PER_FILE=10" >&2
echo " export TOTAL_ERROR_THRESHOLD=25" >&2
exit 0
Examples
Error Rate Monitor Hook Script
Complete hook script that performs error rate monitoring across log files
#!/usr/bin/env bash
echo "Monitoring error rates across log files..." >&2
ERROR_THRESHOLD_PER_FILE=${ERROR_THRESHOLD_PER_FILE:-5}
TOTAL_ERROR_THRESHOLD=${TOTAL_ERROR_THRESHOLD:-10}
LOG_LINES_TO_CHECK=${LOG_LINES_TO_CHECK:-100}
TOTAL_ERRORS=0
for log_file in *.log logs/*.log 2>/dev/null; do
if [ -f "$log_file" ]; then
ERROR_COUNT=$(tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null | grep -icE '(fatal|critical|error|exception)' || echo "0")
TOTAL_ERRORS=$((TOTAL_ERRORS + ERROR_COUNT))
if [ "$ERROR_COUNT" -gt "$ERROR_THRESHOLD_PER_FILE" ]; then
echo "ERROR SPIKE: $log_file has $ERROR_COUNT errors" >&2
fi
fi
done
if [ "$TOTAL_ERRORS" -gt "$TOTAL_ERROR_THRESHOLD" ]; then
echo "HIGH ERROR RATE DETECTED: $TOTAL_ERRORS errors" >&2
fi
exit 0
Docker Container Error Monitoring
Enhanced hook script for Docker container error monitoring with Docker Engine 24.0+ support
#!/usr/bin/env bash
if command -v docker &> /dev/null && docker info &> /dev/null 2>&1; then
CONTAINERS=$(docker ps --format "{{.Names}}" 2>/dev/null | head -5)
for container in $CONTAINERS; do
if [ -n "$container" ]; then
ERROR_COUNT=$(docker logs "$container" --since=10m 2>&1 | grep -icE '(fatal|critical|error|exception)' || echo "0")
if [ "$ERROR_COUNT" -gt 0 ]; then
echo "Container '$container' has $ERROR_COUNT recent errors" >&2
docker logs "$container" --since=10m 2>&1 | grep -iE '(fatal|critical|error|exception)' | head -2 >&2
fi
fi
done
fi
exit 0
Error Severity Classification
Enhanced hook script for error severity classification with fatal, error, and warning pattern detection
#!/usr/bin/env bash
ERROR_THRESHOLD_PER_FILE=${ERROR_THRESHOLD_PER_FILE:-5}
LOG_LINES_TO_CHECK=${LOG_LINES_TO_CHECK:-100}
FATAL_PATTERNS=("fatal" "critical" "panic" "abort" "segfault")
ERROR_PATTERNS=("error" "exception" "failed" "failure" "timeout")
for log_file in *.log logs/*.log 2>/dev/null; do
if [ -f "$log_file" ]; then
recent_logs=$(tail -"$LOG_LINES_TO_CHECK" "$log_file" 2>/dev/null || echo "")
fatal_count=0
error_count=0
for pattern in "${FATAL_PATTERNS[@]}"; do
fatal_count=$((fatal_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
for pattern in "${ERROR_PATTERNS[@]}"; do
error_count=$((error_count + $(echo "$recent_logs" | grep -icE "\\b$pattern\\b" || echo "0")))
done
file_total_errors=$((fatal_count + error_count))
if [ "$fatal_count" -gt 0 ]; then
echo "CRITICAL: $log_file has $fatal_count fatal errors" >&2
fi
if [ "$file_total_errors" -gt "$ERROR_THRESHOLD_PER_FILE" ]; then
echo "ERROR SPIKE: $log_file has $file_total_errors errors (fatal: $fatal_count, error: $error_count)" >&2
fi
fi
done
exit 0
Framework-Specific Log Monitoring
Enhanced hook script for framework-specific log monitoring including Next.js, Node.js, and Python logs
#!/usr/bin/env bash
LOG_DIRS=("logs" "log" "var/log" ".logs" "tmp/logs")
if [ -f "package.json" ]; then
if [ -d ".next" ]; then
find .next -name "*.log" -type f 2>/dev/null | while read -r file; do
ERROR_COUNT=$(tail -100 "$file" 2>/dev/null | grep -icE '(fatal|critical|error|exception)' || echo "0")
if [ "$ERROR_COUNT" -gt 0 ]; then
echo "Next.js log $file has $ERROR_COUNT errors" >&2
fi
done
fi
fi
exit 0
Troubleshooting
Hook runs continuously causing terminal spam
Add sleep interval or debounce logic to notification hook: sleep 60 between checks. Reduce LOG_LINES_TO_CHECK to 50 for faster processing with less output. Use notification hook throttling to limit execution frequency. Consider using file modification time checks to skip unchanged log files.
Docker container log checks fail with permission denied
Ensure user is in docker group: sudo usermod -aG docker $USER and restart session. Alternatively, skip Docker checks: remove docker logs section from script. Verify Docker Engine 24.0+ is installed and daemon is running: docker info. Check Docker daemon socket permissions.
Log file pattern matching misses framework-specific logs
Add custom log paths to LOGDIRS array: LOG_DIRS+=('build/logs' '.next/logs'). Extend file patterns: find with -name '.out' -o -name 'app_.log' for comprehensive coverage. Check framework-specific log locations (Next.js .next/, Django logs/, Flask app.log). Use recursive find with appropriate depth limits.
Error rate threshold alerts for normal warning messages
Separate ERROR_PATTERNS from WARNING_PATTERNS in severity classification. Only count fatal+error toward threshold, exclude warnings: TOTAL_ERRORS=$((fatal_count + error_count)). Use severity-based thresholds: FATAL_THRESHOLD and ERROR_THRESHOLD separately. Configure warning-only monitoring separately from error monitoring.
Hook performance degrades with many large log files
Limit file search depth: find . -maxdepth 2 instead of recursive. Increase LOG_LINES_TO_CHECK interval but reduce file count: head -5 on find results for performance. Use file size checks to skip very large log files. Consider log rotation or archiving old log files. Set timeout limits for log file processing.
Error samples show truncated or incomplete error messages
Increase MAX_SAMPLE_ERRORS to show more error samples. Adjust line truncation limit (default 120 characters) for longer error messages. Use tail with larger line count: tail -200 for more context. Consider showing error context lines: grep -A 2 -B 2 for error context.
Docker container log monitoring misses errors in stopped containers
Check both running and stopped containers: docker ps -a --format '{{.Names}}'. Use docker logs with container ID for stopped containers. Consider monitoring container exit codes: docker ps -a --format '{{.Names}} {{.Status}}'. Add stopped container log checking with appropriate time windows.
Time-based error rate calculations don't account for log rotation
Use log file modification time to detect log rotation: stat -c %Y logfile. Check for multiple log files with rotation patterns: _.log, _.log.1, *.log.2. Use log file timestamps instead of line counts for time-based calculations. Consider using log rotation detection: check for log file size changes or new log files.
- Features
- Use Cases
- Installation
- Config paths
- Requirements
- Hook Configuration
- Hook Script
- Examples
- Error Rate Monitor Hook Script
- Docker Container Error Monitoring
- Error Severity Classification
- Framework-Specific Log Monitoring
- Troubleshooting
- Hook runs continuously causing terminal spam
- Docker container log checks fail with permission denied
- Log file pattern matching misses framework-specific logs
Source citations
Signals
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.