Формальное разделение маркера событий системного журнала?

Я искал RFC5424, чтобы найти формально указанный маркер, который завершит событие системного журнала.

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

Пояснение:

Я называю это событием, потому что связываю сообщение одной строкой. Событие может быть что-то вроде

Type: foo
Source: webservers

тогда как сообщение для меня таково:

Type: foo Source: webservers

http://tools.ietf.org/html/rfc5424 определяет:

SYSLOG-MSG      = HEADER SP STRUCTURED-DATA [SP MSG]

ни STRUCTURED-DATA ни MSG скажи мне, как заканчиваются эти поля. Особенно MSG определяется как MSG-ANY / MSG-UTF8 который распространяется практически на все. Там нет ничего, что говорит, что новая строка отмечает конец (или 8 или a в этом отношении). Приведенный пример сообщения (раздел 6.5):

Это одно действительное сообщение или два действительных сообщения, в зависимости от того, 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 говорит все это для транспорта UDP.

@joechip: Поскольку ваши комментарии и ответы привели меня к тому, что я на самом деле немного больше прочитал RFC по транспорту, я буду рад принять ваш ответ, если вы немного обновите его в этом направлении:)

2 ответа

Решение

Ну, что вы подразумеваете под "событием системного журнала"? В случае, если вы обращаетесь к сообщениям системного журнала, 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 - это количество байтов, которое должно быть взято из буфера buf и отправлено на удаленный хост.

Аналогично, на сервере системного журнала вызывается другая функция или метод, такой как этот:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

Эта функция возвращает длину в байтах полезной нагрузки UDP, полученной в буфере buf. Если приложение попытается прочитать больше, чем эта возвращаемая длина, оно получит мусор (или ошибку сегментации). Чтобы избежать чтения за этим пределом, обычно значение NULL помещается в позицию buf[siz] сразу после вызова siz=recvfrom(...). Таким образом, любой последующий вызов функции, который использует buf в качестве строки, будет работать правильно. Это нулевое завершение, конечно, относится только к строкам, а не к потокам октетов. И это нулевое значение, как я уже сказал, обычно не передается по сети, а только добавляется принимающим приложением.

В случае сервера системного журнала как принимающего приложения, большинство серверов системного журнала могут добавить это нулевое завершение для их внутренней обработки полученной строки (если они вообще рассматривают это как строку), но в любом случае это нулевое значение остается out, когда строка добавляется в файл журнала, чтобы не нарушать обработку текста файла журнала в целом.

В разделе 6.1 они определяют длину сообщения. Я бы подумал, что когда вы получите полное сообщение, у вас будут заголовок и данные, и это будет в сумме до такой длины.

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

Другие вопросы по тегам