1. 程式人生 > 其它 >syslog程序與日誌輸出

syslog程序與日誌輸出

技術標籤:# C++

守護程序: 在後臺執行而且不和任何控制終端關聯的程序

syslogd守護程序

Unix系統中的syslogd守護程序通常由某個系統初始化指令碼啟動,而且在系統工作期間一直執行。 源自Berkeleysyslogd實現在啟動時執行以下步驟

(1) 讀取配置檔案

  • /etc/syslog.conf指定本守護程序可能收取的各種日誌資訊應該如何處理
  • 這些訊息可能被新增到一個檔案(/dev/console檔案是一個特例,它把訊息寫到控制檯上),或者被寫到指定使用者的登入視窗(如果該使用者已經登入到本守護程序所在系統中),或者被轉發給另一個主機上的syslogd程序

CentOS6.5之前,配置檔案為/etc/syslog.conf,從CentOS6.5之後,配置檔名變更為/etc/rsyslog.conf

  • 該檔案由不同程式或訊息分類的單個條目組成,每個佔一行。對每類訊息提供一個選擇域和一個動作域。這些域由tab隔開
    • 選擇域指明訊息的型別和優先順序;
    • 動作域指明syslogd接收到一個與選擇標準相匹配的訊息時所執行的動作。

每個選項是由裝置和優先順序組成。當指明一個優先順序時,syslogd將紀錄一個擁有相同或更高優先順序的訊息。所以如果指明"crit",那所有標為crit、alert和emerg的訊息將被紀錄。每行的行動域指明當選擇域選擇了一個給定訊息後應該把他傳送到哪兒。

格式為:

​ 型別.級別;型別.級別 [TAB] 動作

  • 保留欄位中的“型別(facility)”代表資訊產生的源頭,可以是:
    • auth 認證系統,即詢問使用者名稱和口令
    • cron 系統定時系統執行定時任務時發出的資訊
    • daemon 某些系統的守護程式的syslog,如由in.ftpd產生的log
    • kern 核心的syslog資訊
    • lpr 印表機的syslog資訊
    • mail 郵件系統的syslog資訊
    • mark 定時傳送訊息的時標程式
    • news 新聞系統的syslog資訊
    • user 本地使用者應用程式的syslog資訊
    • uucp uucp子系統的syslog資訊
    • local0…7 種本地型別的syslog資訊,這些資訊可以又使用者來定義
    • * 代表以上各種裝置
  • 保留欄位中的“級別”代表資訊的重要性,可以是:
    • emerg 緊急,處於Panic狀態。通常應廣播到所有使用者;
    • alert 告警,當前狀態必須立即進行糾正。例如,系統資料庫崩潰;
    • crit 關鍵狀態的警告。例如,硬體故障;
    • err 其它錯誤;
    • warning 警告;
    • notice 注意;非錯誤狀態的報告,但應特別處理;
    • info 通報資訊;
    • debug 除錯程式時的資訊;
    • none 通常除錯程式時用,指示帶有none級別的型別產生的資訊無需送出。如*.debug;mail.none表示除錯時除郵件資訊外其它資訊都送出。
  • “動作”(action)域指示資訊傳送的目的地。可以是:
    • /filename 日誌檔案。由絕對路徑指出的檔名,此檔案必須事先建立;
    • @host 遠端主機; @符號後面可以是ip,也可以是域名,預設在/etc/hosts檔案下loghost這個別名已經指定給了本機。
    • user1,user2 指定使用者。如果指定使用者已登入,那麼他們將收到資訊;
    • * 所有使用者。所有已登入的使用者都將收到資訊。
$ cat /etc/rsyslog.conf
# ​ 型別.級別;型別.級別    [TAB]     動作
*.err;kern.debug;daemon.notice;mail.crit    [TAB]   /var/adm/messages 

這行中的“action”就是我們常關心的那個/var/adm/messages檔案,輸出到它的資訊源頭“selector”是:
*.err - 所有的一般錯誤資訊;

  • kern.debug - 核心產生的除錯資訊;
  • daemon.notice - 守護程序的注意資訊;
  • mail.crit - 郵件系統的關鍵警告資訊

例如,如果想把所有郵件訊息紀錄到一個檔案中,如下:

#Log all the mail messages in one place
mail.* /var/log/maillog

其他裝置也有自己的日誌。UUCP和news裝置能產生許多外部訊息。它把這些訊息存到自己的日誌(/var/log/spooler)中並把級別限為"err"或更高。例如:

# Save mail and news errors of level err and higher in aspecial file. 
uucp,news.crit /var/log/spooler

(2)建立一個Unix資料報套接字,給它捆綁路徑名/var/run/log或者/dev/log
(3) 建立一個UDB套接字,捆綁514埠
(4)開啟路徑名/dev/log。來自核心中的任何出錯作為=訊息

syslog

理論

既然守護程序沒有控制終端,它們就不能把訊息fprintfstderr上。從守護程序中登記訊息使用syslog

#include <syslog.h> //標頭檔案
void openlog (char*ident, int option, int facility);
void syslog(int priority, char*format,……);
void closelog();

呼叫openlog是可選擇的。如果不呼叫openlog,則在第一次呼叫syslog時,自動呼叫openlog。呼叫closelog也是可選擇的,它只是關閉被用於與syslog守護程序通訊的描述符。

openlog 函式中:
(1)第一個引數ident將是一個標記,ident所表示的字串將固定地加在每行日誌的前面以標識這個日誌,通常就寫成當前程式的名稱以作標記。

(2)第二個引數option是下列值取|運算的結果:

  • LOG_CONS : 如果送到system logger時發生問題,直接寫入系統console。
  • LOG_NDELAY : 立即開啟連線(通常,連線是在第一次寫入訊息時才打開的)。
  • LOG_PERROR : 將訊息也同時送到stderr
  • LOG_PID : 將PID含入所有訊息中

(3)第三個引數facility是用來指定記錄訊息程式的型別。它讓指定的配置檔案,將以不同的方式來處理來自不同方式的訊息。

  • LOG_AUTH ——認證系統:login、su、getty等
  • LOG_AUTHPRIV ——同LOG_AUTH,但只登入到所選擇的單個使用者可讀的檔案中
  • LOG_CRON ——cron守護程序
  • LOG_DAEMON ——其他系統守護程序,如routed
  • LOG_FTP ——檔案傳輸協議:ftpd、tftpd
  • LOG_KERN ——核心產生的訊息
  • LOG_LPR ——系統印表機緩衝池:lpr、lpd
  • LOG_MAIL ——電子郵件系統
  • LOG_NEWS ——網路新聞系統
  • LOG_SYSLOG ——由syslogd(8)產生的內部訊息
  • LOG_USER ——隨機使用者程序產生的訊息
  • LOG_UUCP ——UUCP子系統
  • LOG_LOCAL0~LOG_LOCAL7 ——為本地使用保留

syslog函式中
(1)priority是level(級別) + facility(設定)的組合
level如下:

  • LOG_EMERG——緊急情況
  • LOG_ALERT——應該被立即改正的問題,如系統資料庫破壞
  • LOG_CRIT——重要情況,如硬碟錯誤
  • LOG_ERR——錯誤
  • LOG_WARNING——警告資訊
  • LOG_NOTICE——不是錯誤情況,但是可能需要處理
  • LOG_INFO——情報資訊
  • LOG_DEBUG——包含情報的資訊,通常旨在除錯一個程式時使用

實踐

#include <syslog.h>

int main(int argc, char **argv) {
    openlog("zooyo", LOG_CONS | LOG_PID, 0);
    syslog(LOG_INFO,
           "This is a syslog test message generated by program %sn",
           argv[0]);
    closelog();
    return 0;
}

編譯執行,然後檢視

cat /var/log/messages

在這裡插入圖片描述

#include<stdio.h>
#include<stdlib.h>
#include <syslog.h>
#define SYSNAME "wohawoha"
void Info(void)
{
 openlog("info",LOG_PID,LOG_LOCAL5);/*注意這裡的數字5與第一條裡面提到的local5.*裡的5必須相同,並且這個數字的範圍為0--7*/
 syslog(LOG_INFO, "hello %s","woring");
}

void Woring(void)
{
 openlog("woring",LOG_PID,LOG_LOCAL5);
 syslog(LOG_WARNING, "hello %s","test");
}

int main()
{
 Info();
 Woring();
 closelog();
 return 0;
}