Unix/Linux syslogd守護進程 & 日志記錄syslog


1. syslogd守護進程

我們知道, 守護進程(daemon)是

在后台運行且不與任何控制終端關聯的進程.

參見: Linux 系統編程學習筆記 - 終端、作業控制與守護進程 守護進程章節.

那么如何得知守護進程的狀態, 和某些事情發生呢?守護進程如何輸出消息, 或者告知管理員?
可以調用syslog函數輸出這些消息, 函數把消息發送給syslogd守護進程, 而syslogd守護進程可以將消息寫入同一個文件或者發送至另一個主機, 方便系統管理人員查看.

1.1 BSD syslog組織結構:


有以下3種產生日志消息的方法:
1)內核例程調用log函數
任何一個用戶進程都可以通過open, read /dev/klog設備來讀取這些消息. 不過, 編寫內核例程時, 才會用到.

2)大多數用戶進程(守護進程)調用syslog(3)函數來產生日志消息
3)本機上的用戶進程, 或者網絡上的用戶進程, 都可以通過TCP/IP網絡連接到此主機, 可將日志消息發向UDP port 514.
syslog函數本身不會產生UDP數據報, 而是要求產生此日志消息的進程進行顯式的網絡編程.

1.2 syslogd守護進程的啟動

syslond守護進程是由某個系統初始化腳本啟動, 而且在系統工作期間一直運行.
源自Berkeley的syslogd的啟動實現步驟:
1)讀取配置文件
通常為/ect/syslog.conf 的配置文件指定本守護進程可能收取的各種日志消息(log message)應該如何處理. 這些消息可能被添加到一個文件(特例/dev/console), 或被寫到指定用戶的登錄窗口(若該用戶已登錄到本守護進程所在系統中), 或被轉發給另一個主機上的syslogd進程.

2)創建一個Unix Domain數據報套接字, 給他捆綁路徑名/var/run/log(某些系統是/dev/log)

3)創建一個UDP套接字, 捆綁端口514(syslog服務使用端口號)

4)打開路徑名/dev/klog
來自內核中的任何出錯消息看着像是這個設備的輸入.

5)此后, syslogd守護進程在一個無限循環中運行: 調用select以等待它的3個描述符(來自上面的1),2),3))之一可讀, 讀入日志消息, 並按照配置文件進行處理. 如果守護進程收到SIGHUP信號, 那么就重新讀取配置文件.

注意: 較新的syslogd實現禁止創建UDP套接字, 除非管理員明確要求. 理由: 允許任何進程往該套接字發送UDP數據報, 會讓系統易遭拒絕服務攻擊, 其文件系統可能被填滿, 而合法進程的日志消息可能被排擠掉.


2. 日志記錄函數

2.1 syslog

守護進程沒有控制終端, 不能打印消息到stdout, stderr. 用戶進程從syslogd守護進程中登記消息的常用方法是調用syslog函數.
調用syslog產生一個日志消息.

#include <syslog.h>

void syslog(int priority, const char *format, ...);
  • 參數
    priority 是facility和level的組合. level見下表, facility見openlog的facility.

syslog的level:

level 說明
LOG_EMERG 緊急(系統不可使用)(最高優先級)
LOG_ALERT 必須立即修復的情況
LOG_CRIT 嚴重情況(如硬件設備出錯)
LOG_ERR 出錯情況
LOG_WARNING 警告情況
LOG_NOTICE 正常但重要的情況
LOG_INFO 信息性消息
LOG_DEBUG 調試消息(最低優先級)

2.2 openlog, closelog

#include <syslog.h>

void openlog(const char *ident, int option, int facility);
void closelog(void);
void vsyslog(int priority, const char *format, va_list ap);

openlog 可選調用, 如果不調用openlog, 則在第一次調用syslong時, 自動調用openlog. openlog可以在首次調用syslog前調用.
closelog 可選調用, 因為它只是關閉曾被用於與syslogd守護進程進行通信的描述符. 這些描述符在進程正常終止以后, 也會自動關閉. closelog可以在應用進程不再需要發送日志消息時調用, 以關閉與syslogd通信的描述符.

  • 參數
    options 調用openlog時, 通常不立即創建Unixo Domain socket, 而該socket到首次調用syslog時才打開. openlog的options能影響log的行為, 如指定LOG_NDELAY選項將迫使該socket在openlog調用后立即創建, 而不是到調用syslog時才創建.
    openlog的options由一個或多個常值的構成(邏輯或):
options 說明
LOG_CONS 若無法發送到syslogd守護進程則登記到控制台
LOG_NDELAY 不延遲打開, 立即創建套接字
LOG_PERROR 既發送到syslogd守護進程, 又登記到標准錯誤輸出
LOG_PID 隨每個日志消息登記進程ID

facility 設施, 標識消息發送進程的類型, 來自不同設施的消息將以不同的方式進行處理. openlog的facility參數, 為沒有指定設施的后續syslog調用指定一個默認值, i.e. openlog如果指定了facility, syslog可不必另外指定facility.

facility XSI 說明
LOG_AUDIT 審計設施
LOG_AUTH 授權程序: login, su, getty等
LOG_AUTHPRIV 與LOG_AUTH相同, 但寫日志文件時具有權限限制
LOG_CONSOLE 消息寫入 /dev/console
LOG_CRON cron和at
LOG_DAEMON 系統守護進程: inetd, routed等
LOG_FTP FTP守護進程(ftpd)
LOG_KERN 內核產生的消息
LOG_LOCAL0 保留本地使用
LOG_LOCAL1 保留本地使用
LOG_LOCAL2 保留本地使用
LOG_LOCAL3 保留本地使用
LOG_LOCAL4 保留本地使用
LOG_LOCAL5 保留本地使用
LOG_LOCAL6 保留本地使用
LOG_LOCAL7 保留本地使用
LOG_LPR 行式打印機系統: lpd, lpc等
LOG_MAIL 郵件系統
LOG_NEWS Usenet網絡新聞系統
LOG_NTP 網絡時間協議系統
LOG_SECURITY 安全子系統
LOG_SYSLOG syslogd守護進程本身
LOG_USER 來自其他用戶進程的消息(默認)
LOG_UUCP UUCP系統

3. syslog文件

3.1 syslog文件存放位置

Linux下調用syslog函數輸出的消息就放在syslog文件, 存放在/var/log/syslog. syslog文件, 通常用於存放應用程序(守護進程)警告信息.
其他日志存放位置, 詳見: linux系統各種日志存儲路徑和詳細介紹 | 博客園

3.2 手動刪除syslog文件

步驟:

  1. 刪除syslog文件
    到/var/log/目錄下rm文件
$ cd /var/log 
$ rm -f syslog  # 需要root權限
  1. 重啟syslog服務
$ service syslog restart

參見: [LINUX]手動清理syslog | CSDN


4. 例程

同時向控制台和syslog輸出包含PID的進度信息, 1秒鍾更新10%, 到100%為止.

#include <syslog.h>
#include <unistd.h>
#include <stdio.h>

/**
 * linux下syslog存放位置 : /var/log/syslog
 */
int main()
{
    int i;
    puts("hello");

    /* LOG_CONS: 若無法發送到syslogd守護進程則登記到控制台; 
    LOG_PID: 隨每個日志消息登記進程PID;
    LOG_PERROR: 既發送到syslogd守護進程,也發送到stderr;
    LOG_USER: 任意的用戶級消息(默認) */
    openlog("mysyslog", LOG_CONS | LOG_PID |  LOG_PERROR, LOG_USER);
    syslog(LOG_INFO, "system is starting..." );
    
    for (i = 0; i < 10; ++i) {
        
        syslog(LOG_WARNING | LOG_USER, "process %d\n", (i + 1) * 10);
        sleep(1);
    }
    
    closelog();
    return 0;
}

控制台輸出結果:

$ ./a.out 
hello
mysyslog[26710]: system is starting...
mysyslog[26710]: process 10
mysyslog[26710]: process 20
mysyslog[26710]: process 30
mysyslog[26710]: process 40
mysyslog[26710]: process 50
mysyslog[26710]: process 60
mysyslog[26710]: process 70
mysyslog[26710]: process 80
mysyslog[26710]: process 90
mysyslog[26710]: process 100

syslog輸出結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM