我如何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 daemon
, su
和守护进程本身)。
缺点 :由于混淆守护进程的命令行选项,难以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理程序pipexec
, logger
和守护进程本身); 如果守护进程立即终止(例如无效命令) 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-daemon
closures标准文件描述符。 从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 ...