Supervisord Configuration: Understanding redirect_stderr and stderr_logfile Behavior


2 views

When configuring a program in Supervisord, there's often confusion about the interaction between stderr_logfile and redirect_stderr directives. Specifically, whether setting stderr_logfile is necessary when redirect_stderr=true is enabled.

Your understanding is correct. When redirect_stderr=true is set in the Supervisord configuration:

[program:myapp]
command=/path/to/your/program
stdout_logfile=/path/to/logfile/stdout.log
stderr_logfile=/path/to/logfile/stderr.log
redirect_stderr=true

This configuration will result in:

  • All stderr output being redirected to stdout
  • The stderr.log file remaining empty (or not being created at all)
  • Combined stdout/stderr output appearing in stdout.log

While technically you don't need to specify stderr_logfile when redirect_stderr=true, there are practical considerations:

[program:myapp]
; This is valid and will work
command=/path/to/your/program
stdout_logfile=/var/log/myapp.log
redirect_stderr=true

However, explicitly specifying both log files can be beneficial for:

  1. Configuration clarity (documenting expected behavior)
  2. Future maintenance (if someone later changes redirect_stderr)
  3. Consistency across different program configurations

Here's a more complete example showing proper log rotation and permission handling:

[program:myapp]
command=/usr/bin/python /opt/myapp/main.py
directory=/opt/myapp
user=appuser
stdout_logfile=/var/log/myapp/out.log
stderr_logfile=/var/log/myapp/err.log
redirect_stderr=true
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
stdout_capture_maxbytes=0
stderr_capture_maxbytes=0

In this case, while err.log will remain empty, having it defined makes the configuration more explicit about its logging strategy.

If you're not seeing expected behavior:

  • Check Supervisord's log for errors (/var/log/supervisor/supervisord.log)
  • Verify file permissions on the log directory
  • Restart Supervisord after configuration changes
  • Use supervisorctl tail myapp to verify output




When configuring process management with Supervisord, the relationship between redirect_stderr and log file settings often causes confusion. Let's examine this through concrete examples.

Given the configuration:

[program:myapp]
command=/usr/bin/python myapp.py
stdout_logfile=/var/log/myapp.stdout.log
stderr_logfile=/var/log/myapp.stderr.log
redirect_stderr=true

The key behavior to understand:

  • When redirect_stderr=true, STDERR output is merged with STDOUT
  • All output (both streams) goes to stdout_logfile
  • The stderr_logfile remains empty in this case

For most use cases, you actually want one of these patterns:

# Option 1: Separate logs (default behavior)
[program:myapp]
command=/usr/bin/python myapp.py
stdout_logfile=/var/log/myapp.out.log
stderr_logfile=/var/log/myapp.err.log
redirect_stderr=false  # explicitly declared for clarity
# Option 2: Merged logs (recommended for simpler monitoring)
[program:myapp]
command=/usr/bin/python myapp.py
stdout_logfile=/var/log/myapp.combined.log
redirect_stderr=true
# stderr_logfile intentionally omitted

While the difference is minimal for most applications, there's a slight overhead when maintaining separate log files:

  • Two file descriptors instead of one
  • Additional I/O operations
  • Double the inotify watches if using log monitoring

For applications where you want to separate critical errors but merge routine output:

[program:critical_app]
command=/usr/bin/python critical.py
stdout_logfile=/var/log/critical.out.log
stderr_logfile=/var/log/critical-errors.log
redirect_stderr=false
# Application code handles output routing:
#   sys.stdout for normal output
#   sys.stderr only for critical failures