VC-Logger 是一個簡單易用的 C++ 程式通用日誌組件。設計時著重考慮三個方面:功能、可用性和效能。為了讓大家能更方便的學習 VC-Logger,特此精心製作了幾個測試案例:TestGUILogger(GUI 版本測試案例 / 靜態載入)、TestDynamicLogger(GUI 版本測試案例 / 動態載入)、TestConsoleLogger(Console 版本測試案例 / 靜態載入)。
(項目首頁:http://www.jessma.org,:http://www.oschina.net/p/vc-logger)
功能: 本日誌組件的目的是滿足大多數應用程式記錄日誌的需求 —— 把日誌輸出到檔案或發送到應用程式中,並不提供一些複雜但不常用的功能。本日誌組件的功能包括:
- 把日誌資訊輸出到指定檔案
- 每日產生一個記錄檔
- 對於 GUI 程式,可以把日誌資訊發送到指定視窗
- 對於Console應用程式,可以把日誌資訊發往標準輸出 (std::cout)
- 支援 MBCS / UNICODE,Console / GUI 程式
- 支援動態載入和靜態載入日誌組件 DLL
- 支援 DEBUG/TRACE/INFO/WARN/ERROR/FATAL 等多個記錄層級
可用性: 本日誌組件著重考慮了可用性,盡量讓使用者用起來覺得簡便、舒心:
- 簡單純淨:不依賴任何程式庫或架構
- 使用介面簡單,不需複雜的配置或設定工作
- 提供 CStaticLogger 和 CDynamicLogger 封裝類用於靜態或動態載入以及動作記錄組件,使用者無 需關注載入細節
- 程式如果要記錄多個記錄檔只需為每個記錄檔建立相應的 CStaticLogger 或 CDynamicLogger 對象
- 只需調用 Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法記錄日誌
- 日誌記錄方法支援可變參數
- 日誌輸出格式:<時間> <線程ID> <記錄層級> <日誌內容>
效能: 效能是組件是否值得使用的硬指標,本組件從設計到編碼的過程都盡量考慮到效能最佳化:
- 支援多線程同時發送寫日誌請求
- 使用單獨線程在後台寫日誌,不影響背景工作執行緒的正常執行
- 採用批處理方式批量記錄日誌
*** 使用方法 ***
方法一:(靜態載入 Logger DLL)
--------------------------------------------------------------------------------------
- 應用程式套件組合含 StaticLogger.h 標頭檔
- 建立 CStaticLogger 對象(通常為全域對象)
- 調用 CStaticLogger->Init(...) 初始化日誌組件
- 使用 CStaticLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法寫日誌
- 調用 CStaticLogger->UnInit(...) 清理日誌組件(CStaticLogger 對象析構時也會自動清理日誌組件)
方法二:(動態載入 Logger DLL)
--------------------------------------------------------------------------------------
- 應用程式套件組合含 DynamicLogger.h 標頭檔
- 建立 CDynamicLogger 對象(通常為全域對象)
- 調用 CDynamicLogger->Init(...) 初始化日誌組件
- 使用 CDynamicLogger->Log()/Debug()/Trace()/Info()/Warn()/Error()/Fatal() 等方法寫日誌
- 調用 CDynamicLogger->UnInit(...) 清理日誌組件(CDynamicLogger 對象析構時也會自動清理日誌組件)
方法三:(直接用匯出函數載入 Logger DLL)
--------------------------------------------------------------------------------------
- 應用程式套件組合含 Logger.h 標頭檔
- 手工調用 ILoger_Create() 和 ILoger_Create() 匯出函數建立和銷毀 ILogger 對象
(註:如果是動態載入,需手工調用 ::LoadLibrary()/::FreeLibrary() 系列 API 函數載入和卸載 Logger DLL)
[
***** 對於希望通過視窗接收日誌資訊的 GUI 程式 *****
A. 日誌組件初始化成功後調用 SetGUIWindow(HWND) 設定收日誌的視窗
B. 視窗須響應處理 LOG_MESSAGE 訊息
C. 處理完 LOG_MESSAGE 訊息後,調用 ILogger::FreeLogMsg() 銷毀接收到的 TLogMsg
]
Environment:
- Windows 2000 or later (_WIN32_WINNT >= 0x0500)
- VC++ 2010 or later
Release:
- Logger_C.dll - Console/MBCS/Release
- Logger_CD.dll- Console/MBCS/Debug
- Logger_CU.dll- Console/Unicode/Release
- Logger_CUD.dll- Console/Unicode/Debug
- Logger.dll - GUI/MBCS/Release
- Logger_D.dll - GUI/MBCS/Debug
- Logger_U.dll - GUI/Unicode/Release
- Logger_UD.dll- GUI/Unicode/Debug
Examples:
- TestGUILogger- GUI 版測試程式 (靜態載入)
- TestDynamicLogger- GUI 版測試程式 (動態載入)
- TestConsoleLogger- Console 版測試程式 (靜態載入)
相關博文:《Windows C++ 應用程式通用日誌組件(組件及測試程式下載)》
眾所周知,在調試、跟蹤和執行應用程式的過程中,程式的日誌能為這些工作提供大量有價值的運行資訊。因此,程式的日誌對應用程式的運行、維護至關重要。
在如何記錄程式日誌方面,通常有三種選擇:
1、採用Log4CXX等公用開源日誌組件:這類日誌組件的特點是跨平台且功能比較強大,例如可以把日誌發往另一台伺服器或記錄到資料庫中等;另外,可配置性較高,可以通過設定檔或程式碼對日誌進行很多個人化。但從另外一個角度看,由於這些優點往往也導致了在使用方面的缺點。首先,對於一般應用程式來說,它們並不需要太多的功能,通常只需要把日誌記錄到檔案或反饋到應用程式,功能太多反正讓使用者使用起來覺得繁瑣還得背負很多從來都用不到的代碼。其次,這類日誌組件通常是跨平台的,並不只是針對 Windows 或 VC 的應用程式,因此使用起來總會覺得有點彆扭,例如他們的字元都是用 char 類型的,對於一個 Unicode 程式來說每次寫日誌都要做字元轉換是很不爽的事情,本座在多年前曾經使用過 Log4Cpp ,程式執行時總是報告日誌組件有記憶體泄露,雖然有可能是誤判,但是使用起來總覺得很不舒服。
2、自己寫幾個簡單的類或函數記錄日誌:這種方法的確很簡單,通常都不用一兩百行的代碼。但這種方法通常缺乏規範性和通用性,其他程式需要記錄類似的但有點差異的日誌時,通常的作法是:Copy-Paste-Modify;另外,這類方法很可能也沒有考慮效能或並發方面的問題,通常是直接在背景工作執行緒中寫日誌,對於那些效能要求較高的應用程式是絕對不允許的。
3、乾脆不記錄任何日誌:的確,現在很多程式由於各種原因並沒有記錄任何日誌。但本座以為,如果一個程式是有用的,具備一定功能,並且需要連續運行較長一段時間,那麼記錄日誌是必須的;否則,得認真考慮該程式是否有存在的必要了。
CodeProject