Skip to main content

MongoDB Log Rotation

Note

Please handle MongoDB log rotation first. If mongodb.log is left unrotated for a long time and grows too large, VictoriaLogs collection and query pressure may increase significantly, and memory or CPU usage may even spike.

Log Rotation​

  1. Create the logrotate configuration directory and archive directory

    mkdir -p /usr/local/logrotate-config
    mkdir -p /data/logs/mongodb/oldlogs
  2. Write the logrotate configuration file

    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
    PID=$(pgrep -x mongod)
    [ -n "$PID" ] && /bin/kill -USR1 "$PID" || true
    endscript
    }
    EOF
  3. Run a dry-run check first

    logrotate -d -f /usr/local/logrotate-config/mongodb
  4. Add a scheduled task

    (crontab -l ; echo "# Use logrotate to rotate MongoDB logs
    0 0 * * * /usr/sbin/logrotate -f /usr/local/logrotate-config/mongodb >/dev/null 2>&1") | crontab -
    crontab -l

Handling 0-Byte Log Files​

If 0-byte log files appear after rotation, it is usually related to settings such as ifempty and delaycompress. You can use the script below to move 0-byte log files into a separate directory.

  1. Create the script directory

    mkdir /usr/local/mongodb/script/
    cd /usr/local/mongodb/script/
  2. Write the cleanup script

    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 "Start moving 0-byte log files to $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 "Found 0-byte file: $filename, moving it to $DEST_DIR"
    mv "$file" "$DEST_DIR/$filename"
    log_info "File moved to $DEST_DIR/$filename"
    done
    log_info "Finished moving 0-byte log files."
    }

    cleanup_empty_logs() {
    local max_days=${1:-$MAX_DAYS}
    log_info "Start cleaning 0-byte log files, retention days: $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 "Deleted file: $file"
    done
    log_info "Cleanup finished."
    }

    move_empty_logs
    cleanup_empty_logs "$1"
    EOF
  3. Set permissions and add a scheduled task

    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