Debugging Logrotate Failure: Why Logs Aren’t Rotating Despite Correct Configuration


10 views

Looking at your debug output, the key error appears repeatedly:

error: error switching euid to 0 and egid to 104: Operation not permitted

This indicates logrotate doesn't have sufficient permissions to perform the rotation. Even though your configuration appears correct at first glance, permission issues often prevent execution.

The specific error occurs when logrotate tries to switch to root privileges (euid 0) and group ID 104. The most common scenarios causing this:

  • The logrotate process isn't running as root (though sudo helped partially)
  • Directory permissions prevent access to log files
  • SELinux/AppArmor restrictions (common on RHEL/Debian systems)

Here's how to properly fix the rotation for your Rails application logs:

# First verify directory permissions
sudo ls -la /home/deployer/abc/shared/log/

# Recommended permission structure:
sudo chown -R deployer:deployer /home/deployer/abc/shared/log
sudo chmod -R 755 /home/deployer/abc/shared/log

# Then test logrotate with force option
sudo logrotate -vf /etc/logrotate.d/your_config_file

For production environments, consider this enhanced configuration:

/home/deployer/abc/shared/log/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    size 5M
    copytruncate
    create 0644 deployer deployer
    su deployer deployer
    sharedscripts
    postrotate
        [ -f /home/deployer/abc/shared/tmp/pids/unicorn.pid ] && kill -USR1 cat /home/deployer/abc/shared/tmp/pids/unicorn.pid
    endscript
}

After implementation, verify rotation works:

# Check logrotate status
sudo cat /var/lib/logrotate/status | grep abc

# Force a test rotation
sudo logrotate -vf /etc/logrotate.d/abc

# Monitor log directory
ls -larth /home/deployer/abc/shared/log/

The key error message appearing in your debug output reveals the core problem:

error: error switching euid to 0 and egid to 104: Operation not permitted

This indicates a fundamental permission issue where logrotate cannot properly switch user contexts during execution. Even when running with sudo, the euid/egid switching fails for certain operations.

Your configuration appears correct at first glance:

/home/deployer/abc/shared/log/*.log {
  daily
  missingok
  rotate 30
  compress
  delaycompress
  size 5M
  copytruncate
}

However, the debug output shows logrotate attempts to switch to egid 104 (typically the 'syslog' group) when processing these logs, which fails because:

  • The deployer user may not have proper permissions
  • The log files may have restrictive ownership
  • SELinux contexts might be interfering

Here are proven solutions to make your log rotation work:

1. Proper Permission Setup

First, verify and correct file permissions:

sudo chown -R deployer:syslog /home/deployer/abc/shared/log
sudo chmod -R 664 /home/deployer/abc/shared/log/*.log

2. Alternative Configuration Approach

Create a dedicated configuration file with proper su directive:

# /etc/logrotate.d/abc_custom
/home/deployer/abc/shared/log/*.log {
  daily
  missingok
  rotate 30
  compress
  delaycompress
  size 5M
  copytruncate
  su deployer deployer
}

3. Manual Rotation Test

Force a rotation with verbose output to verify:

sudo logrotate -vf /etc/logrotate.d/abc_custom

When troubleshooting logrotate issues:

# Check current status of rotations
cat /var/lib/logrotate/status

# Test configuration syntax
sudo logrotate -d /etc/logrotate.conf

# Force immediate rotation with debug
sudo logrotate -vf /etc/logrotate.d/your_config
  • Missing su directive when rotating user-owned logs
  • Incorrect file permissions on log directory
  • Conflicting size and time-based rotation triggers
  • Improper use of copytruncate with applications that maintain file handles

For production environments with sensitive logs:

/var/log/application/*.log {
  daily
  rotate 30
  compress
  delaycompress
  size 100M
  missingok
  notifempty
  create 0640 appuser syslog
  sharedscripts
  postrotate
    /bin/kill -HUP cat /var/run/application.pid 2>/dev/null 2>/dev/null || true
  endscript
}