聲明:本文僅限于簡書發(fā)布扔役,其他第三方網(wǎng)站均為盜版番枚,原文地址: Python syslog 淺談
最近在寫一些命令行守護程序,類似于 Linux 下的一些常運行的程序深啤,除了用到一些常見的IO 以及進程間通信的內容之外溯街,還嘗試了一下 Unix 系列的 syslog洋丐,在嘗試過程中,發(fā)現(xiàn) Python 已經(jīng)在 logging 模塊中很方便得集成了 syslog 的功能堤尾,很是方便郭宝;但同時掷漱,Python 的內置庫中也提供了 syslog 的支持卜范,所以,我就對這兩種方式都進行一個介紹和總結缰冤。
syslog
開始之前想說說什么是 syslog喳魏,在 Linux 中刺彩,有很多后臺程序都是以后臺進程的形式存在運行,例如 crontab/sshd/nginx 等嗡害,有些是系統(tǒng)的畦攘,有些是我們自己添加的知押,但是鹃骂,他們都有一些相同的特點:
- 我們不能直接從標準輸入給他們輸入畏线,也不能直接從標準輸出獲得他們的輸出
- 他們通常在固定的位置有日志可以查看良价,這個位置通常在 /var/log
- ... ...
對于其中的第 2 個特點明垢,大部分 Linux 后臺進程都通過 syslog 來實現(xiàn)。因為服務器中很多進程的調試和維護都需要一個穩(wěn)定專業(yè)的日志系統(tǒng)抵蚊,因此,Linux 提供了一個守護進程專門用來處理系統(tǒng)日志粘姜,而這個守護進程就是 syslogd孤紧,不過,現(xiàn)在的系統(tǒng)大都使用 rsyslod(syslog 升級版) 代替臭猜。例如以下是我在一臺 Ubuntu16 的機器上的 syslogd 進程:
有一點值得一提的是蔑歌,無論是內核還是用戶態(tài)次屠,都可以使用 syslog雳刺,只不過他們的路徑不一樣
- 用戶態(tài):我們調用 syslog 生成日子掖桦,然后這個函數(shù)將日志輸出到一個 UNIX域套接字類型的文件 /dev/log 中,然后 rsyslogd 監(jiān)聽這個文件來獲取日志
- 內核態(tài)[2]:內核日志通過調用 printk 等函數(shù)打印到內核的環(huán)狀緩存中涌穆,然后這個緩存的內容和文件 /proc/kmsg 是直接映射的,所以 rsyslogd 就可以直接讀取這個文件獲得日志了
syslog 日志的位置
rsyslogd 在接收到日志之后朱监,需要將日志輸出到特定的日志文件中赫编,默認情況下
- 調試信息會保存到 /var/log/debug 文件中
- 普通信息會保存到 /var/log/messages 文件中
- 內核消息會保存到 /var/log/kern.log 文件中
但是這些都是可以改變的奋隶,在我的系統(tǒng)中唯欣,配置文件的位置是 /etc/rsyslog.conf,因為我沒準備修改這些配置蟀拷,所以就沒有研究配置信息问芬,有需要可以參考資料[3]寿桨。
內置 syslog 庫
在 Python 中亭螟,直接就有內置的函數(shù)庫可以使用 syslog挡鞍,一段很簡單的代碼如下:
就可以在 /var/log/syslog 中看到這個內容了:
我們還可以加上日志級別:
然而,我們會發(fā)現(xiàn)预烙,這些日志有些簡單墨微,例如我們不知道是哪個進程打出來的,這個時候扁掸,還有一個函數(shù)值得我們一試欢嘿,那就是 openlog
然后再看看我們的日志輸出:
可以看到,這些設置都不是那么好用也糊,畢竟是比較底層的接口炼蹦,所以我們來嘗試一下高層一點的狸剃。
與 logging 模塊結合
我們查閱一下 Python 文檔中的 logging 模塊的文檔掐隐,可以發(fā)現(xiàn)又一個 handler 叫做:SysLogHandler,看一下參數(shù),并不比 syslog 的原始函數(shù)簡單虑省,但是匿刮,我們可以忽略所有這些參數(shù),而簡單得控制日志輸出:
class logging.handlers.SysLogHandler(address=(‘localhost’, SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)
- address: 前面說了 rsyslog 是一個套接字探颈,這里可以制定套接字的地址熟丸,注意:這個可以是不在同一臺機器
- facility:這個參數(shù)的作用是告訴 rsyslog 日志的類型,從而可以讓他根據(jù)不同的類型執(zhí)行不同的操作
- socktype:這個不用多解釋了
所以使用的話就和其他的 Handler 一致伪节,簡單得記一下:
這里的 address 用的是 /dev/log光羞,因為我查看了一下我機器上是沒有開放 514 端口的,查了一下資料[5]發(fā)現(xiàn):/dev/log 是一個 Unix 套接字怀大,而我機器上并不開放所有機器可用的日志服務纱兑,所以使用 /dev/log 就好了。