跳到主要内容

MongoDB 日志切割

注意

先做 MongoDB 日志切割。mongodb.log 长期不切割、文件过大时,可能导致 VictoriaLogs 采集和查询压力增大,甚至出现内存、CPU 飙高的问题。

日志切割

  1. 创建 logrotate 配置目录和归档目录

    mkdir -p /usr/local/logrotate-config
    mkdir -p /data/logs/mongodb/oldlogs
  2. 写入 logrotate 配置文件

    cat > /usr/local/logrotate-config/mongodb <<EOF
    /data/logs/mongodb/mongodb.log {
    create 0644 mongodb mongodb
    daily
    dateext
    dateformat -%Y-%m-%d
    dateyesterday
    rotate 180
    missingok
    ifempty
    compress
    delaycompress
    olddir /data/logs/mongodb/oldlogs
    sharedscripts
    postrotate
    /bin/kill -USR1 \`pgrep mongod 2>/dev/null\` 2>/dev/null || true
    endscript
    }
    EOF
  3. 先做 dry-run 检查

    logrotate -d -f /usr/local/logrotate-config/mongodb
  4. 加入定时任务

    (crontab -l ; echo "# Use Logrotate Cut mongodb Logs
    0 0 * * * /usr/sbin/logrotate -f /usr/local/logrotate-config/mongodb >/dev/null 2>&1") | crontab -
    crontab -l

处理 0 字节日志文件

日志切割后如果出现大小为 0 的日志文件,通常与 ifemptydelaycompress 等配置有关。可以使用下面脚本把 0 字节日志文件移动到单独目录。

  1. 创建脚本目录

    mkdir /usr/local/mongodb/script/
    cd /usr/local/mongodb/script/
  2. 写入清理脚本

    cat > move_empty_logs.sh << 'EOF'
    #!/bin/bash
    SOURCE_DIR="/data/logs/mongodb/"
    DEST_DIR="/data/logs/mongodb/old-log-0"
    MAX_DAYS=180

    log_info() {
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO: $1"
    }

    log_error() {
    echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR: $1"
    }

    move_empty_logs() {
    [[ ! -d "$DEST_DIR" ]] && mkdir -p "$DEST_DIR"
    log_info "开始移动大小为 0 的日志文件到 $DEST_DIR"
    find "$SOURCE_DIR" -type f -name "mongodb.log.*" -size 0 -print0 | while IFS= read -r -d '' file; do
    local filename=$(basename "$file")
    log_info "找到大小为 0 的文件: $filename,准备移动到 $DEST_DIR"
    mv "$file" "$DEST_DIR/$filename"
    log_info "文件已移动到 $DEST_DIR/$filename"
    done
    log_info "移动大小为 0 的日志文件完成。"
    }

    cleanup_empty_logs() {
    local max_days=${1:-$MAX_DAYS}
    log_info "开始清理大小为 0 的日志文件,保留天数:$max_days"
    find "$DEST_DIR" -type f -name "mongodb.log.*" -size 0 -mtime +$max_days -print -delete | while IFS= read -r file; do
    log_info "删除文件:$file"
    done
    log_info "清理完成。"
    }

    move_empty_logs
    cleanup_empty_logs "$1"
    EOF
  3. 设置权限并加入定时任务

    chown mongodb:mongodb -R /usr/local/mongodb/script/
    chmod +x /usr/local/mongodb/script/move_empty_logs.sh
    (crontab -l; echo "15 0 * * * /usr/local/mongodb/script/move_empty_logs.sh >/dev/null 2>&1") | crontab -
    crontab -l