3

There are several questions about this already but none of them seem to work. I have a production system that is currently down and I need to be able to get the stderr output from the daemon quickly to debug it.

I thought I could just redirect the output from the point it is called (in an init.d script) but it is proving extremely difficult.

 start-stop-daemon -d $DDIR -b -m --start --quiet -pidfile $PIDFILE --exec $DAEMON -- \
                $DAEMON_ARGS > /var/log/daemon.log 2>&1 \
                || return 2

This does not work. I tried running a shell script that calls the executable and redirects the output but still the log file remained empty (and I do know that the process is outputting information).

Any help would be extremely appreciated.

David Nehme
  • 20,665
  • 7
  • 73
  • 114
Pryo
  • 650
  • 1
  • 9
  • 24
  • Can't you improve the source code of your daemon to use `syslog(3)` facilities? AFAIK `start-stop-daemon` is like `daemon(3)` with `noclose=0` so closes `stdout` & `stderr` (redirecting them to `/dev/null`) – Basile Starynkevitch Oct 08 '12 at 19:08
  • [This](https://stackoverflow.com/questions/8251933/how-can-i-log-the-stdout-of-a-process-started-by-start-stop-daemon/33606496#33606496) seems to work... – Onlyjob Nov 09 '15 at 12:10

4 Answers4

3

If you have start-stop-daemon >= version 1.16.5 you simply call it with --no-close to be able to redirect the output of the started process.

From man start-stop-daemon:

-C, --no-close

          Do not close any file descriptor when forcing the daemon into
          the background (since version 1.16.5).  Used for debugging
          purposes to see the process output, or to redirect file
          descriptors to log the process output.  Only relevant when
          using --background.
Tim S.
  • 198
  • 1
  • 8
2

As far as i remember, this is impossible, usually when i need to get data from a daemon process i either log it before hand or create a monitor program that connects to the program via network sockets or named pipes or any other interprocess communication mechanism.

Rafael
  • 2,697
  • 1
  • 14
  • 17
1

Calling start-stop-daemon with > /var/log/daemon.log 2>&1 will redirect start-stop-daemon's output and not the started daemon's output. Start-stop-daemon will close standard output/input descriptors before running a daemon.

Wrapping an executable in a simple shell script like that:

#!/bin/bash
STDERR=$1
shift
DAEMON=$1
shift
$DAEMON 2>$STDERR $*

works for me - maybe you should check file permissions?

There is a problem with this naive solution - when start-stop-daemon kills this wrapper, the wrapped daemon will be left alive. That cannot be easily solved in bash, because you cannot run signal handlers during the script execution (see trap documentation for details). You have to write a C wrapper which looks like that:

#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv){
    int fd_err;

    fd_err = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC);
    dup2(fd_err, STDERR_FILENO);
    close(fd_err);

    return execvp(argv[2], argv + 2);
}

(I've omitted error checking for clarity).

Rafał Rawicki
  • 20,923
  • 3
  • 55
  • 76
0

Here is a solution that may work (based on the solution given here).

At the beginning of your init.d script (and after the header), add the following:

exec > >(tee --append /var/log/daemon.log)

#You may also choose to log to /var/log/messages using this:
#exec > >(logger -t MY_DAEMON_NAME)

#And redirect errors to the same file with this:
exec 2>&1

This will log all that is invoked during your script, including start-stop-daemon output.

Community
  • 1
  • 1
lauhub
  • 827
  • 13
  • 26