程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> spdlog源碼閱讀 (3): log_msg和BasicWriter

spdlog源碼閱讀 (3): log_msg和BasicWriter

編輯:關於C++

spdlog源碼閱讀 (3): log_msg和BasicWriter。本站提示廣大學習愛好者:(spdlog源碼閱讀 (3): log_msg和BasicWriter)文章只能為提供參考,不一定能成為您想要的結果。以下是spdlog源碼閱讀 (3): log_msg和BasicWriter正文


4. log_msg和它的打手BasicWriter

在spdlog源碼閱讀 (2): sinks的創建和使用中,提到log_msg提供了存儲日志的功能。那麼到底在spdlog中它是怎麼
起到這個作用的呢?
不妨現在代碼中搜索下log_msg的具體使用(即在logger_impl.h中),可以得出一下幾種用法:

1. log_msg.raw << msg;
2. log_msg.raw.write(fmt, args...);
3. err_msg.formatted.write("[*** LOG ERROR ***] [{}] [{}] [{}]{}", name(), msg, date_buf, details::os::eol);

上面三行代碼是log_msg使用的最幾種體現,而做相應操作的raw和formatted是
MemoryWriter類型的對象。

4.1 打手BasicWriter

接上文,繼續向上查看MemoryWriter的定義,發現:

typedef BasicMemoryWriter<char> MemoryWriter;

繼續查看BasicMemoryWriter:

template <typename Char, typename Allocator = std::allocator<Char> >
class BasicMemoryWriter: public BasicWriter<Char>
//......

在類內部並沒有發現我們想要找的"<<"操作符,也沒有write。繼續向它的父類尋求幫助,
此處打手BasicWriter出現了。

BasicWriter &operator<<(int value)
{
    write_decimal(value);
    return *this;
}

在BasicWriter中,"<<"操作符針對不同參數類型分別提供了對應的實現。打手裝備了
武器write_decimal,下面我們就看看這個武器是如何的鋒利(叼)。

4.2 打手武器篇

作為程序猿閒話少說,直接代碼

template <typename Int>
void write_decimal(Int value)
{
    1. typedef typename internal::IntTraits<Int>::MainType MainType;
    MainType abs_value = static_cast<MainType>(value);
    if (internal::is_negative(value))
    {
        abs_value = 0 - abs_value;
        *write_unsigned_decimal(abs_value, 1) = '-';
    }
    else
    {
        write_unsigned_decimal(abs_value, 0);
    }
}

line1: 使用IntTraits

template <bool FitsIn32Bits>
struct TypeSelector
{
    typedef uint32_t Type;
};

template <>
struct TypeSelector<false>
{
    typedef uint64_t Type;
};

template <typename T>
struct IntTraits
{
    // Smallest of uint32_t and uint64_t that is large enough to represent
    // all values of T.
    typedef typename
    TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType;
};

在spdlog中這種寫法較多,例如判斷是否無符號數,通過模板的參數演繹來獲取真實的類型。
更多的內容參見(SGI __type_traits)。
write_decimal繼續執行調用write_unsigned_decimal通過單獨處理10進制下的每一位轉換為
字符串,存儲到buffer中。

4.3 buffer

在本文示例中,最後的buffer是MemoryBuffer。一般是一個char類型的存儲區,默認大小為500字節。
當存儲的內容大於該限制時,則進行轉儲,並擴大空間。擴大的空間每次以當前的緩沖區大小加上,
當前緩沖區的一半。

5 寫在最後

關於spdlog的先寫到這裡,到今天已經有三篇分別介紹: sink,sink的作用,以及日志的緩沖區。
當然實際上spdlog還有更多內容,例如formatter等。後面如果有機會,會整理一個比較完整的類圖
放在後面,幫助理解。

(人不是全能的,如果有錯誤的地方,還請大家不吝指出,本人不勝感激)。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved