Shell脚本如何配置容器日志解析

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器日志解析

  1. 基础日志收集脚本
  2. Docker日志配置脚本
  3. 高级日志解析器
  4. 日志分析报告生成器
  5. 主执行脚本
  6. 使用示例
  7. 日志解析最佳实践

我来详细说明如何配置容器日志解析的Shell脚本:

基础日志收集脚本

#!/bin/bash
# 日志配置
LOG_DIR="/var/log/containers"
OUTPUT_DIR="/var/log/parsed"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# 创建输出目录
mkdir -p $OUTPUT_DIR
# SQL数据库日志解析函数
parse_mysql_logs() {
    local container_name=$1
    local log_file="${LOG_DIR}/${container_name}.log"
    if [ -f "$log_file" ]; then
        echo "Parsing MySQL logs for $container_name..."
        # 提取错误日志
        grep -i "error" $log_file > "${OUTPUT_DIR}/mysql_errors_${TIMESTAMP}.log"
        # 提取慢查询
        grep -i "slow query" $log_file > "${OUTPUT_DIR}/mysql_slow_${TIMESTAMP}.log"
        # 统计日志级别
        echo "Log Level Statistics:" > "${OUTPUT_DIR}/mysql_stats_${TIMESTAMP}.txt"
        grep -c "ERROR" $log_file >> "${OUTPUT_DIR}/mysql_stats_${TIMESTAMP}.txt"
        grep -c "WARNING" $log_file >> "${OUTPUT_DIR}/mysql_stats_${TIMESTAMP}.txt"
    fi
}
# Nginx日志解析函数
parse_nginx_logs() {
    local container_name=$1
    local log_file="${LOG_DIR}/${container_name}.log"
    if [ -f "$log_file" ]; then
        echo "Parsing Nginx logs for $container_name..."
        # 解析访问日志
        awk '{print $1, $7, $9}' $log_file > "${OUTPUT_DIR}/nginx_access_${TIMESTAMP}.log"
        # 统计HTTP状态码
        echo "HTTP Status Code Distribution:" > "${OUTPUT_DIR}/nginx_status_${TIMESTAMP}.txt"
        awk '{print $9}' $log_file | sort | uniq -c | sort -rn >> "${OUTPUT_DIR}/nginx_status_${TIMESTAMP}.txt"
        # 统计请求最多的IP
        echo "Top 10 IPs:" >> "${OUTPUT_DIR}/nginx_status_${TIMESTAMP}.txt"
        awk '{print $1}' $log_file | sort | uniq -c | sort -rn | head -10 >> "${OUTPUT_DIR}/nginx_status_${TIMESTAMP}.txt"
    fi
}
# 通用日志解析函数
parse_generic_logs() {
    local container_name=$1
    local log_file="${LOG_DIR}/${container_name}.log"
    local log_format=$2
    if [ -f "$log_file" ]; then
        case $log_format in
            "json")
                parse_json_logs $log_file $container_name
                ;;
            "text")
                parse_text_logs $log_file $container_name
                ;;
            "xml")
                parse_xml_logs $log_file $container_name
                ;;
            *)
                echo "Unknown log format: $log_format"
                return 1
                ;;
        esac
    fi
}

Docker日志配置脚本

#!/bin/bash
# Docker日志驱动配置
configure_docker_logging() {
    echo "Configuring Docker logging..."
    # 创建Docker守护进程配置
    cat > /etc/docker/daemon.json <<EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "labels": "product,environment",
    "env": "OS,LOG_LEVEL"
  }
}
EOF
    # 重启Docker服务
    systemctl restart docker
}
# 配置容器日志轮转
setup_log_rotation() {
    cat > /etc/logrotate.d/docker-containers <<EOF
/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    missingok
    delaycompress
    copytruncate
    postrotate
        docker logs --tail 0 my_container > /dev/null 2>&1 || true
    endscript
}
EOF
    # 手动执行轮转测试
    logrotate -f /etc/logrotate.d/docker-containers
}

高级日志解析器

#!/bin/bash
# 高级日志解析脚本
LOG_BUFFER_SIZE=1000
# 使用正则表达式解析日志行
parse_log_line() {
    local line=$1
    local patterns=(
        "^\[ERROR\]"
        "^\[WARN\]"
        "^\[INFO\]"
        "^\[DEBUG\]"
        "^(\d{4}-\d{2}-\d{2})"
        "^(\d{2}\/\w{3}\/\d{4})"
    )
    for pattern in "${patterns[@]}"; do
        if [[ $line =~ $pattern ]]; then
            echo "MATCH: $pattern"
            return 0
        fi
    done
    return 1
}
# JSON格式日志解析
parse_json_logs() {
    local log_file=$1
    local container_name=$2
    echo "Parsing JSON logs for $container_name..."
    # 使用jq解析JSON格式日志
    if command -v jq &> /dev/null; then
        cat $log_file | jq -r '
            select(.level == "error") | 
            {timestamp: .timestamp, message: .message, level: .level}
        ' > "${OUTPUT_DIR}/${container_name}_errors_${TIMESTAMP}.json"
        # 统计日志级别
        cat $log_file | jq -r '.level' | sort | uniq -c | sort -rn > "${OUTPUT_DIR}/${container_name}_levels_${TIMESTAMP}.txt"
    else
        echo "jq not installed. Installing..."
        apt-get install -y jq 2>/dev/null || yum install -y jq 2>/dev/null
    fi
}
# 文本格式日志解析
parse_text_logs() {
    local log_file=$1
    local container_name=$2
    echo "Parsing text logs for $container_name..."
    # 按时间戳分组
    awk '
    /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ {
        if (date != "") {
            print date ":" count
        }
        date = substr($0, 1, 10)
        count = 1
    }
    !/^[0-9]{4}-[0-9]{2}-[0-9]{2}/ {
        count++
    }
    END {
        print date ":" count
    }
    ' $log_file > "${OUTPUT_DIR}/${container_name}_timeline_${TIMESTAMP}.txt"
}
# 实时日志监控
monitor_logs() {
    local container_name=$1
    local keywords=$2
    echo "Monitoring logs for $container_name..."
    echo "Keywords: $keywords"
    docker logs -f $container_name | while read line; do
        if echo "$line" | grep -qi "$keywords"; then
            echo "[ALERT] $line"
            # 发送告警
            send_alert "$line"
        fi
    done
}

日志分析报告生成器

#!/bin/bash
# 生成日志分析报告
generate_report() {
    local container_name=$1
    local report_file="${OUTPUT_DIR}/${container_name}_report_${TIMESTAMP}.html"
    cat > $report_file <<HTMLHEADER
<!DOCTYPE html>
<html>
<head>Container Log Analysis Report - ${container_name}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #4CAF50; color: white; }
        .error { color: red; }
        .warning { color: orange; }
        .info { color: blue; }
    </style>
</head>
<body>
    <h1>Container Log Analysis Report</h1>
    <h2>Container: ${container_name}</h2>
    <p>Report generated: $(date)</p>
HTMLHEADER
    # 添加错误统计
    echo "<h2>Error Statistics</h2>" >> $report_file
    echo "<table><tr><th>Error Type</th><th>Count</th></tr>" >> $report_file
    if [ -f "${OUTPUT_DIR}/${container_name}_errors_${TIMESTAMP}.log" ]; then
        grep -E "error|Error|ERROR" "${OUTPUT_DIR}/${container_name}_errors_${TIMESTAMP}.log" | \
        awk '{print $1}' | sort | uniq -c | sort -rn | \
        while read count type; do
            echo "<tr><td>$type</td><td>$count</td></tr>" >> $report_file
        done
    fi
    echo "</table>" >> $report_file
    # 添加性能指标
    echo "<h2>Performance Metrics</h2>" >> $report_file
    echo "<table><tr><th>Metric</th><th>Value</th></tr>" >> $report_file
    # 添加日志大小
    local log_size=$(du -sh "${LOG_DIR}/${container_name}.log" 2>/dev/null | cut -f1)
    echo "<tr><td>Log File Size</td><td>${log_size:-N/A}</td></tr>" >> $report_file
    # 添加日志行数
    local log_lines=$(wc -l < "${LOG_DIR}/${container_name}.log" 2>/dev/null)
    echo "<tr><td>Total Log Lines</td><td>${log_lines:-0}</td></tr>" >> $report_file
    echo "</table>" >> $report_file
    # 添加建议
    echo "<h2>Recommendations</h2>" >> $report_file
    echo "<ul>" >> $report_file
    if [ -f "${OUTPUT_DIR}/${container_name}_errors_${TIMESTAMP}.log" ] && \
       [ $(wc -l < "${OUTPUT_DIR}/${container_name}_errors_${TIMESTAMP}.log") -gt 100 ]; then
        echo "<li class='error'>High error rate detected. Consider investigating.</li>" >> $report_file
    fi
    echo "</ul>" >> $report_file
    echo "</body></html>" >> $report_file
    echo "Report generated: $report_file"
}

主执行脚本

#!/bin/bash
# 主执行脚本
source ./log_parser_functions.sh
main() {
    echo "=========================================="
    echo "Container Log Parser Configuration"
    echo "=========================================="
    # 参数解析
    while [[ $# -gt 0 ]]; do
        case $1 in
            --container|-c)
                CONTAINER_NAME="$2"
                shift 2
                ;;
            --format|-f)
                LOG_FORMAT="$2"
                shift 2
                ;;
            --output|-o)
                OUTPUT_DIR="$2"
                shift 2
                ;;
            --monitor|-m)
                MONITOR_KEYWORD="$2"
                shift 2
                ;;
            --generate-report|-r)
                GENERATE_REPORT=true
                shift
                ;;
            --help|-h)
                echo "Usage: $0 [OPTIONS]"
                echo "Options:"
                echo "  --container, -c     Container name"
                echo "  --format, -f        Log format (json/text/xml)"
                echo "  --output, -o        Output directory"
                echo "  --monitor, -m       Monitor keyword"
                echo "  --generate-report, -r  Generate HTML report"
                exit 0
                ;;
            *)
                echo "Unknown option: $1"
                exit 1
                ;;
        esac
    done
    # 执行日志解析
    if [ -n "$CONTAINER_NAME" ]; then
        case $LOG_FORMAT in
            "json")
                parse_json_logs $CONTAINER_NAME
                ;;
            "text")
                parse_text_logs $CONTAINER_NAME
                ;;
            *)
                parse_generic_logs $CONTAINER_NAME $LOG_FORMAT
                ;;
        esac
        # 监控模式
        if [ -n "$MONITOR_KEYWORD" ]; then
            monitor_logs $CONTAINER_NAME $MONITOR_KEYWORD &
        fi
        # 生成报告
        if [ "$GENERATE_REPORT" = true ]; then
            generate_report $CONTAINER_NAME
        fi
    fi
}
# 执行主函数
main "$@"

使用示例

# 1. 配置Docker日志驱动
./configure_logging.sh
# 2. 解析单个容器日志
./log_parser.sh --container my-web-app --format json --output /var/log/parsed
# 3. 实时监控特定关键字
./log_parser.sh --container my-web-app --monitor "ERROR|CRITICAL"
# 4. 生成HTML报告
./log_parser.sh --container my-web-app --format json --generate-report
# 5. 批量处理所有运行容器
for container in $(docker ps --format "{{.Names}}"); do
    ./log_parser.sh --container "$container" --format json
done
# 6. 定时任务配置 (crontab)
# 每5分钟解析一次日志
*/5 * * * * /path/to/log_parser.sh --container my-app --format json --generate-report

日志解析最佳实践

# 日志压缩和归档
archive_old_logs() {
    find ${OUTPUT_DIR} -name "*.log" -mtime +7 -exec gzip {} \;
    find ${OUTPUT_DIR} -name "*.log.gz" -mtime +30 -exec rm {} \;
}
# 日志监控和告警
setup_alerting() {
    # Prometheus 和 Grafana 集成
    cat > /etc/prometheus/log_exporter.yml <<EOF
scrape_configs:
  - job_name: 'container_logs'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'
EOF
}
# 集中式日志管理
setup_centralized_logging() {
    # 配置rsyslog接收容器日志
    cat > /etc/rsyslog.d/container.conf <<EOF
module(load="imudp")
input(type="imudp" port="514")
template(name="ContainerLogs" type="string" string="%timestamp% %hostname% %app-name% %msg%\n")
:programname, startswith, "docker" /var/log/containers/container.log
EOF
    systemctl restart rsyslog
}

这个配置方案提供了完整的容器日志解析解决方案,包括基础日志收集、格式解析、实时监控、报告生成等功能,适用于生产环境中的容器日志管理需求。

抱歉,评论功能暂时关闭!