У меня есть собственный демон, которым управляет выскочка на моем сервере Ubuntu. Он работает отлично, за исключением того, что мне нужно фиксировать (регистрировать) вывод демона. В официальная страница строф говорит, что я могу использовать console logged
для этого, но в какой файл он записывается?
Я также читал это console logged
является больше не действительная строфа. В настоящее время я использую 0.3.9 (Hardy), но через несколько месяцев я обновлюсь до 0.6.x (Lucid). Если console logged
на самом деле не будет работать с более поздними версиями, что мне использовать вместо этого?
Этот фрагмент будет передавать вывод вашей службы в регистратор, в то же время позволяя вам выполнять процесс службы (таким образом заменяя процесс оболочки), чтобы выскочка не запуталась. Это также гарантирует, что процесс регистратора переназначен на init, поэтому он не является дочерним по отношению к вашей службе, и позволяет избежать бессмысленного бездействия в файловой системе, даже если ему необходимо временно создать файл 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 (он же именованный канал). Тип man 7 fifo
для получения дополнительной информации.( logger ... </tmp/myservice-log-fifo & )
запускает считывание регистратора из FIFO в фоновом режиме. Сквозные скобки приводят к тому, что процесс регистратора заменяется на init, а не остается дочерним по отношению к текущему процессу оболочки.exec >/tmp/myservice-log-fifo
перенаправляет стандартный вывод текущей оболочки на 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
строфа, а затем направьте вывод вашего скрипта в logger
(командный интерфейс оболочки к модулю системного журнала syslog (3)), тогда это будет работать.
Например
console output
exec /my/script | logger
войдет в /var/log/messages
Например
console output
exec /my/script | logger -t my-script
войдет в /var/log/messages
и пометьте каждое сообщение my-script
logger --help
для вариантов использования регистратора.
(Я использую AMI Amazon Linux, основанный на Centos 5.x; YMMV)
Я не получил mkfifo
трюк, чтобы работать удовлетворительно; похоже, что он не захватывает stderr, и попытки перенаправить вызвали Upstart без ошибок.
У этого также есть неприятный побочный эффект: logger
процесс торчать как ребенок init
, поэтому информация о том, кто "владеет" регистратором, теряется, и кто-либо еще не знает mkfifo
может подумать, что это зависший процесс, который можно убить.
Вместо этого я пришел к следующему решению, которое решает все эти проблемы. Это вызывает logger
чтобы стать дочерним процессом, сохранив службу в качестве корневого процесса. К сожалению, это требует выполнения bash
, но это просто выглядит грязный.
script
# ... setup commands here, e.g. environment, cd, ...
exec bash <<EOT
exec 1> >(logger -t myservice) 2>&1
exec myservice
EOT
end script
Здесь используется трюк, который перенаправляет stdout и stderr на команду. Поскольку мы выполняем сервис внутри bash
команда, это имеет побочный эффект замены оболочки и волшебным образом превращает bash в дочерний процесс службы, как показано ps aufxw
:
myservice
\_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
\_ logger -t myservice
По какой-то причине указанная выше команда должна быть заключена в bash -c
. Я предполагаю, что это потому, что Upstart только делает вид, что запускает ваш скрипт через Bash, но на самом деле это не так. Если кто-нибудь может предложить способ избежать лишней оболочки bash, это было бы здорово.
Это уродливо, но пока лучшее, что я нашел
exec / путь / к / серверу >> /tmp/upstart.log 2> & 1
Вы также можете перенаправить вывод в системный журнал, например
exec $SERVER 2>&1 | logger -t myservice -p local0.info
Однако конвейер может привести к тому, что выскочка перепутает PID процесса регистрации с PID демона.
Другой вариант - использовать тройник, например:
exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice
чтобы получить как файл выскочки, так и вывод системного журнала