書名: Linux程序設計(第4版)作者名: (英)Neil Matthew Richard Stones本章字數: 1871字更新時間: 2021-04-09 20:04:49
4.7 日志
許多應用程序需要記錄它們的活動。系統程序經常需要向控制臺或日志文件寫消息。這些消息可能指示錯誤、警告或是與系統狀態(tài)有關的一般信息。例如,su程序會把某個用戶嘗試得到超級用戶權限但失敗的事實記錄下來。
通常這些日志信息被記錄在系統文件中,而這些系統文件又被保存在專用于此目的的目錄中。它可能是/usr/adm或/var/log目錄。對一個典型的Linux安裝來說,文件/var/log/messages包含所有系統信息,/var/log/mail包含來自郵件系統的其他日志信息,/var/log/debug可能包含調試信息。根據你所使用Linux版本的不同,可以通過查看/etc/syslog.conf文件或者/etc/syslog-ng/sys-log-ng.conf文件來檢查系統配置。
下面是一些日志信息的示例:

這里,你可以看到記錄的各種類型的信息。前幾個是由Linux內核在啟動和檢測已安裝硬件時自己報告的信息。然后是防火墻記錄它重新配置的信息。最后,su程序報告用戶neil獲得了超級用戶權限。
查看日志信息可能需要有超級用戶特權。
有些UNIX系統并不像上面這樣提供可讀的日志文件,而是為管理員提供一些工具來讀取系統事件的數據庫。具體情況請參考系統文檔。
雖然系統消息的格式和存儲方式不盡相同,但產生消息的方法卻是標準的。UNIX規(guī)范通過syslog函數為所有程序產生日志信息提供了一個接口:

syslog函數向系統的日志設施(facility)發(fā)送一條日志信息。每條信息都有一個priority參數,該參數是一個嚴重級別與一個設施值的按位或。嚴重級別控制日志信息的處理方式,設施值記錄日志信息的來源。
定義在頭文件syslog.h中的設施值包括LOG_USER(默認值)——它指出消息來自一個用戶應用程序,以及LOG_LOCAL0、LOG_LOCAL1直到LOG_LOCAL7,它們的含義由本地管理員指定。
嚴重級別按優(yōu)先級遞減排列,如表4-6所示。
表4-6

根據系統配置,LOG_EMERG信息可能會廣播給所有用戶,LOG_ALERT信息可能會EMAIL給管理員,LOG_DEBUG信息可能會被忽略,而其他信息則寫入日志文件。當編寫的程序需要使用日志記錄功能時,你只需要在希望創(chuàng)建日志信息時調用syslog函數即可。
syslog創(chuàng)建的日志信息包含消息頭和消息體。消息頭根據設施值及日期和時間創(chuàng)建。消息體根據syslog的message參數創(chuàng)建,該參數的作用類似printf中的格式字符串。syslog的其他參數要根據message字符串中printf風格的轉換控制符而定。此外,轉換控制符%m可用于插入與錯誤變量errno當前值對應的出錯消息字符串。這對于記錄錯誤消息很有用。
實驗syslog函數
在這個程序中,你試圖打開一個不存在的文件:

編譯并運行這個程序syslog.c,你沒有看到輸出,但是/var/log/messages文件尾現在有如下一行:

實驗解析
在這個程序中,你試圖打開一個不存在的文件。在文件打開失敗后,調用syslog在系統日志中記錄這一事件。
注意:日志信息并未指明是哪個程序調用了日志設施,它僅僅記錄syslog被調用以記錄一條信息的事實。%m轉換控制符被替換為一個錯誤描述,在本例中就是“文件沒有找到”。這比僅僅報告一個原始的錯誤碼更有用。
在頭文件syslog.h中還定義了一些能夠改變日志記錄行為的其他函數。它們是:

你可以通過調用openlog函數來改變日志信息的表示方式。它可以設置一個字符串ident,該字符串會添加在日志信息的前面。你可以通過它來指明是哪個程序創(chuàng)建了這條信息。facility參數記錄一個將被用于后續(xù)syslog調用的默認設施值,其默認值是LOG_USER。logopt參數對后續(xù)syslog調用的行為進行配置,它是0個或多個表4-7中參數的按位或。
表4-7

openlog函數會分配并打開一個文件描述符,并通過它來寫日志。你可以調用closelog函數來關閉它。注意,在調用syslog之前無需調用openlog,因為syslog會根據需要自行打開日志設施。
你可以使用setlogmask函數來設置一個日志掩碼,并通過它來控制日志信息的優(yōu)先級。優(yōu)先級未在日志掩碼中置位的后續(xù)syslog調用都將被丟棄。所以你可以通過這個方法關閉LOG_DEBUG消息而不用改變程序主體。
你可以用LOG_MASK(priority)為日志信息創(chuàng)建一個掩碼,它的作用是創(chuàng)建一個只包含一個優(yōu)先級的掩碼。你還可以用LOG_UPTO(priority)來創(chuàng)建一個由指定優(yōu)先級之上的所有優(yōu)先級(包括指定優(yōu)先級)構成的掩碼。
實驗logmask程序
在本例中,你將看到日志掩碼的作用:

這個logmask.c程序沒有輸出,但是在一個典型的Linux系統中,在/var/log/messages文件尾,你會看到如下信息:

接收調試日志信息的文件(根據日志配置而定,通常是/var/log/debug,有時也可能是/var/log/messages)會包含如下信息:

實驗解析
這個程序用它自己的名字logmask初始化日志設施,并要求日志信息中包含進程標識符。一般信息記錄到文件/var/log/messages中,調試信息記錄到文件/var/log/debug中。第二條調試信息沒有出現,這是因為你調用setlogmask忽略了優(yōu)先級低于LOG_NOTICE的所有信息(注意,這種做法在早期Linux內核中可能不支持)。
如果你的Linux安裝沒有啟用調試信息日志記錄功能,或者采用的是其他配置情況,你可能看不到調試信息。要啟用所有的調試信息,請查看系統中針對syslog或syslog-ng的文檔以找到正確的配置方法。
logmask.c還用到了getpid函數,它和與其緊密相關的getppid函數的定義如下所示:

這兩個函數分別返回調用進程和調用進程的父進程的進程標識符(PID)。要了解PID的更多內容,請參考第11章的內容。
- 深度實踐OpenStack:基于Python的OpenStack組件開發(fā)
- C語言程序設計教程
- Java完全自學教程
- 信息可視化的藝術:信息可視化在英國
- Spring Boot+Spring Cloud+Vue+Element項目實戰(zhàn):手把手教你開發(fā)權限管理系統
- Neo4j Essentials
- Gradle for Android
- 零基礎入門學習Python(第2版)
- PLC應用技術(三菱FX2N系列)
- 執(zhí)劍而舞:用代碼創(chuàng)作藝術
- 創(chuàng)意UI:Photoshop玩轉APP設計
- Natural Language Processing with Python Quick Start Guide
- Software Architecture with Python
- Java語言程序設計實用教程(第2版)
- AI輔助編程Python實戰(zhàn):基于GitHub Copilot和ChatGPT