Я смотрел на RFC5424 чтобы найти официально указанный маркер, который завершит событие системного журнала.
К сожалению, найти не удалось. Итак, если бы я хотел реализовать небольшой сервер системного журнала, который реагирует на определенные сообщения, то какой маркер заканчивает сообщение (да, обычно событие представляет собой одну строку, но я просто не мог найти его в спецификации)
Разъяснение:
Я называю это событием, потому что связываю сообщение с одной строкой. Событие могло быть чем-то вроде
Type: foo
Source: webservers
тогда как сообщение для меня таково:
Type: foo Source: webservers
http://tools.ietf.org/html/rfc5424#section-6 определяет:
SYSLOG-MSG = HEADER SP STRUCTURED-DATA [SP MSG]
ни то, ни другое STRUCTURED-DATA
ни MSG
скажите, чем заканчиваются эти поля. Особенно MSG
определяется как MSG-ANY / MSG-UTF8
который расширяется практически до всего. Нет ничего, что говорило бы, что новая строка отмечает конец (или 8
или a
в этом отношении). Учитывая примеры сообщений (раздел 6.5):
Это одно действительное сообщение или 2 действительных сообщения в зависимости от того, говорите ли вы, что HEADER
элемент никогда не должен встречаться ни в каком MSG
элемент:
буквальный пробел
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - <34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
|
is this an end marker?
\t
обозначает вкладку
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\t<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
|
is this an end marker?
\n
означает новую строку
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 -\n<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47
|
is this an end marker?
Либо я неправильно читаю RFC, либо там просто нет упоминания. Размеры, указанные в RFC, просто говорят о минимальной ожидаемой длине, с которой я могу работать ...
ОТВЕТ?: Похоже, я читал не тот RFC. Нужно перейти к конкретным RFC для транспорта и придерживаться этого http://tools.ietf.org/html/rfc5426#section-3.1 говорит само за себя об UDP-транспорте.
@joechip: Поскольку ваш комментарии и ответ заставьте меня прочитать немного больше в RFC транспорта, я буду рад принять ваш ответ, если вы немного обновите его в этом направлении :)
Что вы имеете в виду под «событием системного журнала»? Если вы ссылаетесь на сообщения системного журнала, RFC5424 однозначно определяет синтаксис сообщения системного журнала в своем разделе 6, а именно то, как оно должно передаваться от одного приложения системного журнала к другому.
В случае, если вы имеете в виду, как они хранятся в файлах журнала принимающим приложением системного журнала, типичные реализации системного журнала просто отделяют одну запись от другой с помощью символов новой строки, и это обычно не настраивается. Более того, текстовое поле записи системного журнала может также включать символы новой строки, что усложняет задачу правильного анализа файла журнала. Тем не менее его обычно можно проанализировать, потому что каждая запись системного журнала начинается с обычной последовательности даты, времени, хоста и тега, в то время как новые строки внутри записи системного журнала обычно не сопровождаются текстом, аналогичным тем.
Я думаю, что возможность изменить разделитель хранимых записей системного журнала была бы полезной функцией, но любое появление такого разделителя внутри самой записи должно быть исключено, чтобы это было полезно. Добавление такой большой структуры к текстовому файлу обязательно будет компромиссом. Если вас очень волнует эта проблема, возможно, вам следует поддержать запись в файлы журнала в каком-либо четко определенном двоичном формате (например, здесь может быть полезен sqlite).
Изменить: более тщательное изучение раздела 6 RFC5424 показывает, что сообщение системного журнала может иметь две формы:
HEADER SP STRUCTURED-DATA
или
HEADER SP STRUCTURED-DATA SP MSG
Расширяя спецификацию ABNF, мы можем легко увидеть, что первая форма оканчивается либо на «-», либо на «]». Перед этим последним символом могут быть другие символы «-» и «]», поэтому его нельзя принимать за терминатор сообщения системного журнала.
Окончание второй формы зависит от того, как закончится MSG. MSG может быть либо строкой UTF-8 (как указано в RFC 3629, которая не содержит завершения строки), либо произвольным потоком октетов, заканчивающимся любым значением. Очевидно, что и для этой формы такого символа завершения не предусмотрено.
Но факт в том, что нет необходимости в ограничителе сообщения системного журнала, независимо от того, в какой форме оно находится, потому что длина сообщения передается внеполосным транспортным уровнем. Когда пакет UDP отправляется приложением, сообщение системного журнала должно быть уже подготовлено в соответствии со спецификацией и сохранено в буфере. Этот буфер передается приложением в функцию или метод для его отправки, а также передается количество байтов для отправки. Например, в C мы имеем:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
В этом примере len это количество байтов, которое следует взять из буфера бух и отправляется на удаленный хост.
Аналогичным образом на сервере системного журнала вызывается другая функция или метод, например:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
Эта функция возвращает длину в байтах полезной нагрузки UDP, полученной в буфере. бух. Если приложение попытается прочитать больше, чем эта возвращенная длина, оно получит мусор (или ошибку сегментации). Чтобы избежать превышения этого предела, обычно помещают значение NULL в позицию buf [размер] сразу после siz = recvfrom (...) вызов. Таким образом, любой последующий вызов функции, использующий бух как строка будет работать правильно. Это завершение нулем применяется, конечно, только к строкам, но не к потокам октетов. И это нулевое значение, как я уже сказал, обычно не передается по сети, а только добавляется принимающим приложением.
В случае сервера системного журнала в качестве принимающего приложения большинство серверов системного журнала могут добавить это завершение нулем для своей внутренней обработки полученной строки (если они вообще обрабатывают ее как строку), но в любом случае это нулевое значение остается out, когда строка добавляется к файлу журнала, чтобы не нарушать обработку текста файла журнала в целом.
В разделе 6.1 они определяют длину сообщения. Я полагаю, что когда вы получите полное сообщение, у вас будут заголовок и данные, и они увеличатся до этой длины.
Кроме того, я не вижу возможности для нескольких сообщений. Поэтому я полагаю, что каждое сообщение - это событие. Отсутствует какое-либо отслеживание нескольких сообщений и определенная кодировка для начального, среднего и конечного сообщений. Системный журнал отслеживает зарегистрированные сообщения, на самом деле он не имеет концепции событий более высокого уровня.