用暴发户logging守护进程的输出

我有一个由我的Ubuntu服务器上的新贵pipe理的自定义守护进程。 除了我需要捕获(logging)守护进程的输出外,它完美的工作。 官方节页面说,我可以使用console logged做到这一点,但它login到什么文件?

我也读过, console logged 不再是一个有效的节 。 我目前使用0.3.9(哈代),但几个月后会升级到0.6.x(Lucid)。 如果console logged实际上不能用于更高版本,我用什么来代替?

这段代码将把你的服务的输出传递给logging器,同时还允许你执行服务进程(从而replaceshell进程),这样暴发户就不会感到困惑。 它也确保logging器进程重新初始化,所以它不是你的服务的孩子,它可以避免在文件系统中留下垃圾,即使它需要临时创build一个fifo。

 script mkfifo /tmp/myservice-log-fifo ( logger -t myservice </tmp/myservice-log-fifo & ) exec >/tmp/myservice-log-fifo rm /tmp/myservice-log-fifo exec myservice 2>/dev/null end script 

这是如何工作的:

  1. mkfifo /tmp/myservice-log-fifo只是使fifo特殊文件(又称命名pipe道)。 inputman 7 fifo获取更多信息。
  2. ( logger ... </tmp/myservice-log-fifo & )从后台开始logging器读取。 该parens导致logging器进程重新初始化为init,而不是保留当前shell进程的subprocess。
  3. exec >/tmp/myservice-log-fifo将当前shell的stdoutredirect到fifo。 现在我们有一个用于该fifo的开放文件描述符,而且我们实际上不再需要文件系统条目了…
  4. rm /tmp/myservice-log-fifo所以我们将删除它。
  5. exec myservice 2>/dev/null只是以通常的方式运行服务。 Stdout已经进入fifo了,新程序执行时不会改变。

更新: set -e不需要,因为默认情况下,Upstart使用此选项运行脚本(请参阅http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh

对于最近的Ubuntu版本(12.04+),只需使用

 console log 

守护进程输出(STDOUT&STDERR)将被追加到/var/log/upstart/<service>.log

http://upstart.ubuntu.com/cookbook/#console-log

如果使用console output 节 ,然后将脚本的输出pipe道输出到logger (shell命令接口到syslog(3)系统日志模块),那么这将工作。

例如

 console output exec /my/script | logger 

会logging到/var/log/messages

例如

 console output exec /my/script | logger -t my-script 

将logging到/var/log/messages并用my-script标记每条消息

logger --help帮助logging器使用选项。

(我在基于CentOS 5.x的Amazon Linux AMI上; YMMV)

我没有得到令人满意的mkfifo技巧, 它似乎没有捕捉到stderr,并试图redirect导致Upstart保释无误。

它还有一个不幸的副作用,就是使得logger进程作为init一个subprocess挂起,所以关于“拥有”logging器的信息将会丢失,而任何不知道mkfifo可能会认为这是一个悬而未决的进程杀害。

相反,我结束了以下解决scheme,解决所有这些问题。 它使logger成为一个subprocess,同时保留作为根进程的服务。 不幸的是,它需要执行bash ,但它看起来很脏。

 script # ... setup commands here, eg environment, cd, ... exec bash <<EOT exec 1> >(logger -t myservice) 2>&1 exec myservice EOT end script 

这使用一个把stdout和stderrredirect到一个命令的技巧。 由于我们在bash命令里面执行了这个服务,这有副作用,换成shell,神奇地把bash变成服务的subprocess,如ps aufxw

 myservice \_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice \_ logger -t myservice 

出于某种原因,上面的命令必须包装在bash -c 。 我认为这是因为Upstart只是假装通过Bash运行你的脚本,但实际上并不是这样。 如果任何人都可以build议一种方法来避免多余的bash shell,那就太棒了。

这是丑陋的,但迄今为止我find的最好的

exec / path / to / server >> /tmp/upstart.log 2>&1

你也可以将输出redirect到系统日志,例如

 exec $SERVER 2>&1 | logger -t myservice -p local0.info 

但是,stream水线可能会引起新手将日志进程的PID与守护进程的PID混淆。

另一种select是使用T恤:

 exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice 

获得新贵文件和syslog输出