2017-03-14 75 views
2

我寫了這個logger。它工作正常,但有一些我無法做到的事情。如何刷新日誌消息並在C++中自動解鎖互斥鎖?

uLOG(warning) << "Test log message " << 123 << uLOGE; 

uLOG鎖定C++ 11互斥鎖並開始在文件流上寫入。
uLOGE刷新流並解鎖互斥鎖。

我想這個語法來獲得相同的結果:

uLOG(warning) << "Test log message " << 123; 

所以我想沖洗和解鎖自動在該行的末尾被調用。

這是一種可行的方法嗎?

  • 我嘗試設置ios::unitbuf標誌,但是這迫使每一個<<操作沖洗,不理想的一個SSD穿着。它並沒有解開互斥鎖。
  • 我試圖確定在ULOG一個臨時對象,它的析構函數將刷新和解鎖,但力量放在它自己的代碼塊中的日誌行:{ uLOG(warning) << 123; }

Reference

+0

第二個例子中的大括號不是必須的,你爲什麼認爲它們是? :)這可能是真正的問題 – OMGtechy

+0

@OMGtechy:我把大括號,以便臨時對象超出範圍和其析構函數被調用。 – Pietro

回答

5

您需要重新設計您的日誌框架,以便uLOG是您實例化的,並且它的析構函數執行您的uLOGE宏的工作。


非常簡單的例子:

struct uLOG 
{ 
    uLOG(std::string const& type) 
    { 
     std::cout << "Log: " << type << " - "; 
    } 

    template<typename T> 
    uLOG& operator<<(T const& output) 
    { 
     std::cout << output; 
     return *this; 
    } 

    ~uLOG() 
    { 
     std::cout << " (end of log)" << std::endl; 
    } 
}; 

// ... 
uLOG("warning") << "log message" << 123; 

上面,在一個合適的方案,應該打印

 
Log: warning - log message123 (end of log) 

該溶液不應該要求使用大括號的,所以可以在使用單語句不加強if或循環。

2

你的第二種方法是正確的,如果實施正確,它不需要大括號。你用宏做了嗎?這裏不需要它們。

uLOG應該是一個返回Log編寫器類臨時對象的函數。正如你所概述的那樣,它應該鎖定在ctor中並在dtor中刷新和解鎖,並且對於所有類型也有模板化的運營商< <,它只將呼叫轉發到實際的日誌目的地。