簡體   English   中英

使用 syslog.h 將自定義時間戳寫入 syslog

[英]write custom timestamp into syslog using syslog.h

我的程序從遠程系統獲取事件,每個事件都包含一個時間戳。 我想使用事件時間戳而不是系統時間將此事件記錄到系統日志中。

有什么方法可以將自定義標頭發送到 syslog deamon 嗎?

我在 debian 上使用 rsyslog

編輯:

“事件”是由一些“裸機”設備生成的。 我的應用程序是實時以太網 (EthernetPOWERLINK) 和普通網絡之間的網關。

我想以微秒的精度保存它們,因為了解它們發生的順序很重要。

所以我需要由裸機設備創建的確切時間戳。 我想將此事件放入系統日志中。 我沒有找到任何要寫入 syslog 的庫(除了 syslog.h)。

我真的需要自己構建軟件包並將它們發送到 rsyslog deamon 嗎?

不,不要打開那罐蠕蟲。

如果您允許發送方指定時間戳,那么您就允許攻擊者欺騙他們希望隱藏的事件的時間戳。 這違背了使用單獨機器進行日志記錄的整個目的(安全方面)。

但是,您可以做的是比較當前時間和時間戳,並將其包含在每條記錄消息的開頭,使用類似

struct timespec   now;
struct timespec   timestamp;
double            delta;

int               priority = facility | level;
const char *const message;

delta = difftime(timestamp.tv_sec,   now.tv_sec)
      + ((double)timestamp.tv_nsec - now.tv_nsec) / 1000000000.0;

syslog(priority, "[%+.0fs] %s\n", delta, message);

在典型配置的 Linux 機器上,這應該產生類似於

Jan 18 08:01:02 hostname service: [-1s] Original message

假設消息至少需要半秒鍾才能到達。 如果主機名的時鍾運行得很快,則增量將為正。 通常,增量為零。 在網絡非常慢的情況下,增量為負,因為原始事件相對於顯示的時間戳發生在過去。

如果您已經有了監控記錄消息的基礎設施,您可以使用守護程序或 cron 腳本讀取日志文件,並生成帶有時間戳的新日志文件(不是通過syslog() ,而是簡單地使用字符串和文件操作)按指定的增量調整。 然而,這必須非常小心地完成,識別不可接受或意外變化的增量,或者可能以某種方式標記它們。

如果您編寫日志文件監控/顯示小部件,那么您可以非常輕松地讓用戶在“實際”(系統日志)或“派生”(系統日志 + 增量)時間戳之間切換,因為從記錄的行中提取增量是微不足道的,如果永遠在場; 即便如此,您也必須小心地讓用戶知道增量是否超出范圍或意外更改,因為此類更改通常對用戶來說是最有用的信息。 (如果它不是惡意的,它確實意味着機器計時有問題;時間不應該只是跳來跳去。即使是 NTP 調整也應該非常平滑。)


如果您堅持要打開那罐蠕蟲,只需生成您自己的日志文件。 許多應用程序都這樣做。 畢竟,這不像syslog()是靈丹妙葯或可靠日志記錄的嚴格要求。

如果您的日志接收應用程序作為特定用戶和組運行,您可以創建由 root 用戶和該組擁有的/var/log/yourlogs/ ,並將您的日志文件保存在那里。 將目錄模式設置為02770drwxrws---u=rwx,g=rwxs,o= ),在該目錄中創建的所有文件將自動歸同一個組所有(這就是 setgid 位s作用目錄)。 您只需要確保您的服務將 umask 設置為002 (並在創建日志文件時使用06660660模式標志),以便它們保持組可讀和組可寫。

日志輪換(歸檔和/或刪除舊日志文件、郵寄日志)通常是一個單獨的服務,由logrotate包提供,並在安裝時通過在/etc/logrotate.d/中刪除特定於服務的配置文件進行配置。 換句話說,即使您自己編寫日志文件,也不要輪換它們; 為此使用現有服務。 它使您的用戶(我們系統管理員)的生活變得更加輕松。 (注意:在上述目錄情況下,在日志輪換腳本的開頭設置umask 002非常有用;創建的文件將是組可寫的umask 022將使它們成為組只讀。)

好的已經解決了這個問題,通過在 rsyslog 配置中啟用網絡支持 (TCP) 和微秒計時器。

根據 RFC 5424,我的應用程序構建原始系統日志消息並通過 TCP(端口 514)將它們發送到守護進程。 感謝Nominal Animal,但我別無選擇......

您可以將原始日志消息寫入/dev/log文件。 這是一個 Unix 域套接字,系統日志服務器從中讀取消息,因為它們是用syslog()函數編寫的。

我不確定可移植性,因為syslog()編寫的消息格式似乎不遵循 RFC 5424。我只能與busybox及其syslogdnc實用程序分享我的發現。

syslog()函數的形式將消息寫入作為數據報<PRI>Mon DD HH:MM:SS message ,其中PRI是一個優先級,即,十進制數計算為facility | severity facility | severity ,后跟時間戳和消息。

使用nc -u local:/dev/log ,您可以直接將 UDP 數據報寫入域套接字。 例如,寫入<84>Apr 3 07:27:20 hello world導致/var/log/messages中出現Apr 3 07:27:20 hostname authpriv.warn hello world行。

然后您可以自由地以微秒精度擴展時間戳。 無論如何,您需要確保您的系統日志服務器實現接受這種形式。 對於busybox ,我不得不修改源代碼。

注意:Busybox 需要配置啟用的CONFIG_NC_EXTRACONFIG_NC_110_COMPATCONFIG_FEATURE_UNIX_LOCAL選項以允許使用nc打開/dev/log

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM