linux下的守護進程(daemon)和系統日誌(syslog)

  • 守護進程daemon

Unix/Linux中的守護進程(Daemon)類似於Windows中的後臺服務進程,一直在後臺長時間運行的進程。它通常在系統啓動後就運行,沒有控制終端,也無法和前臺的用戶交互,在系統關閉時才結束。Daemon程序一般都作爲服務程序使用,等待客戶端程序與它通信。我們也把運行的Daemon程序稱作守護進程。比如的網絡服務程序,可以在完成創建套接口,綁定套接口,設置套接口爲監聽模式後,變成守護進程進入後臺執行而不佔用控制終端,這是網絡服務程序的常用模式。UNIX下的網絡服務程序,如WebServer(Nginx、Apache等),FTP(vsftp),SSH(openssh)等一般都是由守護進程(Daemon)來實現的。守護進程不佔用終端,在後臺運行。UNIX的守護進程一般都命名爲 *d 的形式,如httpd,vsftpd,sshd等。守護進程一旦脫離了終端,退出就成了問題,這時需要使用 ps 命令查出進程ID然後再使用kill命令停止。

Linux系統專門提供了一個用來創建daemon進程的庫函數,該函數的原型是

#include <unistd.h>  //包含daemon頭文件

int daemon(int nochdir, int noclose);
  • 參數

  1. nochdir

指定是否要切換當前工作路徑到"/“根目錄,

    2.noclose

指定是否要關閉標準輸入、標準輸出和標準出錯(即重定向到/dev/null)。

  • 在創建守護進程的時候,往往需要將進程的工作目錄修改爲”/"根目錄,並將標準輸入、標準輸出和標準出錯關閉。所以這兩個參數我們一般都是傳0。

  • 編程示例

#ifndef __DAEMON_H__
#define __DAEMON_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <libgen.h>

#endif

int main (int argc, char *argv[])
{

    char          *progname  = basename(argv[0]);
    if ( daemon(1,1) < 0) //實行daemon
    {
        printf("Program daemon failure:%s\n", strerror(errno));
        return -1;
    }

    openlog("daemon",LOG_CONS | LOG_PID,0);
    syslog(LOG_NOTICE, "program '%s' start running\n",progname);
    syslog(LOG_WARNING, "program '%s' running with a warnning message\n", progname);
    syslog(LOG_EMERG, "program '%s' running with a emergency message\n",progname);
    while (1)
    {
        //do something;

    }
    syslog(LOG_NOTICE, "program '%s' stop running\n", progname);
    closelog();

        return 0;
}
              
  • 我們可以在使用以下命令來查看daemon程序的信息
 ps -aux |grep daemon

 

  • 如果想要kill daemon這個程序:
killall daemon 
  • 日誌系統syslog

syslog是一種工業標準的協議,可用來記錄設備的日誌。在UNIX系統,路由器、交換機等網絡設備中,系統日誌(System Log)記錄系統中任何時間發生的大小事件。管理者可以通過查看系統記錄,隨時掌握系統狀況。UNIX的系統日誌是通過syslogd這個進程記錄系統有關事件記錄,也可以記錄應用程序運作事件。通過適當的配置,我們還可以實現運行syslog協議的機器間通信,通過分析這些網絡行爲日誌,藉以追蹤掌握與設備和網絡有關的狀況。

  • 函數原型:

#include <syslog.h>      //需要包含頭文件
void openlog(const char *ident, int option, int facility);  //打開系統日誌
void syslog(int priority, const char *format, ...);         //寫入日誌系統
void closelog(void);                                         //關閉日誌系統
  • openlog函數及其參數說明 (打開系統日誌)

  • 參數說明:

1、ident:

     是一個標記,ident 所表示的字符串將固定的加在每行日誌的前面一標識這個日誌,通常就寫成當前程序的名稱以作標記。

 2、option:

    指定openlog函數和接下來調用的syslog函數的控制標誌

option 說明
LOG_CONS 如果將信息發送給 syslogd 守護進程時發生錯誤,直接將相關信息輸出到終端
LOG_NDELAY 立即打開與系統日誌的連接(通常情況下,只有在產生第一條日誌信息的情況下才會打開與日誌系統的連接)
LOG_ODELAY 類似於 LOG_NDELAY 參數,與系統日誌的連接只有在 syslog 函數調用時纔會創建

LOG_PERROR

在將信息寫入日誌的同時,將信息發送到標準錯誤輸出
LOG_PID 每條日誌信息中都包含進程號

 3、facility:

指定記錄消息程序的類型,與 syslogd 守護進程的配置文件 syslog.conf 中的 facility 對應。

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函數及其參數說明 (寫入日誌,與文件系統調用 printf使用方法類似,但在前面指定日誌級別。)

  • 參數說明

  • priority:

表示消息的級別,與 syslogd 守護進程的配置文件 syslog.conf 中的 level 對應。

LOG_EMERG 緊急情況
LOG_ALERT 應該被立即改正的問題,如系統數據庫破壞
LOG_CRIT 重要情況,如硬盤錯誤
LOG_ERR 錯誤
LOG_WARNING 警告信息
LOG_NOTICE 不是錯誤情況,但是可能需要處理
LOG_INFO 情報錯誤
LOG_DEBUG 包含情報的信息,通常指在調試一個程序時使用
  • closelog函數(關閉當前打開日誌系統)

函數說明:關閉日誌設備,與文件系統調用的close類似;調用closelog也是可選擇的,它只是關閉被用於與syslog守護進程通信的描述符。

  • 編程示例

#ifndef __DAEMON_H__
#define __DAEMON_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <libgen.h>

#endif

int main (int argc, char *argv[])
{

    char          *progname  = basename(argv[0]);
    if( daemon(1,1) < 0)
    {
        printf("Program daemon failure:%s\n", strerror(errno));
        return -1;
    }

    openlog("daemon",LOG_CONS | LOG_PID,0);   //打開日誌系統
    syslog(LOG_NOTICE, "program '%s' start running\n",progname);   //寫入日誌信息
    syslog(LOG_WARNING, "program '%s' running with a warnning message\n", progname);
    syslog(LOG_EMERG, "program '%s' running with a emergency message\n",progname);
    while (1)
    {
        //do something;

    }
    syslog(LOG_NOTICE, "program '%s' stop running\n", progname);
    closelog();  //關閉日誌系統

        return 0;
}
              

 

  • 我們可以在使用以下命令來查看寫入到系統日誌的信息,
vim /var/log/syslog
  • 運行程序寫入日誌系統的內容(由於Linux 實行的時日誌回滾系統,我們寫入的信息一般在最後)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章