我正在嘗試使用Boost.Log自定義格式化程序。我知道如何做到這一點的方法是調用匯給它一個本地函數的地址set_formatter
方法,其中本地函數的簽名必須是:如何在自定義格式化函數中使用Boost.Log格式表達式
void my_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm)
在my_formatter
我可以使用Boost .Log抽取API以獲取我需要的屬性值。一旦我得到的值,我可以輸出他們到strm
。我想這樣做,這樣我可以輕鬆地格式化存儲在記錄中的一些自定義屬性。但對於其他更傳統的Boost.Log屬性,我想繼續使用簡單的格式化表達式,這些表達式被記錄爲set_formatter
方法的關鍵字參數。有沒有辦法在my_formatter
自定義函數中使用關鍵字表達式?
例如:
void my_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm)
{
// here I can get the timestamp attribute and format its ticks value to the stream
boost::log::value_ref<boost::posix_time::ptime> tstamp_ref =
boost::log::extract<boost::posix_time::ptime>("TimeStamp", rec);
const boost::posix_time::ptime& timestamp = tstamp_ref.get();
strm << timestamp.time_of_day().ticks();
}
然後給一個接收器,我可以打電話給
sink->set_formatter(&my_formatter)
但Boost.Log給我一個優雅的(幾乎是不可思議的)的表達,我可以用它來設置格式:
boost::log::formatter formatter =
expr::stream
<< expr::format_date_time<boost::posix_time::ptime>(
"TimeStamp", "%Y/%m/%d, %H:%M:%S.%f, ");
sink->set_formatter(formatter)
我的問題是:有沒有辦法在我的自定義中使用formatter表達式my_formatter
功能?
謝謝!
謝謝!這是一個很長的答案,所以我將不得不稍稍研究一下,但這似乎也是一個很好的方法。在使用格式化表達式時,您可以多討論一下性能下降嗎?您在文檔中提到,代碼中的格式化表達式的執行速度要比從配置文件創建的快。我的觀察是我的非表達式格式化程序比基於表達式的表達式執行得更快。 (在我的臨時基準測試中,唯一正在做的工作就是日誌記錄,所以我對速度變慢了,但有時性能確實很重要。) – Phil
必須檢查代碼和生成的程序集才能發現績效迴歸的原因。格式化表達式(無論如何涉及'expr :: stream')比解析格式化器更有效率,因爲編譯器有更多優化方法。特別是它可以更積極地內聯函數。手寫格式化程序可能會勝過格式化表達式,因爲它可以更加專業化。它通常是一個扁平函數,所以它不依賴內聯,而編譯器可能由於某種原因無法優化模板表達式。 –
另外,如果你的格式化程序涉及日期/時間,那麼確保你使用'expr :: format_date_time'而不是Boost.DateTime中的'operator <<',因爲後者被認爲比較慢。 –