我如何logging由start-stop-daemon启动的进程的stdout?

我正在使用一个初始化脚本来运行一个简单的过程,它是从以下开始的:

start-stop-daemon --start --quiet --chuid $DAEMONUSER \ --make-pidfile --pidfile $PIDFILE --background \ --exec $DAEMON $DAEMON_ARGS 

名为$ DAEMON的进程通常会将日志信息打印到其标准输出中。 据我可以告诉这个数据没有被存储在任何地方。

我想编写或追加$ DAEMON的标准输出到某个地方的文件。

我知道的唯一解决scheme是告诉start-stop-daemon直接调用shellcript而不是$ DAEMON; 该脚本然后调用$ DAEMON并写入日志文件。 但是这需要一个额外的脚本,像修改守护进程本身似乎是解决这个共同任务的错误方法。

为了扩大ypocat的答案,因为它不会让我评论:

 start-stop-daemon --start --quiet --chuid $DAEMONUSER \ --make-pidfile --pidfile $PIDFILE --background \ --startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1" 

使用exec来运行守护进程允许停止正确地停止subprocess,而不是仅仅是bash父进程。

使用--startas而不是--exec可确保进程能够正确检测到它的PID,并且不会错误地启动守护程序的多个实例(如果启动被多次调用)。 否则,start-stop-daemon将查找/ bin / bash进程并忽略运行守护进程的实际subprocess。

你需要做的是:

 start-stop-daemon --start --quiet --chuid $DAEMONUSER \ --make-pidfile --pidfile $PIDFILE --background \ --exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1" 

另外,如果您使用--chuid--user ,请确保用户可以写入/var/log或现有的/var/log/some.log 。 最好的办法是让该用户拥有一个/var/log/subdir/虽然。

在启动start-stop-daemon来捕获守护进程输出时,似乎应该可以使用--no-close参数。 Debian上的版本1.16.5以后, dpkg软件包中提供了这个新function :

添加新的–no-close选项来禁用在–background上closuresfds。

这使得调用者能够看到用于debugging目的的进程消息,或者能够将文件描述符redirect到日志文件,系统日志或类似文件。

使用openrc(例如gentoo或alpine linux上的默认值) start-stop-daemon具有-1-2选项:

-1,–stdout将stdoutredirect到文件

-2,–stderr将stderrredirect到文件

所以你可以写:

 start-stop-daemon --start --quiet --chuid $DAEMONUSER \ --make-pidfile --pidfile $PIDFILE --background \ --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE 

捕获守护进程的输出并将其保存到文件并不难:

 start-stop-daemon --start --background \ --pidfile $PIDFILE --make-pidfile \ --chuid $DAEMON_USER \ --startas $DAEMON --no-close \ -- $DAEMON_ARGS >> $LOGFILE 2>&1 

但是这个解决scheme对于logrotate可能不是最理想的。

将输出捕获到syslog可能会更好。 在Debian上,这将匹配systemd服务的行为。 以下直接的尝试重写上面的例子是错误的,因为在停止守护进程之后,由于start-stop-daemon仅终止其子而不是所有的后代,所以留下了两个无父(“僵尸”)进程(logging器和守护进程):

 ## Do not use this! start-stop-daemon --start --background \ --pidfile $PIDFILE --make-pidfile \ --chuid $DAEMON_USER \ --startas /bin/sh \ -- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME""" 

为了使它工作,我们需要一个封装器,它在从start-stop-daemon接收到SIGTERM时终止它的子SIGTERM 。 有一些:

duende :

 start-stop-daemon --start --background \ --pidfile $PIDFILE \ --startas /usr/sbin/duende \ -- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \ /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS""" 

注意: uid=65534是一个用户nobody

优点 :它的工作原理相对简单。
缺点 :4个进程(主pipeduende ,其叉与放弃特权(logging器), su和守护进程本身); 强制--chroot ; 如果守护进程立即终止(例如无效命令) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"报告它已成功启动。

守护进程 :

 start-stop-daemon --start --pidfile $PIDFILE \ --startas /usr/bin/daemon \ -- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \ -- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS""" 

优点 :3个进程(supervisor daemonsu和守护进程本身)。
缺点 :由于混淆守护进程的命令行选项,难以pipe理$PIDFILE ; 如果守护进程立即终止(例如无效命令) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"报告它已成功启动。

pipexec ( 获胜者 ):

 start-stop-daemon --start --background \ --pidfile $PIDFILE --make-pidfile \ --chuid $DAEMON_USER \ --startas /usr/bin/pipexec -- -k \ -- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}' 

优点 :3个进程(pipe理程序pipexeclogger和守护进程本身); 如果守护进程立即终止(例如无效命令) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"正确报告失败。
缺点 :没有。

这是赢家 – 最简单,整洁的解决scheme,似乎运作良好。

引用旧的邮件列表:

https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html

一个简单的方法 – 如果你想使用start-stop-daemon,那么唯一的方法就是创build一个包含以下内容的小脚本:

 #!/bin/sh exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log 

然后使用该脚本作为start-stop-daemon的参数。

也许真正的问题是,是否真的有必要首先使用start-stop-daemon?

我不确定是否“$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2>&1”会closures日志文件的文件描述符…这意味着如果守护进程永远运行,我不确定logrotate或清理磁盘空间的其他机制将起作用。 由于它是>而不是>>,build议的命令也会在重新启动时截断现有的日志。 如果你想知道守护进程为什么崩溃,并且自动重启,那可能不是很有帮助。

另一个选项可能是“$ DAEMON | logger”。 logging器是一个将logging到syslog(/ var / log / messages)的命令。 如果你还需要stderr,我想你可以使用“$ DAEMON 1&2 | logger”

在后台运行时,通常start-stop-daemonclosures标准文件描述符。 从start-stop-daemon的手册页:

-C, – 不接近
强制守护程序进入后台时不要closures任何文件描述符。 用于debugging目的以查看过程输出,或redirect文件描述符以logging过程输出。 只有在使用–background时才有意义。

这个为我工作:

  start-stop-daemon -b -C -o -c \ $DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1 

假设它是bash(尽pipe其他一些shell也可以允许这样做):

 exec >>/tmp/myDaemon.log 

将所有未来的标准输出发送到该文件。 这是因为没有程序名的exec只是做了一些redirect的魔法。 从bash手册页:

如果未指定命令,则任何redirect在当前shell中生效。

所述文件的pipe理当然是另一个问题。

怎么样:

 sudo -u myuser -i start-stop-daemon ...