Реєстрація виходу Daemon за допомогою Upstart


34

У мене є користувацький демон, яким керує upstart на моєму сервері Ubuntu. Це прекрасно працює за винятком того, що мені потрібно зафіксувати (записати) вихід демона. На офіційній сторінці строф написано, що я можу використовувати console loggedце, але в який файл він входить?

Я також читав, що console loggedце вже не дійсна строфа . Зараз я використовую 0,3,9 (Hardy), але оновлюсь до 0,6.x (Lucid) через кілька місяців. Якщо console loggedнасправді не працюватимуть з пізнішими версіями, що я використовую натомість?


1
Чи можете ви просто оновити свій користувацький демон, щоб надіслати вихід у syslog або в файл реєстрації, вказаний у файлі конфігурації демона?
Zoredache

Відповіді:


35

Цей фрагмент передає висновок вашої послуги в реєстратор, при цьому все ще дозволяє виконувати сервісний процес (таким чином замінюючи процес оболонки), щоб швидкий запуск не заплутався. Він також гарантує, що процес реєстрації буде відновлений до init, тому він не є вашим дочірнім сервісом, і це дозволяє уникнути того, як груба клітка сидітиме навколо файлової системи, навіть якщо їй потрібно створити фіфо тимчасово.

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). Введіть man 7 fifoдодаткову інформацію.
  2. ( logger ... </tmp/myservice-log-fifo & ) починає зчитування реєстратора з фіфо, на задньому плані. Парени спричиняють відновлення процесу реєстрації до init, а не залишаючись дочірнім поточним процесом оболонки.
  3. exec >/tmp/myservice-log-fifoпереадресовує поточну оболонку оболонки на фіфо. Тепер у нас є дескриптор відкритого файлу для цієї програми, і нам фактично вже не потрібна запис файлової системи ...
  4. rm /tmp/myservice-log-fifo тому ми його видалимо.
  5. exec myservice 2>/dev/nullпросто запускає послугу звичайним способом. Stdout вже йде до фіфо, і це не зміниться після запуску нової програми.

ОНОВЛЕННЯ: set -e не потрібна, оскільки Upstart запускає сценарії з цією опцією за замовчуванням (див. Http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh )


чудова відповідь, і не залишає файлів FIFO лежачи де-небудь.
Еш Берлін-Тейлор

Що таке set -e?
Пітер Мунс

1
set -eВикликає скрипт негайно вийти , якщо будь-яка команда виходить з ладу. Без цього рядка сценарій продовжував би виконувати наступні команди марно (а можливо і небезпечно).
Кіт Рарік

1
Щоб увійти як stderr, так і stdout, додайте рядок exec 2>&1над rmрядком та видаліть 2>/dev/nullз останнього рядка.
ітадок

31

Для останніх версій Ubuntu (12.04 і новіших) просто використовуйте

console log

І вихід демона (STDOUT & STDERR) буде доданий до /var/log/upstart/<service>.log

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


2
Це було б чисто і приємно, але, на жаль, він не працює на CentOS 6.x, який все ще постачає стародавню версію upstart, яка не підтримує це.
Крістіан Магеружан-Станчіу

11

Якщо ви використовуєте 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 для параметрів використання реєстраторів.

(Я перебуваю на Amazon Linux AMI, який базується на Centos 5.x; YMMV)


4
Виявляється, це не гарне рішення. на початку засувається на PID logger, а не в процесі, яким ви хочете, щоб ним керували.
Пітер Мунс

10

Я не отримав 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

Чомусь вищевказану команду потрібно загорнути в a bash -c. Я припускаю, що це тому, що Upstart тільки робить вигляд, що запускає ваш сценарій через Bash, але насправді це не так. Якщо хтось може запропонувати спосіб уникнути зайвої оболонки, це було б приголомшливо.


1
Так! Я так рада, що знайшла це. Виглядає краще, ніж варіант mkfifo, і в моєму випадку мені потрібно було, exec bash -l << EOFщоб там втрат не було.
thom_nic

6

Це некрасиво, але поки що найкраще, що я знайшов

exec / шлях / до / сервера >> /tmp/upstart.log 2> & 1


2
Рішення не є гарним, коли справа стосується обертання журналу, оскільки програма веде реєстрацію безпосередньо у файл. Реєстрація через syslog дозволяє уникнути пов'язаних з цим проблем.
Марк Стосберг

3

Ви також можете перенаправити вихід на syslog, наприклад

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

Однак конвеєр може призвести до запуску, щоб плутати PID процесу каротажу з PID демона.


Демон, що плутає PID, насправді є марним демоном, оскільки він повинен спостерігати за процесом, а потім відновлювати його. Будь-яка ідея, як переконатися, що правильний PID спостерігається?
Йоганн Філіп Стратхаузен

Я думаю (але не намагався), що ви хочете expect forkабо expect daemonстрофу. Або, можливо, ви могли б catpid-файл у лог-повідомлення в іншому випадку, я думаю.
Пітер Мунс

1

Ще одна альтернатива - використання трійника типу:

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

щоб отримати як файл запуску, так і вихід системи

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.