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
    /bin/kill -USR1 \`pgrep mongod 2>/dev/null\` 2>/dev/null || 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