開源日誌系統 log4cplus 七

2021-05-23 19:56:29 字數 3696 閱讀 5355

首先我們先了解一下log4cplus中嵌入診斷上下文(nested diagnostic context),即ndc。對log系統而言,

當輸入源可能不止乙個,而只有乙個輸出時,往往需要分辯所要輸出訊息的**,比如伺服器處理來自不同

客戶端的訊息時就需要作此判斷,ndc可以為交錯顯示的資訊打上乙個標記(stamp), 使得辨認工作看起來

比較容易些,呵呵。這個標記是執行緒特有的,利用了執行緒區域性儲存機制,稱為執行緒私有資料(thread-specific

data,或tsd)。 看了一下源**,相關定義如下,包括定義、初始化、獲取、設定和清除操作:

linux pthread

#   define log4cplus_thread_local_type pthread_key_t*

#   define log4cplus_thread_local_init ::log4cplus::thread::createpthreadkey()

#   define log4cplus_get_thread_local_value( key ) pthread_getspecific(*key)

#   define log4cplus_set_thread_local_value( key, value ) pthread_setspecific(*key, value)

#   define log4cplus_thread_local_cleanup( key ) pthread_key_delete(*key)

win32
#   define log4cplus_thread_local_type dword

#   define log4cplus_thread_local_init tlsalloc()

#   define log4cplus_get_thread_local_value( key ) tlsgetvalue(key)

#   define log4cplus_set_thread_local_value( key, value ) /

tlssetvalue(key, static_cast(value))

#   define log4cplus_thread_local_cleanup( key ) tlsfree(key)

使用起來比較簡單,在某個執行緒中:

ndc& ndc = log4cplus::ge***c();

ndc.push("ur ndc string");

log4cplus_debug(logger, "this is a ndc test");

... ...

ndc.pop();

... ...

log4cplus_debug(logger, "there should be no ndc...");

ndc.remove();

當設定輸出格式(layout)為ttcclayout時,輸出如下:

10-21-04 21:32:58, [3392] debug test  - this is a ndc test

10-21-04 21:32:58, [3392] debug test <> - there should be no ndc...

也可以在自定義的輸出格式中使用ndc(用%x) ,比如:
... ...

std::string pattern = "ndc:[%x]  - %m %n";

std::auto_ptr _layout(new patternlayout(pattern));

... ...

log4cplus_debug(_logger, "this is the first log message...")

ndc& ndc = log4cplus::ge***c();

ndc.push("ur ndc string");

log4cplus_warn(_logger, "this is the second log message...")

ndc.pop();

ndc.remove();

... ...

輸出如下:

ndc:  - this is the first log message...

ndc:[ur ndc string]  - this is the second log message...

ndccontextcreator _first_ndc("ur ndc string");

log4cplus_debug(logger, "this is a ndc test")

不必顯式地呼叫push/pop了,而且當出現異常時,能夠確保push與pop的呼叫是匹配的。

### 執行緒 ###

執行緒是log4cplus中的副產品, 而且僅作了最基本的實現,使用起來也異常簡單,只要且必須要

在派生類中過載run函式即可:

class testthread : public abstractthread

;

void testthread::run()

log4cplus的執行緒沒有考慮同步、死鎖,有互斥,實現執行緒切換的小函式挺別緻的:
void log4cplus::thread::yield()

### 套接字 ###

套接字也是log4cplus中的副產品,在namespace log4cplus::helpers中,實現了c/s方式的日誌記錄。
1. 客戶端程式需要做的工作:

... ...
socketbuffer buffer = converttobuffer(event, servername);

socketbuffer msgbuffer(log4cplus_max_message_size);

2. 伺服器端程式需要做的工作:

/* 定義乙個serversocket */

serversocket serversocket(port);

/* 呼叫accept函式建立乙個新的socket與客戶端連線 */

socket sock = serversocket.accept();

此後即可用該sock進行資料read/write了,形如:

socketbuffer msgsizebuffer(sizeof(unsigned int));
if(!clientsock.read(msgsizebuffer))

unsigned int msgsize = msgsizebuffer.readint();
socketbuffer buffer(msgsize);
if(!clientsock.read(buffer))

為了將讀到的資料正常顯示出來,需要將socketbuffer存放的內容轉換成internalloggingevent格式:
spi::internalloggingevent event = readfrombuffer(buffer);

【注】 read/write是按照阻塞方式實現的,意味著對其呼叫直到滿足了所接收或傳送的個數才返回。

開源日誌系統 log4cplus 二

本文介紹了使用log4cplus有六個步驟,並提供了一些例子引導你了解log4cplus的基本使用。基本使用 使用log4cplus有六個基本步驟 下面通過一些例子來了解log4cplus的基本使用。using namespace log4cplus using namespace log4cplu...

開源日誌系統 log4cplus 七

經過短暫的熟悉過程,log4cplus已經被成功應用到了我的專案中去了,效果還不錯,除了上文提及的 功能之外,下面將介紹log4cplus提供的執行緒和套接字的使用情況。ndc 首先我們先了解一下log4cplus中嵌入診斷上下文 nested diagnostic context 即ndc。對lo...

開源日誌系統 log4cplus 六

一些可以改進之處 1.使用者自定義loglevel的實現機制不夠開放在第五篇中曾經介紹過如何實現使用者自行定義loglevel,為了實現比較理想的效果,甚至還需要改log4cplus 的源 2.生成logger物件的機制可以改進我在使用時候,經常需要在不同的檔案 函式中操作同乙個logger,雖然l...