STDERR 把日誌消息輸出到標準錯誤輸出流、也就是stderr.
LOGGER 輸出到本地的logger守衛程序
OSTREAM 把日誌輸出到ostream *對象指定的地方。比如可以使用ofstrem指定輸出到某個文件。必須調用 msg_ostream成員函數設置一個ostream *對象
MSG_CALLBACK 把日誌輸出到回調對象。必須自己定義一個從ACE_Log_Msg_Callback繼承的子類,並實現新類的log函數和調用ACE_Log_Msg 的msg_callback函數設置一個 ACE_Log_Msg_Callback子類的對象指針。
VERBOSE 在日誌消息中記錄日誌信息的程序名稱、線程id、日誌記錄時間等。默認情況下是不會輸出記錄日誌的時間的,可以通過設置系統環境變量ACE_LOG_TIMESTAMP來輸出時間的格式。可以爲TIME或者DATE。
VERBOSE_LITE 打印一些是線程相關的信息。
SILENT 不輸出任何日誌消息、即使設置了STDERR、LOGGER 等輸出格式時。
SYSLOG 把日誌消息輸出到本地系統日誌模塊。 如 linux的sysylog或者windows的事件 /// Write messages to the user provided backend
CUSTOM 與MAG_CALLBACK類似。必須定義一個從ACE_Log_Msg_Backend繼承的子類,並實現新類的log接口。和調用ACE_Log_Msg的msg_backend靜態函數設置ACE_Log_Msg_Backend的一個實現的指針。 該標誌與MSG_CALLBACK不同的是針對系統當前的所有ACE_Log_Msg都會進行該設置,而MSG_CALLBACK只是設置當前的ACE_Log_Msg對象。
log輸出目的地:STDERR 、LOGGER 、OSTREAM 、MSG_CALLBACK 、SYSLOG 、CUSTOM
log輸出的附加格式:VERBOSE 、VERBOSE_LITE
set_flags (u_long f) 設置log的輸出目的地或格式,可以同時設置多個標誌。
clr_flags (u_long f); 取消某個log輸出目的地或者格式。
log輸出優先級:
enum ACE_Log_Priority
{
LM_SHUTDOWN = 01,
LM_TRACE = 02,
LM_DEBUG = 04,
LM_INFO = 010,
LM_NOTICE = 020,
LM_WARNING = 040,
LM_STARTUP = 0100,
LM_ERROR = 0200,
LM_CRITICAL = 0400,
LM_ALERT = 01000,
LM_EMERGENCY = 02000,
LM_MAX = LM_EMERGENCY,
LM_ENSURE_32_BITS = 0x7FFFFFFF
};
與其說是log輸出優先級還不如說他們是log輸出的類型。他們在log中都是優先級的標誌位來判斷是否設定某個輸出類型的。
static void disable_debug_messages (ACE_Log_Priority priority = LM_DEBUG); 取消輸出某個優先級的日誌消息
static void enable_debug_messages (ACE_Log_Priority priority = LM_DEBUG); 使某個優先級的日誌消息可以被輸出。
讓我們的程序使用日誌來記錄信息。
ACE程序中我們會使用一下幾個常用的宏來輸出我們的日誌消息:
ACE_HEX_DUMP(X) 以16禁止的格式出書X的內容
ACE_RETURN(Y)
ACE_ERROR_BREAK(X)
ACE_ERROR(X)
ACE_DEBUG(X) # 我們最常用的。
ACE_ERROR_INIT(VALUE, FLAGS)
編譯時支持日誌輸出:默認情況下ACE在編譯時是支持以上幾個宏輸出日誌消息的。如果不想在自己的程序中輸出日誌消息時,可以定義宏ACE_NLOGGING ,這樣上面所有的宏都會變成一個空的do while語句,不執行任何內容。
運行時支持日誌輸出:
如果我們不做任何設置的話,那麼我們的程序默認是把日誌輸出到STDERR的。一般的控制檯應用程序已經可以滿足。
在很多情況下,比如和MFC一起使用時,或者我們想把日誌記錄到文件時我們就需要重新設置log的輸出目的地,通過set_flags/clr_flags設置程序指定的日誌輸出目的地。
多線程日誌輸出控制:
ACE_DEBUG等幾個預定義的宏所使用的ACE_Log_Msg對象雖然是通過ACE_Log_Msg::instance接口獲得的,但是並以意味這整個程序中只有一個ACE_Log_Msg對象。在ACE中如果我們編譯的庫是屬於多線程安全的(一定是多線程安全的,因爲我們根本就不會編譯,不會基於ACE開發一個單線程的程序)那麼對於每一個線程都會有一個ACE_Log_Msg對象。也就是不同的線程在使用ACE_DEBUG輸出日誌消息時所使用的ACE_Log_Msg對象是不一樣的。因此當我們把日誌的輸出目的或者格式改變而不是使用默認的輸出目的地和格式時,我們在每一個線程都需要設置每一個線程所屬的ACE_Log_Msg對象的日誌消息輸出格式。
例外:如果我們的輸出目的地是使用CUSTOM 的話,那麼我們就不需要設置每一個線程的輸出目的地了。因爲CUSTOM 的設置是對當前進程的所有線程都生效的。
注意: 如果用戶使用CUSTOM 或者MSG_CALLBACK 時,如果在實現的接口log中不加鎖時,存在多個線程同時打印輸出日誌消息的情況。這樣就很可能出現2條日誌消息在輸出的時候交叉在一起。此時我們可以對log函數輸出進行加鎖。但是加鎖的時候,由於log打印或者輸出消息到文件或者某些I/O口時,其時間來說相對比較長,這樣程序的性能就會比較差勁。
建議:ACE_Log_Msg_Callback或者ACE_Log_Msg_Backend的子類同時繼承自ACE_TASK,log接口只實現copy消息,並把消息放入線程專有的消息對了中,由svc接口獲取日誌信息在打印。也就是在我們的程序中提供一個專門接收日誌信息的緩衝隊列並輸出的線程。