QAUP_Management/deploy/docker/log-manager.sh

428 lines
12 KiB
Bash
Executable File

#!/bin/bash
# QAUP 日志管理脚本
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
LOG_DIR="$PROJECT_ROOT/logs"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_message() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# 配置日志轮转
setup_log_rotation() {
print_message $BLUE "配置日志轮转..."
local logrotate_config="/etc/logrotate.d/qaup"
# 创建 logrotate 配置
sudo tee "$logrotate_config" > /dev/null << EOF
# QAUP 日志轮转配置
$LOG_DIR/app/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
docker exec qaup-app pkill -USR1 java || true
endscript
}
$LOG_DIR/nginx/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
docker exec qaup-nginx nginx -s reopen || true
endscript
}
$LOG_DIR/postgres/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 root root
}
$LOG_DIR/redis/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 root root
}
EOF
print_message $GREEN "日志轮转配置已创建: $logrotate_config"
# 测试配置
if sudo logrotate -d "$logrotate_config" &>/dev/null; then
print_message $GREEN "✓ 日志轮转配置测试通过"
else
print_message $RED "✗ 日志轮转配置测试失败"
fi
}
# 查看日志
view_logs() {
local service=$1
local lines=${2:-100}
case $service in
app|qaup-app)
print_message $BLUE "查看应用日志 (最近 $lines 行):"
docker logs --tail $lines -f qaup-app
;;
nginx|qaup-nginx)
print_message $BLUE "查看 Nginx 日志 (最近 $lines 行):"
docker logs --tail $lines -f qaup-nginx
;;
postgres|qaup-postgres)
print_message $BLUE "查看 PostgreSQL 日志 (最近 $lines 行):"
docker logs --tail $lines -f qaup-postgres
;;
redis|qaup-redis)
print_message $BLUE "查看 Redis 日志 (最近 $lines 行):"
docker logs --tail $lines -f qaup-redis
;;
all)
print_message $BLUE "查看所有服务日志 (最近 $lines 行):"
docker-compose logs --tail $lines -f
;;
*)
print_message $RED "未知服务: $service"
print_message $YELLOW "可用服务: app, nginx, postgres, redis, all"
exit 1
;;
esac
}
# 分析错误日志
analyze_error_logs() {
print_message $BLUE "分析错误日志..."
local error_report="$LOG_DIR/error_analysis_$(date +%Y%m%d_%H%M%S).txt"
{
echo "QAUP 错误日志分析报告"
echo "生成时间: $(date)"
echo "========================================"
echo ""
# 分析应用错误
echo "应用错误 (最近24小时):"
echo "------------------------"
docker logs qaup-app --since 24h 2>&1 | grep -i "error\|exception\|failed" | tail -20
echo ""
# 分析 Nginx 错误
echo "Nginx 错误 (最近24小时):"
echo "------------------------"
docker logs qaup-nginx --since 24h 2>&1 | grep -i "error\|failed" | tail -20
echo ""
# 分析数据库错误
echo "PostgreSQL 错误 (最近24小时):"
echo "-----------------------------"
docker logs qaup-postgres --since 24h 2>&1 | grep -i "error\|fatal\|panic" | tail -20
echo ""
# 分析 Redis 错误
echo "Redis 错误 (最近24小时):"
echo "------------------------"
docker logs qaup-redis --since 24h 2>&1 | grep -i "error\|warning" | tail -20
echo ""
} > "$error_report"
print_message $GREEN "错误日志分析报告已生成: $error_report"
# 显示摘要
local error_count=$(grep -c "error\|ERROR\|Error" "$error_report" || echo "0")
if [ $error_count -gt 0 ]; then
print_message $YELLOW "发现 $error_count 个错误条目"
else
print_message $GREEN "未发现明显错误"
fi
}
# 清理旧日志
cleanup_old_logs() {
local days=${1:-30}
print_message $BLUE "清理 $days 天前的日志文件..."
local cleaned_files=0
# 清理应用日志
if [ -d "$LOG_DIR/app" ]; then
local app_files=$(find "$LOG_DIR/app" -name "*.log*" -mtime +$days -type f | wc -l)
find "$LOG_DIR/app" -name "*.log*" -mtime +$days -type f -delete
cleaned_files=$((cleaned_files + app_files))
fi
# 清理 Nginx 日志
if [ -d "$LOG_DIR/nginx" ]; then
local nginx_files=$(find "$LOG_DIR/nginx" -name "*.log*" -mtime +$days -type f | wc -l)
find "$LOG_DIR/nginx" -name "*.log*" -mtime +$days -type f -delete
cleaned_files=$((cleaned_files + nginx_files))
fi
# 清理数据库日志
if [ -d "$LOG_DIR/postgres" ]; then
local postgres_files=$(find "$LOG_DIR/postgres" -name "*.log*" -mtime +$days -type f | wc -l)
find "$LOG_DIR/postgres" -name "*.log*" -mtime +$days -type f -delete
cleaned_files=$((cleaned_files + postgres_files))
fi
# 清理 Redis 日志
if [ -d "$LOG_DIR/redis" ]; then
local redis_files=$(find "$LOG_DIR/redis" -name "*.log*" -mtime +$days -type f | wc -l)
find "$LOG_DIR/redis" -name "*.log*" -mtime +$days -type f -delete
cleaned_files=$((cleaned_files + redis_files))
fi
print_message $GREEN "已清理 $cleaned_files 个旧日志文件"
}
# 压缩日志文件
compress_logs() {
print_message $BLUE "压缩日志文件..."
local compressed_count=0
# 压缩7天前的日志文件
for log_dir in "$LOG_DIR"/{app,nginx,postgres,redis}; do
if [ -d "$log_dir" ]; then
while IFS= read -r -d '' file; do
if [[ "$file" != *.gz ]]; then
gzip "$file"
compressed_count=$((compressed_count + 1))
fi
done < <(find "$log_dir" -name "*.log" -mtime +7 -type f -print0)
fi
done
print_message $GREEN "已压缩 $compressed_count 个日志文件"
}
# 导出日志
export_logs() {
local service=$1
local start_date=$2
local end_date=$3
local output_file="logs_export_$(date +%Y%m%d_%H%M%S).tar.gz"
print_message $BLUE "导出日志..."
local temp_dir="/tmp/qaup_logs_export"
mkdir -p "$temp_dir"
case $service in
app|qaup-app)
docker logs qaup-app --since "$start_date" --until "$end_date" > "$temp_dir/app.log"
;;
nginx|qaup-nginx)
docker logs qaup-nginx --since "$start_date" --until "$end_date" > "$temp_dir/nginx.log"
;;
postgres|qaup-postgres)
docker logs qaup-postgres --since "$start_date" --until "$end_date" > "$temp_dir/postgres.log"
;;
redis|qaup-redis)
docker logs qaup-redis --since "$start_date" --until "$end_date" > "$temp_dir/redis.log"
;;
all)
docker logs qaup-app --since "$start_date" --until "$end_date" > "$temp_dir/app.log"
docker logs qaup-nginx --since "$start_date" --until "$end_date" > "$temp_dir/nginx.log"
docker logs qaup-postgres --since "$start_date" --until "$end_date" > "$temp_dir/postgres.log"
docker logs qaup-redis --since "$start_date" --until "$end_date" > "$temp_dir/redis.log"
;;
*)
print_message $RED "未知服务: $service"
rm -rf "$temp_dir"
exit 1
;;
esac
# 创建压缩包
tar -czf "$output_file" -C "$temp_dir" .
rm -rf "$temp_dir"
print_message $GREEN "日志已导出到: $output_file"
}
# 实时监控日志
monitor_logs() {
local service=${1:-all}
local filter=${2:-""}
print_message $BLUE "实时监控日志 (服务: $service)"
if [ -n "$filter" ]; then
print_message $BLUE "过滤条件: $filter"
fi
print_message $YELLOW "按 Ctrl+C 停止监控"
case $service in
app|qaup-app)
if [ -n "$filter" ]; then
docker logs -f qaup-app | grep --line-buffered "$filter"
else
docker logs -f qaup-app
fi
;;
nginx|qaup-nginx)
if [ -n "$filter" ]; then
docker logs -f qaup-nginx | grep --line-buffered "$filter"
else
docker logs -f qaup-nginx
fi
;;
postgres|qaup-postgres)
if [ -n "$filter" ]; then
docker logs -f qaup-postgres | grep --line-buffered "$filter"
else
docker logs -f qaup-postgres
fi
;;
redis|qaup-redis)
if [ -n "$filter" ]; then
docker logs -f qaup-redis | grep --line-buffered "$filter"
else
docker logs -f qaup-redis
fi
;;
all)
if [ -n "$filter" ]; then
docker-compose logs -f | grep --line-buffered "$filter"
else
docker-compose logs -f
fi
;;
*)
print_message $RED "未知服务: $service"
exit 1
;;
esac
}
# 显示日志统计
show_log_stats() {
print_message $BLUE "日志统计信息:"
echo ""
print_message $BLUE "日志目录大小:"
if [ -d "$LOG_DIR" ]; then
du -sh "$LOG_DIR"/* 2>/dev/null | sort -hr
else
print_message $YELLOW "日志目录不存在: $LOG_DIR"
fi
echo ""
print_message $BLUE "容器日志大小:"
docker system df --format "table {{.Type}}\t{{.TotalCount}}\t{{.Size}}\t{{.Reclaimable}}"
echo ""
print_message $BLUE "最近24小时日志条目数:"
local containers=("qaup-app" "qaup-nginx" "qaup-postgres" "qaup-redis")
for container in "${containers[@]}"; do
local count=$(docker logs "$container" --since 24h 2>/dev/null | wc -l)
print_message $GREEN "$container: $count"
done
}
# 显示帮助信息
show_help() {
echo "QAUP 日志管理脚本"
echo ""
echo "用法: $0 [命令] [选项]"
echo ""
echo "命令:"
echo " setup 配置日志轮转"
echo " view <service> 查看服务日志"
echo " monitor <service> 实时监控日志"
echo " analyze 分析错误日志"
echo " cleanup [days] 清理旧日志 (默认30天)"
echo " compress 压缩日志文件"
echo " export <service> 导出日志"
echo " stats 显示日志统计"
echo ""
echo "服务名称: app, nginx, postgres, redis, all"
echo ""
echo "示例:"
echo " $0 view app # 查看应用日志"
echo " $0 monitor all # 监控所有服务日志"
echo " $0 cleanup 7 # 清理7天前的日志"
echo " $0 export all 2024-01-01 # 导出指定日期的日志"
}
# 主函数
main() {
if [ $# -eq 0 ]; then
show_help
exit 0
fi
local command=$1
shift
case $command in
setup)
setup_log_rotation
;;
view)
view_logs "$@"
;;
monitor)
monitor_logs "$@"
;;
analyze)
analyze_error_logs
;;
cleanup)
cleanup_old_logs "$@"
;;
compress)
compress_logs
;;
export)
export_logs "$@"
;;
stats)
show_log_stats
;;
help|--help|-h)
show_help
;;
*)
print_message $RED "未知命令: $command"
show_help
exit 1
;;
esac
}
main "$@"