Назад | Перейти на главную страницу

Регистрация вывода демона с помощью Upstart

У меня есть собственный демон, которым управляет выскочка на моем сервере 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

Вот как это работает:

  1. mkfifo /tmp/myservice-log-fifo просто создает специальный файл fifo (он же именованный канал). Тип man 7 fifo для получения дополнительной информации.
  2. ( logger ... </tmp/myservice-log-fifo & ) запускает считывание регистратора из FIFO в фоновом режиме. Сквозные скобки приводят к тому, что процесс регистратора заменяется на init, а не остается дочерним по отношению к текущему процессу оболочки.
  3. exec >/tmp/myservice-log-fifo перенаправляет стандартный вывод текущей оболочки на 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 строфа, а затем направьте вывод вашего скрипта в 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

чтобы получить как файл выскочки, так и вывод системного журнала