ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: глобальные директивы erro r_log и pid



On 14.11.2010 2:40, Maxim Dounin wrote:

Pid можно задать в конфиге или через -g "pid $pidfile;".  Никаких
дополнительных ключей для того чтобы его задавать - вводить не
нужно.

если pid задать в конфиге nginx, то дополнительно нужно будет указывать
то же самое значение и в /etc/sysconfig/nginx, чтобы init-script мог
управлять этим экземпляром nginx. и при изменении nginx.conf надо будет
не забыть поправить также и второй конфиг /etc/sysconfig/nginx
дублирование информации неудобно и будет провоцировать ошибки.

если pid задавать только в одном файле /etc/sysconfig/nginx
и передавать его в nginx через -g "pid $pidfile;" -
тогда появится две достаточно неприятные проблемы:

- перестанет нормально работать nginx -s stop|quit|reopen|reload,
потому что вместо $pidfile будет использоваться built-in default
и для управления nginx теперь необходимо будет использовать
только init-скрипт.

создатели httpd, кстати уже наступили на эти грабли и создали shell-
cкрипт apachectl, который считывает конфиг /etc/sysconfig/httpd
и только после этого запускакает httpd c заданными параметрами.
тут придется тоже при таком подходе создавать скрипт nginxctl

- вместо единственного конфигурационного файла /etc/nginx/nginx.conf
которым полностью задавалось поведение nginx их теперь будет два, при
внесении изменений в конфиг, просматривать и править надо будет уже оба.

по этим причинам я ключ -g стараюсь вообще не использовать.
а в /etc/sysconfig/nginx задаю только путь к конфигу nginx.

аналогичные проблемы будут и если сделать -g " error_log ...; "
или такие же как у апача ключи коммандной строки nginx -e и -E.

я придумал более красивое решение:

1. nginx определяет имя конфигурационного файла из параметра -с
    или используется built-in значение, если ключ -c не определен.

2. вызывается helper-функция, которая парсит конфигурационный файл,
    считывая только несколько глобальных директив: error_log и pid,
    если эти две директивы встретились в конфиге, парсинг прекращается.
    директива include также игнорируется, как и возможные ошибки разбора.

Вопрос на самом деле очень простой: если мы хотим куда-то
логировать ошибки открытия/парсинга конфига - то должны откуда-то ещё
получить место для логирования этих ошибок.

Сейчас это "откуда-то ещё" - --error-log-path из бинарника (и
префикс из бинарника или из ключа -p, если путь в --error-log-path
относительный).

делать много каталогов - это не выход, в Linux принят подход
Filesystem Hierarchy Standard (http://www.pathname.com/fhs/)
так что все error-логи nginx находятся в одном каталоге
/var/log/nginx/ - так что ключ -p тут ничем не поможет.

Предлагаемое решение в качестве "откуда-то ещё" сделать
дополнительный sloppy-parser конфига мне кажется крайне
сомнительным.

по такому же приципу работают и современные операционные системы -
для того чтобы загрузить ядро необходимо получить доступ к файловой
системе, а чтобы получить доступ к файловой системе - надо чтобы ядро
уже было запущено. и загрузчик операционной системы выполняет роль
такого "упрощенного парсера", который умеет только читать файлы.

Угу, и я даже и говорить не хочу сколько в этом месте имеется в
результате геморроя.

тем более, что если в конфиге нет директивы error_log,
то все работает как и раньше, используя biult-in defaults.

а если в конфиге nginx указана директива error_log,
тогда все работает ожидаемым для пользователя образом,
это принцип "наименьшего сюрприза". иначе - как и сейчас,
будет очень много вопросов в списках рассылки, почему они
указали директиву error_log в конфиге, а nginx пишет не туда.

Я не говорил, что мне не нравится идея брать error_log из конфига.
Я говорил, что мне не нравится идея делать sloppy-parser этого
конфига.  Это будет приличный кусок дополнительного кода, нужного
только для одной задачи - вытащить error_log.

т.е. все-таки лучше/проще делать это внешним скриптом на python ?

И ладно бы это решало проблему, так ведь полностью оно её не
решает: если конфиг не открылся или там syntax error до
error_log'а - всё равно придётся сваливаться в --error-log-path.

на этапе определения только error_log`а
все ошибки до error_log`а можно и даже нужно игнорировать.

всё что нам надо - это найти не в комментариях, не внутри блока
и не внутри кавычек фрагмент текста error_log и вытащить всё,
что стоит после этой последовательности символов 'error_log'
до закрывающего символа ';' и при необходимости добавить prefix.

после этого - устанавливаем внутри nginx значение переменной
ngx_str_t error_log вместо ngx_string(NGX_ERROR_LOG_PATH);
и начинаем полноценный парсинг конфига, как и раньше.

если конфиг не открылся - тогда да, выходит что без вариантов,
надо будет сваливаться в дефолтовый /var/log/nginx/error.log
но такие ситуации будут достаточно редкими.

А мне, например, нужно *вообще никогда* не трогать
--error-log-path, потому как тот же test suite предполагает
возможность запуска на произвольно скомпилированном бинарнике без
каких-либо последствий для системы.

не совсем понимаю, как сейчас его получается не трогать,
ведь директива error_log из конфига переопределяет дефолтовое
значение переменной error_log, которое было задано в --error-log-path.

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

5. добавляется всего один параметр командной строки -G

   -G directive  : get global directive from configuration file

это необходимо для того, чтобы можно было seamless использовать
один бинарник nginx для запуска нескольких независимых instances:

pidfile=`nginx -G pid`

и дальше init-script знает, какой pid file отвечает этому экземпляру.
причем, вся конфигурация nginx находится только в одном месте - конфиге.

Just a side note: это не имеет ну никакого отношения к проблеме
error_log'а.

верно.

это другая проблема, которая появится у Hongli Lai
после того как он решит эту проблему с erorr_log`ом.

я просто уже прошелся по всем этим граблям несколько раз,
когда пытался сделать несколько nginx instances на одном binary.

Ходить по граблям не запретишь, но в отличие от error_log'а -
проблемы с заданием pid просто нет.

Есть небольшое неудобство, заключающееся в необходмости задавать
его и в конфиге и в init-скрипте (либо только в init-скрипте, но
соответственно отдельно от остального конфига).

Я лишь указал на проблемы предлагаемого подхода разрешния данного
неудобства.

ясно. спасибо. лично меня устроит практически любое решение -
определение пути к лог-файлу и loglevel через ключи nginx -E и -e,
тоже подходит, тогда можно будет внешним скриптом парсить конфиг
nginx и в init-script`е устанавливать значение этих параметров
командной строки перед запуском nginx из init-скрипта,
и nginx -s stop|quit|reopen|reload тоже будет работать
потому что вся конфигурация будет только в nginx.conf.

P.S. у меня такое ощущение, что при использовании apache-подхода
проблем будет намного больше из-за "размазывания" конфигурации
по нескольким файлам и как следствие этого, например,
необходимости использования shell-скрипта nginxctl
вместо теперешнего nginx -s stop|quit|reopen|reload
и т.п. проблемы.

--
Best regards,
 Gena


_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://nginx.org/mailman/listinfo/nginx-ru


 




Copyright © Lexa Software, 1996-2009.