linux下C語言編程打印syslog日誌

前言

       Linux的日誌系統一直以來都是在linux上開發必學的一部分內容。之前在學習OpenStack的時候,在對openstack組件的發生的錯誤進行調試時,老師就說要多看日誌的報錯,從這裏找到相關線索再去修改配置文件。結果很多的報錯都是通過組件對應的日誌文件反映出來而修改成功的,因此使用好linux日誌系統對了解linux編程有很大的幫助。

日誌文件簡述

其中日誌一般都在/var/log目錄下。該目錄下有以下幾個重要的的日誌文件。
       /var/log/maillog:記錄郵件的往來信息,其實主要是記錄sendmail與dovecot所產生的信息。
       /var/log/dmesg:記錄開機開始到現在的內核檢測過程所產生的各項信息。如果內核編程的模塊中使用printk(),將會把相關信息打印到這裏。
       /var/log/messages:系統發生的重要信息或者是錯誤信息都會記錄在這個文件中,如果系統發生錯誤,這個文件就是需要查閱的文件之一。
       /var/log/httpd:這個文件裏面主要記錄各種網絡服務信息。
       /var/log/cron:這個日誌跟例行工作調度有關。即crontab有沒有被執行,執行過程中有沒有發生錯誤,在這個日子中均有體現。

打印日誌文件

上述的這些日誌都是系統進程打印出的log日誌。我們怎麼能打印出自己的log日誌呢?
首先,我們要分清楚需求是什麼,是通過內核打印出來?還是非內核應用中打印出來?

1.內核打印日誌

相信很多使用過內核模塊的朋友已經很清楚,在linux內核模塊中編程的話,使用簡單的 printk("helloworld");就能達到打印日誌的效果。下述是一個使用LSM的linux內核模塊的部分代碼,在對模塊進行加載後,每一次動作的觸發,都會在  /var/log/dmesg 文件中打印出相應的日誌信息。
  1. #include<linux/security.h>  
  2. #include<linux/sysctl.h>  
  3. static unsigned long long count = 0;  
  4. int task_create_hook(unsigned long clone_flags)  
  5.   {  
  6.     printk("[+geek] call task_create(). count=%llu\n", ++count);      
  7.     return 0;  
  8.   }  
  9.     
  10.   static struct security_operations geek_ops = {  
  11.     .name = "geek",  
  12.     .task_create = task_create_hook,  
  13.   };  
  14.     
  15. static __init int geek_init(void)  
  16.   {  
  17.     printk("[+geek] loading...\n");   
  18.     if(register_security(&geek_ops)){  
  19.         printk("[+geek] register faild\n");   
  20.     }  
  21.     return 0;  
  22.   }  
  23.     
  24. security_initcall(geek_init);  

在linux中使用dmesg命令即可查看內核輸出的日誌。

2.非內核編程打印日誌

若想在非內核的環境下打印日誌,就必須要使用syslog這樣一個工具了(需要提醒的是ubuntu版本和Red Hat版本有很大區別,ubuntu使用的依舊是syslog,而Redhat和centos等版本則使用rsyslog替換掉系統自帶的syslog)。因此我們分兩部分對部分日誌進行分析。
syslog
若你的系統還是使用的syslog,那就直接運行以下測試代碼即可。
  1. #include <syslog.h>  
  2. int main(int argc, char **argv)  
  3. {  
  4.     openlog("MyMsgMARK", LOG_CONS | LOG_PID, 0);  
  5.     syslog(LOG_DEBUG,  
  6.            "This is a syslog test message generated by program '%s'\n",  
  7.            argv[0]);  
  8.     closelog();  
  9.     return 0;  
  10. }  

編譯生成可執行程序後,運行一次程序將向/var/log/syslog文件添加一行信息如下:

1
   Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program './a.out'

   Feb 12 08:48:38 localhost MyMsgMARK[7085]: This is a syslog test message generated by program './a.out'

可以看到的是,此程序導入了syslog庫函數,使用了syslog函數向syslog文件輸出日誌,第一個參數是消息的緊急級別,第二個參數是消息的格式,之後是格式對應的參數。就是printf函數一樣使用。。其中,syslog文件過大後,系統就會把文件分割並壓縮,如下圖所示。


如果我們的程序要使用系統日誌功能,只需要在程序啓動時使用openlog函數來連接syslogd程序,後面隨時用syslog函數寫日誌就行了。
還需要提醒的是,大家如果想刪除日誌,千萬不要把日誌文件直接刪除,如果這樣很有可能系統找不到文件,就無法再打印日誌,恢復起來也是比較麻煩。直接清空日誌內容即可  cat /dev/null > syslog  

rsyslog

如果上述方法無法打印syslog,很有可能你的系統已經把rsyslog替換了過去,這樣,如果想要打印自己的日誌,就需要先對rsyslog配置文件進行修改。
打開  /etc/rsyslog.conf
在最後寫下自己日誌的文件名稱。
  1. #Mylog  
  2. local2.* /var/log/mylog  
修改完保存後重啓rsyslog服務     :/etc/init.d/rsyslog restart    或service rsyslog restart  或systemctl restart rsyslog

接下來就開始編寫一個小的測試方法來驗證一下。

  1. #include <syslog.h>  
  2. int main(int argc, char **argv)  
  3. {  
  4.     openlog("MyLog", LOG_CONS | LOG_PID, LOG_LOCAL2);  
  5.     syslog(LOG_INFO,  
  6.            "This is a syslog test message generated by program '%s'\n",  
  7.            argv[0]);  
  8.     closelog();  
  9.     return 0;  
  10. }  
編譯運行上述代碼後,就會在 /var/log 目錄下多出一個mylog文件

不出什麼問題的話,裏面的內容應該是LOG_INFO,This is a syslog test message generated by program ./ 。
到現在,我所瞭解的linux 下c語言編程所能打印日誌的方法已經闡述完畢。希望跟大家多多交流。

轉載自:http://blog.csdn.net/ls7011846/article/details/52626952
發佈了37 篇原創文章 · 獲贊 24 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章