Should a foreground program invoked by a daemon split logging between stderr and stdout based on severity levels?

Solution 1:

I would not suggest co-mingling stdout and stderr inside your program, but how you handle it outside is up to you. stdout was intended for processed data meant for a pipeline, while stderr is specifically for non-data messages. This makes certain behaviors possible, such as batch processing, without altering the existing interactive behavior. Your case is different - there is a good chance stdout means little to nothing.

Because runit has a slightly different take on logging via svlog, and the service you are writing most likely will not daemonize (which in this case means "detach from a tty") then it will be up to you if you want to capture everything to a single log, or not, via the /etc/sv/<servicename>/run script. For the most part, most run scripts use

exec 2>&1 

to fuse the two streams together, as most services don't pass along data via stdout. If you do want to use svlog you will need to create a script at /etc/sv/<servicename>/log/run with the appropriate command to start it. It probably looks similar (but not exactly like) this:

#!/bin/sh
exec 2>&1
exec svlog -tt main

where main is a symlink to a logging directory.

Solution 2:

First, something important to clarify: STDOUT and STDERR are rarely relevant within the context of a daemon process once it has successfully started, unless you're invoking one with a debugging switch.

The whole point of a daemon is that it needs to disassociate itself from having a controlling terminal, so that it can persist after logout. Once there is no terminal, all messages need to be sent to either a syslog daemon or a log file managed directly by the process.

If you are not actually referring to daemons, and really just mean any shell script or similar that you're writing yourself, then the logic should generally be this:

  • STDOUT: Anything you want being trapped by pipes or basic output redirection.
  • STDERR: "Out of band" messages. Things you want hitting someone's terminal anyway, even if they're doing some kind of redirection. (hence why they're associated with errors) Let the user decide if they also want to redirect these messages as well, i.e. redirecting STDERR to STDIN as you mentioned.

Solution 3:

I don't think you should use both stdout and stderr for logging. If you have log messages with different severities, they should be tagged with a prefix to make it easy to filter/sort them using svlogd.

I'd say using both stdout and stderr for logging would violate the principle of least surprise.