我有一个由我的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
这是如何工作的:
mkfifo /tmp/myservice-log-fifo
只是使fifo特殊文件(又称命名pipe道)。 inputman 7 fifo
获取更多信息。 ( logger ... </tmp/myservice-log-fifo & )
从后台开始logging器读取。 该parens导致logging器进程重新初始化为init,而不是保留当前shell进程的subprocess。 exec >/tmp/myservice-log-fifo
将当前shell的stdoutredirect到fifo。 现在我们有一个用于该fifo的开放文件描述符,而且我们实际上不再需要文件系统条目了… rm /tmp/myservice-log-fifo
所以我们将删除它。 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
如果使用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输出