Перевод выполнен Алексеем Паутовым в рамках некоммерческого проекта RussianLDP (http://www.rldp.ru/). Именно на этом сайте и надлежит искать новые версии, если таковые будут.
Exim пишет три различных протокола: главный протокол, протокол отклонённых и протокол паники:
Каждая строка протокола начинается со штампа времени в формате, показанном в следующем примере. Отметьте, что многие из примеров, показанных в этой части, даны с переносом строк. В файле протокола это было бы одной строкой:
2001-09-16 16:09:47 SMTP connection from [127.0.0.1] closed by QUIT |
По умолчанию штампы времени в локальной временной зоне. Есть два способа это изменить:
timezone = UTC |
2003-04-25 11:17:07 +0100 Start queue run: pid=12762 |
Протоколы могут быть записаны в локальные файлы, в syslog или в оба места. Однако, нужно отметить, что многие реализации syslog используют в качестве транспорта UDP и ненадёжны в том смысле, что не гарантируется прибытие сообщений на хост протоколирования, и при этом порядок сообщений не обязательно поддерживается. Также сообщалось, что на больших файлах протоколов (десятки мегабайт), возможно, необходимо настроить syslog для предотвращения синхронизации файла при каждой записи: в linux было замечено, что это вызывало 90% загрузку центрального процессора.
Назначение для протоколов exim конфигурируется путём установки LOG_FILE_PATH в Local/Makefile или путём установки log_file_path в рабочей конфигурации. Эта последняя строка раскрывается и таким образом она может содержать, например, ссылки на имя хоста:
log_file_path = /var/log/$primary_hostname/exim_%slog |
Вообще, желательна установка строки в Local/Makefile вместо рабочей конфигурации, поскольку в этом случае установка доступна с самого начала выполнения exim. Иначе, если будет нужно запротоколировать что-то до чтения конфигурационного файла (например, ошибку в конфигурационном файле), он не сможет использовать путь, который Вы хотите, и может оказаться не в состоянии запротоколировать вообще что бы то ни было.
Значение LOG_FILE_PATH или log_file_path задает список, разделённый двоеточиями, в настоящее время ограниченный максимум двумя элементами. Это единственная опция, где не может использоваться средство для изменения разделителя списка. Этот список всегда должен быть разделён двоеточиями. Если элемент в списке syslog, тогда используется syslog, иначе элемент должен быть абсолютным путём, содержащим %s как точку, где должны быть вставлены main, reject, panic или быть пустым, подразумевая использование пути по умолчанию.
Когда exim сталкивается с пустым элементом в списке, он ищет список, заданный путём LOG_FILE_PATH, и использует первый найденный элемент, если он не пустой или не syslog. Это означает, что в log_file_path может использоваться пустой элемент для обозначения использовать путь, заданный при сборке. Если элемента не существует, файлы пишутся в подкаталог log в каталоге спула. Это эквивалентно установке:
log_file_path = $spool_directory/log/%slog |
Если Вы не определили что-то при компиляции или в рабочей конфигурации, протокол пишутся по указанному пути.
Путь к протоколам может содержать %D или %M, если в имени протоколов используется дата, смотрите секцию 48.3 ниже. Вот некоторые примеры возможных установок:
LOG_FILE_PATH=syslog | Только средства syslog. |
LOG_FILE_PATH=:syslog | syslog и путь по умолчанию. |
LOG_FILE_PATH=syslog : /usr/log/exim_%s | syslog и указанный путь. |
LOG_FILE_PATH=/usr/log/exim_%s | Только указанный путь. |
Если в списке более двух путей, используется первый, и протоколируется паническая ошибка.
Некоторые операционные системы предоставляют централизованные и стандартизованные методы для ротации файлов протоколов. Для тех, которые этого не делают, предоставляется скрипт с именем exicyclog. Он переименовывает и сжимает главный протокол и протокол отклонённых при каждом его вызове. Может быть настроено максимальное число оставляемых старых протоколов. Предполагается, что этот скрипт запускается как ежедневное задание cron
Процесс доставки exim открывает главный протокол, когда ему первый раз необходимо в него записать, и оставляет его открытым в случае, если требуется последующая запись, например, если для одного и того же сообщения производится несколько различных доставок. Однако, удалённые SMTP-доставки могут занять много времени, и это означает, что файл может оставаться открытым после его переименования, если exicyclog или что-то подобное используется для переименования файлов протоколов на регулярной основе. Для гарантии, что переключение файлов будет замечено как можно быстрее, exim вызывает stat() для имени главных протоколов до повторного использования открытых файлов, и если файл не существует или изменился его индекс, старый файл закрывается, а exim пробует открыть пустой главный протокол. Таким образом, старый протокол может оставаться открытым довольно долго, но никакие процессы exim в него не пишут, как только он был переименован.
Вместо ротации файлов главного протокола и протокола отклонённых путём их периодического переименовывания, некоторые любят исполльзовать файлы, чьи имена содержат штамп времени, например, mainlog-20031225. Штамп времни имеет форму yyyymmdd. Exim обладает поддержкой для этого способа работы. Он включается путём установки опции log_file_path в путь, который содержит %D или %M в точке, где требуется дата. Например:
log_file_path = /var/spool/exim/log/%slog-%D log_file_path = /var/log/exim-%s-%D.log log_file_path = /var/spool/exim/log/%D-%slog log_file_path = /var/log/exim/%s.%M |
Как и прежде, %s заменяется на main или reject, вот примеры имён, генерируемых этим примером:
/var/spool/exim/log/mainlog-20021225 /var/log/exim-reject-20021225.log /var/spool/exim/log/20021225-mainlog /var/log/exim/main.200212 |
Когда задана эта форма протоколов, exim автоматически переключается на новые файлы по ночам. Он не предпринимает никаких попыток сжатия старых протоколов: Вам придётся написать свой скрипт, который будет это делать. Вы не должны запускать exicyclog с этой формой протоколирования.
Местоположение протокола паники также определяется путём log_file_path, но на него не ставится штамп даты, поскольку ротация протокола паники не имеет смысла. При генерации имени протокола паники %D или %M удаляется из строки. Дополнительно, если он идёт немедленно после слэша, следующий не алфавитно-цифровой символ удаляется, иначе, удаляется предшествующий не алфавитно-цифровой символ. Таким образом, предыдущие примеры привели бы к таким протоколам паники:
/var/spool/exim/log/paniclog /var/log/exim-panic.log /var/spool/exim/log/paniclog /var/log/exim/panic |
Использование syslog не изменяет того, как exim протоколирует или формат его сообщений, исключая один момент. Если syslog_timestamp установлена в ложь, штамп времени в строках протокола exim пропускается, когда строка посылается в syslog. Кроме того, те же самые строки пишутся в syslog как в файлы протоколов. Средство (facility) syslog установлено в LOG_MAIL, и по умолчанию программа именуется exim, но Вы можете изменить это путём опций syslog_facility и syslog_processname, соответственно. Если exim скомпилирован с SYSLOG_LOG_PID, установленным в Local/Makefile (это значение по умолчанию в src/EDITME), тогда на системах, которые разрешают это (все, исключая ULTRIX), флаг LOG_PID установлен так, чтобы вызов syslog() добавлял pid также, как время и имя хоста в каждую строку. Три потока протоколов распределяются по приоритетам syslog следующим образом:
Многие строки пишутся в оба mainlog и rejectlog, а некоторые пишутся в mainlog и в paniclog, таким образом, они будут дублироватся, если syslod их направит в одно место. Вы можете подавить дубликацию путём установки syslog_duplication в ложь.
Иногда строки протоколов exim бывают очень длинными, и некоторые записи rejectlog содержат несколько строк, когда включаются заголовки. Для борьбы с этими обоими случаями, записываемые в syslog вхождения разделяются в отдельные вызовы syslog() по внутренним новым строкам, а также после максимум 870 знаков. Это учитывает максимальную длинну строки syslog 1024, когда добавлены дополнения, типа штампа времени. Если Вы запускаете замену syslog, которая может обработать строки длинней, чем 1024 символа, разрешённые RFC 3164, Вы должны установить:
SYSLOG_LONG_LINES=yes |
Для облегчения повторной сборки разбитых строк, каждый компонент разбитого вхождения начинается со строки формы [n/m] или [n\m], где n компонент числа и m полное число компонентов вхождения. Разделитель / используется, когда строка разделена из-за того, что она слишком длинная, если же она разбита из-за внутренней новой строки, используется разделитель \. Например, предположим, что ограничение длины 50 вместо 870, следующий пример был бы результатом типичного отклонения сообщения в mainlog (LOG_INFO), дополнительно каждая строка предваряется временем, именем хоста и pid, добавляемых syslog:
[1/5] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from[2/5] [127.0.0.1] (ph10): syntax error in 'From' header[3/5] when scanning for sender: missing or malformed lo[4/5] cal part in "<>" (envelope sender is <ph10@cam.exa [5/5] mple>) |
Та же самая ошибка могла бы привести к следующим строкам, записанным в rejectlog (LOG_NOTICE):
[1/18] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected fro [2/18] m [127.0.0.1] (ph10): syntax error in 'From' head [3/18] er when scanning for sender: missing or malformed [4/18] local part in "<>" (envelope sender is <ph10@cam [5\18] .example>) [6\18] Recipients: ph10@some.domain.cam.example [7\18] P Received: from [127.0.0.1] (ident=ph10) [8\18] by xxxxx.cam.example with smtp (Exim 4.00) [9\18] id 16RdAL-0006pc-00 [10/18] for ph10@cam.example; Mon, 16 Sep 2002 16: [11\18] 09:43 +0100 [12\18] F From: <> [13\18] Subject: this is a test header [18\18] X-something: this is another header [15/18] I Message-Id: <E16RdAL-0006pc-00@xxxxx.cam.examp [16\18] le> [17\18] B Bcc: [18/18] Date: Mon, 16 Sep 2002 16:09:43 +0100 |
Строки протоколов, которые не слишком длинные или не содержат символа новой строки, пишутся в syslog без модификации. Если используется только syslog, монитор exim не может показывать протоколы, если syslog не направляет mainlog в файл на локальном хосте, и переменная окружения EXIMON_LOG_FILE_PATH не указывает монитору, где он находится.
На каждое пришедшее сообщение в протоколы записывается одна строка, и для каждой успешной, неуспешной и задержанной доставки. Эти строки могут быть выбраны по отличительным двухсимвольным флагам, которые идут сразу за штампом времени. Флаги таковы:
Флаг | Значение |
<= | прибытие сообщения |
=> | нормальная доставка сообщения |
-> | дополнительный адрес в той же доставке |
*> | доставка подавлена путём -N |
** | доставка неудачна, отправляется рикошет |
== | доставка задержана, временная проблема |
Формат однострочного вхождения в главном протоколе, который пишется для каждого полученного сообщения, показан в простом примере, ниже, который разбит на несколько строк, чтобы уместиться на странице:
2002-10-31 08:57:53 16ZCW1-0005MB-00 <= kryten@dwarf.fict.example H=mailer.fict.example [192.168.123.123] U=exim P=smtp S=5678 id=<incoming message id> |
Адрес, немедленно сопровождаемый <=, указывает адрес отправителя конверта. Рикошет отображается с адресом отправителя <> и, если он сгенерирован локально, сопровождается элементом в форме:
R=<message id> |
H=(10.21.32.43) [192.168.8.34] H=([10.21.32.43]) [192.168.8.34] |
Это может запутывать. Можно положиться лишь на последний адрес в квадратных скобках. Для локально сгенерированных сообщений (то есть, не переданных через TCP/IP), поле H пропущено, поле U содержит логин вызвавшего exim.
Для всех сообщений поле P определяет протокол, используемый для получения сообщения. Это значение сохраняется в $received_protocol. В случае входящего SMTP-сообщения значение указывает, использовались ли расширения SMTP (ESMTP), шифрование или аутентификация. Если сессия SMTP была шифрованная, есть дополнительное поле X, в котором записан тип использовавшегося шифрования.
Протокол устанавливается в esmptsa или esmtpa для сообщений, переданных от хостов, которые аутентифицировались, используя команду SMTP AUTH. Первое значение используется, когда SMTP-соединение шифрованное (secure). В этом случае есть дополнительный пункт A=, сопровождаемый именем использовавшегося аутентификатора. Если аутентифицированная идентификация была установлена аутентифкационной опцией server_set_id, она также протоколируется, отделяемая двоеточием от имени аутентификатора.
Поле id записывает существующий идентификатор сообщения, если он есть. Размер принятого сообщения даётся в поле S. Когда сообщение доставляется, заголовки могут быть удалены или добавлены, таким образом, размер доставленных копий сообщений может не соответствовать этому значению (и в действительности могут отличаться друг от друга).
Опция log_selector может использоваться для запроса протоколирования дополнительных данных при получении сообщения. Смотрите раздел 48.15.
Формат однострочного вхождения в главном протоколе, который пишется для каждой доставки, показан в одном из примеров ниже, для локальной и удалённой доставки, соответственно. Каждый пример был разбит на несколько строк, чтобы вписаться в страницу:
2002-10-31 08:59:13 16ZCW1-0005MB-00 => marv <marv@hitch.fict.example> R=localuser T=local_delivery 2002-10-31 09:00:10 16ZCW1-0005MB-00 => monk@holistic.fict.example R=dnslookup T=remote_smtp H=holistic.fict.example [192.168.234.234] |
Для обычных локальных доставок оригинальный адрес даётся в угловых скобках после финального адреса доставки, который может быть каналом или файлом. Если между оригинальным и финальным адресом существует промежуточный, последний задаётся в круглых скобках после заключительного. Поля R и T записывают роутер и транспорт, которые использовались при обработке адреса. Если после успешной локальной доставки запускается теневой транспорт, к концу строки об успешной доставке добавляется элемент в форме:
ST=shadow transport name |
Если теневой транспорт был неуспешен, сообщение об ошибке помещается в конце, в круглых скобках. Когда в одной доставке включён более, чем один адрес (например, две команды SMTP RCPT в одной транзакции), второй и последующие адреса помечаются флагами с -> вместо =>. Когда два и более сообщения отправляются по одному SMTP-соединению, для второго и последующих сообщений в строках протоколов за IP-адресом вставляется звёздочка. Генерация сообщения с ответом путём файла фильтра протоколируется как доставка на адрес, которому предшествует >. Опция log_selector может использоваться для запроса протоколирования дополнительных данных при получении сообщения. Смотрите раздел 48.15.
Когда от сообщения отказались, как разультат команды seen finish, появившейся в файле фильтра, который не генерирует никаких доставок, записывается вхождение такой формы:
2002-12-10 00:50:49 16auJc-0001UB-00 => discarded <low.club@bridge.example> R=userforward |
1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole: <hole@nowhere.example> R=blackhole_router |
Когда сообщение задержано, протоколируется строка следующей формы:
2002-12-19 16:20:23 16aiQz-0002Q5-00 == marvin@endrest.example R=dnslookup T=smtp defer (146): Connection refused |
В случае удалённых доставок, ошибка то, что давалось для последнего пробовавшегося IP-адреса. Детали индивидуальной SMTP-ошибки также пишутся в протокол, таким образом, вышеупомянутой строке предшествовало бы что-то вроде этого:
2002-12-19 16:20:23 16aiQz-0002Q5-00 Failed to connect to mail1.endrest.example [192.168.239.239]: Connection refused |
Когда задержанный адрес пропускается, поскольку не наступило его времяя повтора, в протокол записывается сообщение, но это может быть подавлено путём установки соответствующего значения в log_selector.
Если доставка неуспешна по причине невозможности сроутить адрес протоколируется строка такой формы:
1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.example <jim@trek99.example>: unknown mail domain |
Если доставка неудачна в транспортное время, показываются роутер и транспорт, и включается ответ удалённого хоста, как в этом примере:
2002-07-11 07:14:17 17SXDU-000189-00 ** ace400@pb.example R=dnslookup T=remote_smtp: SMTP error from remote mailer after pipelined RCPT TO:<ace400@pb.example>: host pbmail3.py.example [192.168.63.111]: 553 5.3.0 <ace400@pb.example>...Addressee unknown |
Слово pipelined указывает, что было использовано расширение SMTP PIPELINING. Смотрите hosts_avoid_esmtp в транспорте smtp для способа отключения PIPELINING. Строки протоколов для всех форм неудачной доставки помечаются флагом **.
Если доставка не имела места, поскольку для её подавления использовалась опция -N, в протокол пишется обычная строка доставки, исключая, что => заменяется на *>.
Строка в такой форме:
2002-10-31 09:00:11 16ZCW1-0005MB-00 Completed |
Краткое изложение идентификаторов полей, которые используются в строках протоколов, показано в следующей таблице:
Идентификатор | Значение |
A | имя аутентификатора (и опциональный id) |
С | подтверждение SMTP после доставки |
CV | статус проверки сертификата |
DN | характерное имя от сертификата узла |
DT | в строке => время затраченное на доставку |
F | адрес отправителя (в строках доставки) |
H | имя хоста и IP адрес |
I | используемый локальный интерфейс |
id | идентификатор сообщения для входящего сообщения |
P | в строке <= используемый протокол |
P | в => и ** строках используемый протокол |
QT | в строках => время нахождения в очереди на данный момент |
QT | в строках Completed время нахождения в очереди |
R | в строках <= ссылка для локального рикошета |
R | в ** и == строках имя маршрутизатора |
S | размер сообщения |
ST | имя теневого транспорта |
T | в строках <= тема сообщения |
T | в ** и == строках имя транспорта |
U | локальный пользователь или идентификатор RFC 1413 |
X | способ шифрования TLS |
Различные иные типы записей время от времени пишутся в протоколы. Большинство из них очевидны. Чаще всего:
errors_to = <> |
Путём установки глобальной опции log_selector Вы можете отключить некоторое протоколирование exim или запросить дополнительные сведения в протокол. Значение log_selector составлено из имён с предшествующем символом плюса или минуса. Например:
log_selector = +arguments -retry_defer |
Список опциональных элементов протокола указан в следующей таблице со значением по умолчанию, отмеченным звёздочкой:
Элемент | Значение |
8bitmime | получен статус 8bitmime |
*acl_warn_skipped | пропущенное в ACL утверждение warn |
address_rewrite | перезапись адреса |
all_parents | все родители в => строке |
arguments | аргументы командной строки |
*connection_reject | отклонения соединений |
*delay_delivery | задержка немедленной доставки |
deliver_time | время затраченнное на выполнение доставки |
delivery_size | добавляет S=nnn в строки => |
*dnslist_defer | задержки поисков в списках DNS (RBL) |
*etrn | команды ETRN |
*host_lookup_failed | в названии опции всё сказано |
ident_timeout | таймаут соединения ident |
incoming_interface | входящий интерфейс в строке <= |
incoming_port | входящий порт в строке <= |
*lost_incoming_connection | что сказано в названии опции (включая таймауты) |
outgoing_port | добавляет удалённый порт к строке => |
pid | добавляет к строке id процесса |
*queue_run | начало и завершение обработки очереди |
queue_time | время в очереди для одного получателя |
queue_time_overall | время в очереди для всего сообщения |
received_recipients | получатели в cтроках <= |
received_recipients | отправители в строках <= |
*rejected_header | содержимое заголовка в логе отклонённых |
*retry_defer | retry time not reached |
return_path_on_delivery | помещает путь возврата в строки => и *\ |
sender_on_delivery | добавляет отправителя к строкам => |
*sender_verify_fail | ошибка проверки отправителя |
*size_reject | отклонение по причине слишком большого размера |
*skip_delivery | пропуск доставки в обработчике очереди |
smtp_confirmation | подтверждение SMTP в строках => |
smtp_connection | подключения SMTP |
smtp_incomplete_transaction | незавершенная транзакция SMTP |
smtp_no_mail | SMTP-сессия без команд MAIL |
smtp_protocol_error | ошибки протокола SMTP |
smtp_syntax_error | ошибки синтаксиса SMTP |
subject | содержимое Subject: в строках <= |
tls_certificate_verified | статус проверки сертификата |
*tls_cipher | метод шифрования TLS в строках <= и => |
tls_peerdn | TLS узел DN в строках <= и => |
tls_sni | TLS SNI в строках <= |
unknown_in_list | неудача поиска DNS при сравнении списка |
all | все вышеупомянутые |
Дополнительные детали для каждого из этих элементов таковы:
В дополнение к главному файлу протоколов exim пишет файл для каждого сообщения, которое он обрабатывает. Имена этих персональных протоколов для сообщений: идентификаторы сообщений, они хранятся в подкаталоге msglog каталога спула. Каждый протокол сообщения содержит копии строк протоколов, которые касаются сообщения. Это облегчает выяснение статуса индивидуального сообщения без необходимости поиска по главному протоколу. Протокол сообщения удаляется после завершения обработки сообщения, если не задана preserve_message_logs, но она должна использоваться с большой осторожностью, поскольку протоколы могут очень быстро заполнить Ваш диск.
На сильно загруженных системах может быть желательно отключить использование персональных протоколов сообщений для уменьшения дискового ввода-вывода. Это может быть сделано путём установки опции message_logs в ложь.