Syslog

系統日誌事件的正式分隔標記?

  • July 1, 2011

我一直在查看RFC5424以找到將結束系統日誌事件的正式指定標記。

不幸的是我找不到它。因此,如果我想實現一些對某些消息做出反應的小型系統日誌伺服器,那麼結束消息的標記是什麼(是的,通常事件是單行,但我只是在規範中找不到它)

澄清

我稱它為事件是因為我將一條消息與一行相關聯。一個事件可能是這樣的

Type: foo
Source: webservers

而給我的資訊是:

Type: foo Source: webservers

https://www.rfc-editor.org/rfc/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 並遵守https://www.rfc-editor.org/rfc/rfc5426#section-3.1說明 UDP 傳輸的全部內容。

@joechip:由於您的評論和回答使我實際上在傳輸 RFC 中閱讀了更多內容,如果您朝那個方向稍微更新一下,我將很樂意接受您的回答 :)

那麼,“系統日誌事件”是什麼意思?如果您提到 syslog 消息,RFC5424 在其第 6 節中明確定義了 syslog 消息語法,即如何將其從一個 syslog 應用程序傳輸到另一個應用程序。

如果您指的是接收 syslog 應用程序如何將它們儲存在日誌文件中,典型的 syslog 實現只是用換行符將一條記錄與另一條記錄分開,這通常不是可配置的行為。此外,系統日誌記錄的文本欄位還可以包含換行符,這會使正確解析日誌文件的任務複雜化。儘管如此,它通常仍然可以被解析,因為每個 syslog 記錄都以通常的日期、時間、主機和標籤序列開頭,而 syslog 記錄中的換行符通常不會跟隨類似的文本。

我認為更改 syslog 儲存記錄分隔符的能力將是一個有用的功能,但記錄本身內出現的任何此類分隔符都應該被轉義以使其有用。在純文字文件中添加如此多的結構必然是一種妥協。如果您非常關心這個問題,也許您應該支持以某種定義良好的二進制格式寫入日誌文件(例如,sqlite 在這裡可能很有用)。

編輯:對 RFC5424 第 6 節的更仔細檢查表明,系統日誌消息可以有兩種形式:

HEADER SP STRUCTURED-DATA

或者

HEADER SP STRUCTURED-DATA SP MSG

通過擴展 ABNF 規範,我們可以很容易地看到第一種形式以“-”或“]”結尾。在最後一個字元之前可能還有其他“-”和“]”字元,因此不能將其用作 syslog 消息終止符。

第二種形式的結尾取決於 MSG 的結尾。MSG 可以是 UTF-8 字元串(如 RFC 3629 中所指定,不包含字元串終止)或以任何值結尾的任意八位字節流。顯然,也沒有為這種形式指定這樣的終止符號。

但事實是,不需要 syslog 消息終止符,無論它採用何種形式,因為消息長度是由傳輸層帶外通信的。當應用程序發送 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中取出並發送到遠端主機的字節數。

同樣,在 syslog 伺服器上呼叫另一個函式或方法,例如:

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

此函式返回緩衝區buf中接收到的 UDP 有效負載的字節長度。如果應用程序嘗試讀取超過此返回長度,它將得到垃圾(或分段錯誤)。為避免讀取超出此限制,通常在位置buf放置一個 NULL 值$$ siz $$siz=recvfrom(…)呼叫之後。這樣,以後任何使用buf作為字元串的函式呼叫都將正常工作。當然,這種空終止僅適用於字元串,而不適用於八位字節流。正如我所說,這個空值通常不通過網路傳輸,而只是由接收應用程序添加。

在 syslog 伺服器作為接收應用程序的情況下,大多數 syslog 伺服器可能會添加此空終止符以用於其內部處理接收到的字元串(如果它們將其視為字元串),但無論如何都會留下此空值當字元串附加到日誌文件時輸出,以免破壞整個日誌文件的文本處理。

引用自:https://serverfault.com/questions/281826