一、源代碼說明
freecplus是一個Linux系統下的C/C++開源框架,源代碼請前往C語言技術網(www.freecplus.net)下載。
本文介紹的是freecplus框架中日誌文件操作的方法。
函數和類的聲明文件是freecplus/_freecplus.h。
函數和類的定義文件是freecplus/_freecplus.cpp。
示例程序位於freecplus/demo目錄中。
編譯規則文件是freecplus/demo/makefile。
二、日誌文件的意義
對於C/C++服務程序來說,程序運行在後臺,沒有操作界面,無人值守,程序運行的狀態、數據處理的日誌、程序的異常等必須記錄在日誌文件中,運維人員根據日誌文件的內容,查看程序運行和數據處理的情況。
三、CLogFile類
CLogFile類用於服務程序記錄程序的運行日誌。
1、類的聲明
// 日誌文件操作類
class CLogFile
{
public:
FILE *m_tracefp; // 日誌文件指針。
char m_filename[301]; // 日誌文件名,建議採用絕對路徑。
char m_openmode[11]; // 日誌文件的打開方式,一般採用"a+"。
bool m_bEnBuffer; // 寫入日誌時,是否啓用操作系統的緩衝機制,缺省不啓用。
long m_MaxLogSize; // 最大日誌文件的大小,單位M,缺省100M。
bool m_bBackup; // 是否自動切換,日誌文件大小超過m_MaxLogSize將自動切換,缺省啓用。
// MaxLogSize:最大日誌文件的大小,單位M,缺省100M,最小爲10M。
CLogFile(const long MaxLogSize=100);
// 打開日誌文件。
// filename:日誌文件名,建議採用絕對路徑,如果文件名中的目錄不存在,就先創建目錄。
// openmode:日誌文件的打開方式,與fopen庫函數打開文件的方式相同,缺省值是"a+"。
// bBackup:是否自動切換,true-切換,false-不切換,在多進程的服務程序中,如果多個進行共用一個日誌文件,bBackup必須爲false。
// bEnBuffer:是否啓用文件緩衝機制,true-啓用,false-不啓用,如果啓用緩衝區,那麼寫進日誌文件中的內容不會立即寫入文件,缺省是不啓用。
bool Open(const char *filename,const char *openmode=0,bool bBackup=true,bool bEnBuffer=false);
// 如果日誌文件大於100M,就把當前的日誌文件備份成歷史日誌文件,切換成功後清空當前日誌文件的內容。
// 備份後的文件會在日誌文件名後加上日期時間。
// 注意,在多進程的程序中,日誌文件不可切換,多線的程序中,日誌文件可以切換。
bool BackupLogFile();
// 把內容寫入日誌文件,fmt是可變參數,使用方法與printf庫函數相同。
// Write方法會寫入當前的時間,WriteEx方法不寫時間。
bool Write(const char *fmt,...);
bool WriteEx(const char *fmt,...);
// 關閉日誌文件
void Close();
~CLogFile(); // 析構函數會調用Close方法。
};
2、示例程序
示例(demo42.cpp)
/*
* 程序名:demo42.cpp,此程序演示採用freecplus框架的CLogFile類記錄程序的運行日誌。
* 本程序修改demo40.cpp把輸出的printf語句改爲寫日誌文件。
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include "../_freecplus.h"
int main()
{
CLogFile logfile;
// 打開日誌文件,如果"/tmp/log"不存在,就創建它,但是要確保當前用戶具備創建目錄的權限。
if (logfile.Open("/tmp/log/demo42.log")==false)
{ printf("logfile.Open(/tmp/log/demo42.log) failed.\n"); return -1; }
logfile.Write("demo42程序開始運行。\n");
CDir Dir;
// 掃描/tmp/data目錄下文件名匹配"surfdata_*.xml"的文件。
if (Dir.OpenDir("/tmp/data","surfdata_*.xml")==false)
{ logfile.Write("Dir.OpenDir(/tmp/data) failed.\n"); return -1; }
CFile File;
while (Dir.ReadDir()==true)
{
logfile.Write("處理文件%s...",Dir.m_FullFileName);
if (File.Open(Dir.m_FullFileName,"r")==false)
{ logfile.WriteEx("failed.File.Open(%s) failed.\n",Dir.m_FullFileName); return -1; }
// 這裏可以插入讀取數據文件的內容、解析xml字符串並把數據寫入數據庫的代碼。
// 讀取文本數據用Fgets和FFGETS方法,讀取二進制數據用Fread方法。
// 具體的代碼我就不寫了。
// 處理完文件中的數據後,關閉文件指針,並刪除文件。
File.CloseAndRemove();
logfile.WriteEx("ok\n");
}
logfile.Write("demo42程序運行結束。\n");
}
先運行demo39程序,在/tmp/data目錄中生成幾個數據文件,然後運行demo42,將生成日誌文件/tmp/log/demo42.log,內容如下:
3、日誌文件的切換
我們通過一個示例程序的演示日誌文件的切換功能,往日誌文件中寫入一千萬數據,讓它產生切換。
示例(demo43.cpp)
/*
* 程序名:demo43.cpp,此程序演示freecplus框架的CLogFile類的日誌文件的切換。
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include "../_freecplus.h"
int main()
{
CLogFile logfile;
// 打開日誌文件,如果"/tmp/log"不存在,就創建它,但是要確保當前用戶具備創建目錄的權限。
if (logfile.Open("/tmp/log/demo43.log")==false)
{ printf("logfile.Open(/tmp/log/demo43.log) failed.\n"); return -1; }
logfile.Write("demo43程序開始運行。\n");
// 讓程序循環10000000,生成足夠大的日誌。
for (int ii=0;ii<10000000;ii++)
{
logfile.Write("本程序演示日誌文件的切換,這是第%010%d條記錄。\n",ii);
}
logfile.Write("demo43程序運行結束。\n");
}
運行demo43,將在/tmp/log目錄中產生一批日誌文件,用ls -l /tmp/log查看如下:
四、版權聲明
C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!