無法過濾 syslog-ng 中格式錯誤的消息
我正在就 syslog-NG 的問題與您聯繫。我們的一些設備(主要是 HP 交換機和 SAN)正在發送似乎不遵守 syslog RFC 5424 的 syslog 消息。
舉幾個例子:
如果我嗅探伺服器的網路介面,我們可以看到這些“錯誤”消息(如您所見,在 PRI 之後,我們可以看到 PROGRAM,然後是時區和用逗號分隔的欄位。簡而言之,混合欄位,缺少欄位等不是標準的系統日誌消息):
<190>raslogd: 2017/03/08-16:03:20, [SEC-1203], 53642, WWN 10:00:50:eb:1a:6c:21:38 | FID 128, INFO, cswc-mo8x-SAN01, Login information: Login successful via TELNET/SSH/RSH. IP Addr: 1.2.3.4
因此,我目前無法過濾這些消息。我嘗試定義一個正常過濾器並嘗試列印 MSGHDR、MSG、PRI 等欄位,但什麼也看不到。
過濾此消息的唯一方法是僅定義外部介面和一個文件作為輸出,而無需任何模板。
例如,如果我做這樣的過濾器:
destination d_INCOMING_ALL { file("/app/syslog-ng/logs/incoming_all.log"); }; log { source(s_EXTERNAL); destination(d_INCOMING_ALL); };
我可以在日誌文件中看到消息,但以某種方式格式化(我想 syslog-NG 重新格式化它們):
[root@xxxxxxxxxxxx logs]# grep -i cswc incoming_all.log Mar 9 09:44:20 cswc-mo8x-hpsan01 raslogd: 2017/03/09-08:34:50, [SEC-1203], 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128, INFO, cswc-mo8x-SAN01, Login information: Login successful via TELNET/SSH/RSH. IP Addr: 1.2.3.4 [root@xm1p1034vmo logs]#
問題是我無法在那裡過濾這些消息(我們從超過 1000 個設備接收日誌),我需要過濾來自這些設備的消息!我能做到的唯一方法是使用主機名(cswc- )或程序名(raslogd)
所以我嘗試通過向該文件添加模板來顯示欄位,例如:
destination d_test { file ("/app/syslog-ng/logs/test_olivier.log" template("pri=${priority} date=${ISODATE} host=${HOST} program=${PROGRAM} message=${MSG}\n") ); };
但沒有任何效果,沒有顯示任何內容。我嘗試了所有欄位,MSG、MESSAGE、MSGHDR 等。無法管理顯示任何內容。唯一有效的是沒有過濾器或模板的解析。
自然,如果我嘗試了所有類型的過濾器,如下面的這些,它就不起作用(因為欄位是混合的):
filter f_is_SAN { host("cswc.*" flags(ignore-case)); };
相同的:
filter f_is_SAN { match(".*cswc.*" flags(ignore-case)); };
關於如何為來自這些設備(主機名或程序名)的這些消息創建過濾器的任何提示?
感謝和問候,
嗯,我找到了一個似乎有效的解決方案
我正在重用“本地副本”目標作為源
例如:
我有一個正常的日誌過濾器,保留所有內容的副本:
destination d_INCOMING_ALL { file("/app/syslog-ng/logs/incoming_all.log"); }; log { source(s_EXTERNAL); destination(d_INCOMING_ALL); };
該消息保存在正在重新格式化的“本地副本”中。然後我可以從源中的這個文件重新讀取並將過濾器應用到它。它很髒,但它有效:
source s_NON_RFC_COMPLIANT { # new source file("/app/syslog-ng/logs/incoming_all.log" follow-freq(10)); }; .... destination d_INCOMING_ALL { file("/app/syslog-ng/logs/incoming_all.log"); # old destination where we keep a local copy of EVERYTHING }; .... log { # local copy of everything source(s_EXTERNAL); destination(d_INCOMING_ALL); }; .... other filters here .... filter f_is_Network { host("cswc.*" flags(ignore-case)) # we want to filter on hosts called cswc-something or program raslogd or program("raslogd" flags(ignore-case)); }; log { # new source for HP stuff here source(s_NON_RFC_COMPLIANT); filter(f_is_Network); # add the filters you need destination(<your_final_destination_here>); flags(final); };
實際上,syslog-ng 並沒有重新格式化它們,而是添加了一個適當的 syslog 標頭:
3 月 9 日 09:44:20 cswc-mo8x-hpsan01 raslogd:2017/03/09-08:34:50,
$$ SEC-1203 $$, 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128,INFO,cswc-mo8x-SAN01,登錄資訊:TELNET/SSH/RSH登錄成功。IP 地址:1.2.3.4
以下是 syslog 添加的:
3 月 9 日 09:44:20 cswc-mo8x-hpsan01
其餘的是原始消息:
raslogd: 2017/03/09-08:34:50,
$$ SEC-1203 $$, 53647, WWN 10:00:50:eb:1a:6c:21:38 | FID 128,INFO,cswc-mo8x-SAN01,登錄資訊:TELNET/SSH/RSH登錄成功。IP 地址:1.2.3.4
因此 syslog-ng 同意您的觀點,即這些消息不符合 RFC。
在設置過濾器方面,這意味著您沒有太多可玩的了。
我個人更習慣於 rsyslog(您可以在其中使用正則表達式檢查消息,例如尋找
raslogd
- 儘管這不一定有效)。但是,標題 syslog-ng 能夠添加給您一些事情要做:
filter hp_hosts { (host(192.168.0.25)) };
- 您目前的主機過濾器失敗,因為消息中沒有 HOST 欄位 -
host
過濾器狀態的文件:也就是說,syslog-ng OSE 會將過濾器表達式與 ${HOST} 宏的內容進行比較。
- 但是,您確實在消息中有一個主機名(至少在您的範例中),因此您可以考慮使用消息過濾器。
話雖這麼說 - 對我來說,如果有可能獲得所有這些設備的源 IP 列表(我只能為了你的緣故希望這是可能的),那麼我會使用網路遮罩過濾器 - 它似乎很可能是比其他選項更有效。