国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++項(xiàng)目實(shí)戰(zhàn)——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng)-⑨-同步日志器類與日志器建造者類設(shè)計(jì)

這篇具有很好參考價(jià)值的文章主要介紹了C++項(xiàng)目實(shí)戰(zhàn)——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng)-⑨-同步日志器類與日志器建造者類設(shè)計(jì)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

專欄導(dǎo)讀

??作者簡(jiǎn)介:花想云 ,在讀本科生一枚,C/C++領(lǐng)域新星創(chuàng)作者,新星計(jì)劃導(dǎo)師,阿里云專家博主,CSDN內(nèi)容合伙人…致力于 C/C++、Linux 學(xué)習(xí)。

??專欄簡(jiǎn)介:本文收錄于 C++項(xiàng)目——基于多設(shè)計(jì)模式下的同步與異步日志系統(tǒng)

??相關(guān)專欄推薦:C語(yǔ)言初階系列C語(yǔ)言進(jìn)階系列 、C++系列數(shù)據(jù)結(jié)構(gòu)與算法、Linux

C++項(xiàng)目實(shí)戰(zhàn)——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng)-⑨-同步日志器類與日志器建造者類設(shè)計(jì),C++項(xiàng)目——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng),c++,設(shè)計(jì)模式,c++項(xiàng)目實(shí)戰(zhàn),c++項(xiàng)目
日志器主要是用來(lái)與前端交互,當(dāng)我們需要使用日志系統(tǒng)打印日志消息時(shí),只需要?jiǎng)?chuàng)建Logger對(duì)象,調(diào)用該對(duì)象的debug、info、warn、error、fatal等方法輸出自己想要打印的日志消息即可。支持解析可變參數(shù)列表和輸出格式,就可以做到像printf函數(shù)一樣打印日志。

因?yàn)槿罩酒髂K是對(duì)前邊所有模塊的一個(gè)整合,所以Logger類管理的成員有:

  • 日志器名稱(日志器的唯一標(biāo)識(shí));
  • 格式化模塊對(duì)象(Formatter);
  • 落地模塊對(duì)象數(shù)組(一個(gè)日志器可能會(huì)向多個(gè)位置進(jìn)行日志輸出);
  • 默認(rèn)的輸出限制等級(jí)(控制達(dá)到指定等級(jí)的日志才可以輸出);
  • 互斥鎖(保證日志輸出過(guò)程是線程安全的,不會(huì)出現(xiàn)交叉日志);

Logger類提供的操作有:

  • debug等級(jí)日志的輸出操作;
  • info等級(jí)日志的輸出操作;
  • warn等級(jí)日志的輸出操作;
  • error等級(jí)日志的輸出操作;
  • fatal等級(jí)日志的輸出操作;

當(dāng)前日志系統(tǒng)支持同步日志和異步日志兩種方式,兩個(gè)不同的日志器唯一的區(qū)別是它們?cè)谌罩韭涞胤绞缴嫌兴煌?/p>

  • 同步日志器:直接對(duì)日志消息進(jìn)行輸出;
  • 異步日志器:將日志消息放入緩沖區(qū),由異步線程進(jìn)行輸出。

因此日志器在設(shè)計(jì)的時(shí)候先設(shè)計(jì)一個(gè)Logger基類,在Logger基類的基礎(chǔ)上繼承出SyncLogger同步日志器AsyncLogger異步日志器

Logger類設(shè)計(jì)

  • debug、info等接口在設(shè)計(jì)時(shí),需要傳遞參數(shù)有文件名、行號(hào)、參數(shù)包。至于為什么要傳遞文件名與行號(hào),因?yàn)橐苊猥@取文件名和行號(hào)時(shí)是在本函數(shù)內(nèi)部;
  • 將參數(shù)包進(jìn)行內(nèi)容提取后保存在字符串中,交由serialize進(jìn)行處理;
  • serialize函數(shù)的功能是,將字符串中的內(nèi)容進(jìn)行日志消息格式化,并進(jìn)行落地操作;
class Logger
{
public:
    using ptr = std::shared_ptr<Logger>;

    Logger(const std::string &logger_name,
           LogLevel::value level,
           Formatter::ptr &formatter,
           std::vector<LogSink::ptr> &sinks) : 
           _logger_name(logger_name),
           _limit_level(level),
           _formatter(formatter),
           _sinks(sinks.begin(), sinks.end())
    {}
	// 獲取日志器名稱
    const std::string& name(){ return _logger_name; }
    
    void debug(const std::string &file, size_t line, const std::string &fmt, ...)
    {
        // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
        // 判斷當(dāng)前的日志是否達(dá)到了輸出等級(jí)
        if (LogLevel::value::DEBUG < _limit_level)
        {
            return;
        }

        // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
        va_list ap;
        va_start(ap, fmt);
        char *res;
        int ret = vasprintf(&res, fmt.c_str(), ap);
        if (ret == 1)
        {
            std::cout << "vasprintf failed\n";
            return;
        }
        va_end(ap);
        serialize(LogLevel::value::DEBUG, file, line, res);
        free(res);
    }
    void info(const std::string &file, size_t line, const std::string &fmt, ...)
    {
        // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
        if (LogLevel::value::INFO < _limit_level)
        {
            return;
        }

        // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
        va_list ap;
        va_start(ap, fmt);
        char *res;
        int ret = vasprintf(&res, fmt.c_str(), ap);
        if (ret == 1)
        {
            std::cout << "vasprintf failed\n";
            return;
        }
        va_end(ap);
        serialize(LogLevel::value::INFO, file, line, res);
        free(res);
    }
    void warn(const std::string &file, size_t line, const std::string &fmt, ...)
    {
        // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
        if (LogLevel::value::WARN < _limit_level)
        {
            return;
        }

        // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
        va_list ap;
        va_start(ap, fmt);
        char *res;
        int ret = vasprintf(&res, fmt.c_str(), ap);
        if (ret == 1)
        {
            std::cout << "vasprintf failed\n";
            return;
        }
        va_end(ap);
        serialize(LogLevel::value::WARN, file, line, res);
        free(res);
    }
    void error(const std::string &file, size_t line, const std::string &fmt, ...)
    {
        // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
        if (LogLevel::value::ERROR < _limit_level)
        {
            return;
        }

        // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
        va_list ap;
        va_start(ap, fmt);
        char *res;
        int ret = vasprintf(&res, fmt.c_str(), ap);
        if (ret == 1)
        {
            std::cout << "vasprintf failed\n";
            return;
        }
        va_end(ap);
        serialize(LogLevel::value::ERROR, file, line, res);
        free(res);
    }
    void fatal(const std::string &file, size_t line, const std::string &fmt, ...)
    {
        // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
        if (LogLevel::value::FATAL < _limit_level)
        {
            return;
        }

        // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
        va_list ap;
        va_start(ap, fmt);
        char *res;
        int ret = vasprintf(&res, fmt.c_str(), ap);
        if (ret == 1)
        {
            std::cout << "vasprintf failed\n";
            return;
        }
        va_end(ap);
        serialize(LogLevel::value::FATAL, file, line, res);
        free(res);
    }

protected:
    void serialize(LogLevel::value level, const std::string &file, size_t line, char *str)
    {
        // 構(gòu)造LogMsg對(duì)象
        LogMsg msg(level, line, file, _logger_name, str);
        // 通過(guò)格式化工具對(duì)LogMsg進(jìn)行格式化, 得到格式化后的日志字符串
        std::stringstream ss;
        _formatter->format(ss, msg);
        // 對(duì)日志進(jìn)行落地
        log(ss.str().c_str(), ss.str().size());
    }
    virtual void log(const char *data, size_t len) = 0;

protected:
    std::mutex _mutex;
    std::string _logger_name;                  // 日志器名稱
    std::atomic<LogLevel::value> _limit_level; // 限制輸出等級(jí)
    Formatter::ptr _formatter;
    std::vector<LogSink::ptr> _sinks; // 落地方向數(shù)組
};

同步日志器類設(shè)計(jì)

同步日志器設(shè)計(jì)較為簡(jiǎn)單,設(shè)計(jì)思想是:

  • 遍歷日志落地?cái)?shù)組,以數(shù)組中的各種落地方式進(jìn)行落地操作;
class SyncLogger : public Logger
{
public:
    SyncLogger(const std::string &logger_name,
               LogLevel::value level,
               LOG::Formatter::ptr &formatter,
               std::vector<LogSink::ptr> &sinks) 
               : Logger(logger_name, level, formatter, sinks)
    {
    }

protected:
    void log(const char *data, size_t len)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if (_sinks.empty())
            return;
        for (auto &sink : _sinks)
        {
            sink->log(data, len);
        }
    }
};

同步日志器測(cè)試

int main()
{
	LOG::LogMsg msg(LOG::LogLevel::value::INFO, 53, "main.cc", "root", "格式化功能測(cè)試...");
    LOG::Formatter fmt;
    std::string str = fmt.format(msg);
    LOG::LogSink::ptr time_lsp = LOG::SinkFactory::create<RollByTimeSink>("./logfile/roll-", TimeGap::GAP_SECOND);
    time_t old = LOG::util::Date::getTime();
    while(LOG::util::Date::getTime() < old + 5)
    {
        time_lsp->log(str.c_str(), str.size());
        sleep(1);
    }

    std::string logger_name = "sync_logger";
    LOG::LogLevel::value limit = LOG::LogLevel::value::WARN;
    LOG::Formatter::ptr fmt(new LOG::Formatter("[%d{%H:%M:%S}][%c][%f:%l][%p]%T%m%n"));
    LOG::LogSink::ptr stdout_lsp = LOG::SinkFactory::create<LOG::StdOutSink>();
    LOG::LogSink::ptr file_lsp = LOG::SinkFactory::create<LOG::FileSink>("./logfile/test.log");
    LOG::LogSink::ptr roll_lsp = LOG::SinkFactory::create<LOG::RollBySizeSink>("./logfile/test.log", 1024*1024);
    std::vector<LOG::LogSink> sinks = {stdout_lsp, file_lsp, roll_lsp};
    LOG::Logger::ptr logger(new LOG::SyncLogger(logger_name, limit, fmt, sinks));

    logger->debug(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->info(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->warn(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->error(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->fatal(__FILE__, __LINE__, "%s", "測(cè)試日志");

    size_t cursize = 0, count = 0;
    while(cursize < 1024*1024*10)
    {   
        logger->fatal(__FILE__, __LINE__, "測(cè)試日志-%d", count++);
        cursize+=20;
    }
	return 0;
}

日志器建造者模式設(shè)計(jì)

觀察上一小節(jié)中的日志器測(cè)試代碼,在構(gòu)建一個(gè)同步日志器時(shí),需要先設(shè)置很多的零部件。這對(duì)于用戶來(lái)說(shuō)未免有些繁瑣。

我們需要使用建造者模式來(lái)建造日志器,而不要讓用戶直接去構(gòu)造日志器,以簡(jiǎn)化用戶的使用復(fù)雜度

設(shè)計(jì)思想:

  • 抽象一個(gè)日志器建造者類
    • 設(shè)置日志器類型;
    • 將不同類型(同步&異步)日志器的創(chuàng)建放到同一個(gè)日志器建造者類中完成。
  • 派生出具體的建造者類----局部日志器建造者 & 全局日志器建造者類(后面添加了全局單例管理器之后,將日志器添加全局管理)。

抽象日志器建造者類

  • 建造者類中包含成員:
    • logger_type 日志器類型;
    • logger_name 日志器名稱;
    • limit_level 日志輸出限制等級(jí);
    • formatter 格式化對(duì)象;
    • sinks 日志落地?cái)?shù)組;
  • 還有構(gòu)建各個(gè)零件的函數(shù);
enum class LoggerType
{
    LOGGER_SYNC,
    LOGGER_ASYNC
};
// 1.抽象一個(gè)日志器建造者類(完成日志器所需零部件的構(gòu)建 & 日志器的構(gòu)建)
class LoggerBuilder
{
public:
    LoggerBuilder() : _logger_type(LoggerType::LOGGER_SYNC),
                      _limit_level(LogLevel::value::DEBUG)
    {}
    void buildLoggerType(LoggerType type) { _logger_type = type; }
    void buildLoggerName(const std::string &name) { _logger_name = name; }
    void buildLoggerLevel(LogLevel::value level) { _limit_level = level; }
    void buildFormatter(const std::string &pattern)
    {
        _formatter = std::make_shared<Formatter>(pattern);
    }
    template <typename SinkType, typename... Args>
    void buildSink(Args &&...args)
    {
        LogSink::ptr psink = SinkFactory::create<SinkType>(std::forward<Args>(args)...);
        _sinks.push_back(psink);
    }
    virtual Logger::ptr build() = 0;

protected:
    LoggerType _logger_type;
    std::string _logger_name;
    std::atomic<LogLevel::value> _limit_level;
    Formatter::ptr _formatter;
    std::vector<LogSink::ptr> _sinks;
};

派生局部日志器建造者

/*2.派生出具體的建造者類---局部日志器的建造者 & 全局日志器的建造者*/
class LocalLoggerBuilder : public LoggerBuilder
{
public:
    Logger::ptr build() override
    {
        assert(_logger_name.empty() == false);
        if (_formatter.get() == nullptr)
        {
            _formatter = std::make_shared<Formatter>();
        }

        if (_sinks.empty())
        {
            buildSink<StdOutSink>();
        }

        if (_logger_type == LoggerType::LOGGER_ASYNC)
        {
            // 后面實(shí)現(xiàn)異步日志器后再完善...
        }
        return std::make_shared<SyncLogger>(_logger_name, _limit_level, _formatter, _sinks);
    }
};

日志器建造者類測(cè)試

int main()
{
	std::unique_ptr<LOG::LoggerBuilder> builder(new LOG::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerLevel(LOG::LogLevel::value::WARN);
    builder->buildFormatter("[%c][%f:%l]%m%n");
    builder->buildLoggerType(LOG::LoggerType::LOGGER_SYNC);
    builder->buildEnableUnSafeAsync();
    builder->buildSink<LOG::FileSink>("./logfile/async.log");
    builder->buildSink<LOG::StdOutSink>();
    LOG::Logger::ptr = builder->build();

    logger->debug(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->info(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->warn(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->error(__FILE__, __LINE__, "%s", "測(cè)試日志");
    logger->fatal(__FILE__, __LINE__, "%s", "測(cè)試日志");

    size_t cursize = 0, count = 0;
    while(cursize < 1024*1024*10)
    {   
        logger->fatal(__FILE__, __LINE__, "測(cè)試日志-%d", count++);
        cursize+=20;
    }
	return 0;
}

同步日志器類與日志器建造者類整理

#ifndef __M_LOGGER_H__
#define __M_LOGGER_H__
#include "util.hpp"
#include "level.hpp"
#include "format.hpp"
#include "sink.hpp"
#include "looper.hpp"
#include <cstdarg>
#include <atomic>
#include <thread>
#include <mutex>
#include <unordered_map>

namespace LOG
{
    class Logger
    {
    public:
        using ptr = std::shared_ptr<Logger>;

        Logger(const std::string &logger_name,
               LogLevel::value level,
               Formatter::ptr &formatter,
               std::vector<LogSink::ptr> &sinks) : 
               _logger_name(logger_name),
               _limit_level(level),
               _formatter(formatter),
               _sinks(sinks.begin(), sinks.end())
        {
        }

        const std::string& name(){ return _logger_name; }
        void debug(const std::string &file, size_t line, const std::string &fmt, ...)
        {
            // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
            // 判斷當(dāng)前的日志是否達(dá)到了輸出等級(jí)
            if (LogLevel::value::DEBUG < _limit_level)
            {
                return;
            }

            // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
            va_list ap;
            va_start(ap, fmt);
            char *res;
            int ret = vasprintf(&res, fmt.c_str(), ap);
            if (ret == 1)
            {
                std::cout << "vasprintf failed\n";
                return;
            }
            va_end(ap);
            serialize(LogLevel::value::DEBUG, file, line, res);
            free(res);
        }
        void info(const std::string &file, size_t line, const std::string &fmt, ...)
        {
            // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
            if (LogLevel::value::INFO < _limit_level)
            {
                return;
            }

            // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
            va_list ap;
            va_start(ap, fmt);
            char *res;
            int ret = vasprintf(&res, fmt.c_str(), ap);
            if (ret == 1)
            {
                std::cout << "vasprintf failed\n";
                return;
            }
            va_end(ap);
            serialize(LogLevel::value::INFO, file, line, res);
            free(res);
        }
        void warn(const std::string &file, size_t line, const std::string &fmt, ...)
        {
            // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
            if (LogLevel::value::WARN < _limit_level)
            {
                return;
            }

            // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
            va_list ap;
            va_start(ap, fmt);
            char *res;
            int ret = vasprintf(&res, fmt.c_str(), ap);
            if (ret == 1)
            {
                std::cout << "vasprintf failed\n";
                return;
            }
            va_end(ap);
            serialize(LogLevel::value::WARN, file, line, res);
            free(res);
        }
        void error(const std::string &file, size_t line, const std::string &fmt, ...)
        {
            // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
            if (LogLevel::value::ERROR < _limit_level)
            {
                return;
            }

            // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
            va_list ap;
            va_start(ap, fmt);
            char *res;
            int ret = vasprintf(&res, fmt.c_str(), ap);
            if (ret == 1)
            {
                std::cout << "vasprintf failed\n";
                return;
            }
            va_end(ap);
            serialize(LogLevel::value::ERROR, file, line, res);
            free(res);
        }
        void fatal(const std::string &file, size_t line, const std::string &fmt, ...)
        {
            // 通過(guò)傳入的參數(shù)構(gòu)造出一個(gè)日志消息對(duì)象, 進(jìn)行日志格式化,最終落地
            if (LogLevel::value::FATAL < _limit_level)
            {
                return;
            }

            // 對(duì)fmt格式化字符串和不定參數(shù)進(jìn)行字符串組織, 得到的日志消息字符串
            va_list ap;
            va_start(ap, fmt);
            char *res;
            int ret = vasprintf(&res, fmt.c_str(), ap);
            if (ret == 1)
            {
                std::cout << "vasprintf failed\n";
                return;
            }
            va_end(ap);
            serialize(LogLevel::value::FATAL, file, line, res);
            free(res);
        }

    protected:
        void serialize(LogLevel::value level, const std::string &file, size_t line, char *str)
        {
            // 構(gòu)造LogMsg對(duì)象
            LogMsg msg(level, line, file, _logger_name, str);
            // 通過(guò)格式化工具對(duì)LogMsg進(jìn)行格式化, 得到格式化后的日志字符串
            std::stringstream ss;
            _formatter->format(ss, msg);
            // 對(duì)日志進(jìn)行落地
            log(ss.str().c_str(), ss.str().size());
        }
        virtual void log(const char *data, size_t len) = 0;

    protected:
        std::mutex _mutex;
        std::string _logger_name;                  // 日志器名稱
        std::atomic<LogLevel::value> _limit_level; // 限制輸出等級(jí)
        Formatter::ptr _formatter;
        std::vector<LogSink::ptr> _sinks;
    };

    class SyncLogger : public Logger
    {
    public:
        SyncLogger(const std::string &logger_name,
                   LogLevel::value level,
                   LOG::Formatter::ptr &formatter,
                   std::vector<LogSink::ptr> &sinks) 
                   : Logger(logger_name, level, formatter, sinks)
        {
        }

    protected:
        void log(const char *data, size_t len)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            if (_sinks.empty())
                return;
            for (auto &sink : _sinks)
            {
                sink->log(data, len);
            }
        }
    };
    // 1.抽象一個(gè)日志器建造者類(完成日志器所需零部件的構(gòu)建 & 日志器的構(gòu)建)
    //  1.設(shè)置日志器類型
    //  2.將不同類型的日志器的創(chuàng)建放到同一個(gè)日志器建造者類中完成
    enum class LoggerType
    {
        LOGGER_SYNC,
        LOGGER_ASYNC
    };

    class LoggerBuilder
    {
    public:
        LoggerBuilder() : _logger_type(LoggerType::LOGGER_SYNC),
                          _limit_level(LogLevel::value::DEBUG)
        {}
        void buildLoggerType(LoggerType type) { _logger_type = type; }
        void buildEnableUnSafeAsync() { _looper_type = AsyncType::ASYNC_UNSAFE; }
        void buildLoggerName(const std::string &name) { _logger_name = name; }
        void buildLoggerLevel(LogLevel::value level) { _limit_level = level; }
        void buildFormatter(const std::string &pattern)
        {
            _formatter = std::make_shared<Formatter>(pattern);
        }
        template <typename SinkType, typename... Args>
        void buildSink(Args &&...args)
        {
            LogSink::ptr psink = SinkFactory::create<SinkType>(std::forward<Args>(args)...);
            _sinks.push_back(psink);
        }
        virtual Logger::ptr build() = 0;

    protected:
        LoggerType _logger_type;
        std::string _logger_name;
        std::atomic<LogLevel::value> _limit_level;
        Formatter::ptr _formatter;
        std::vector<LogSink::ptr> _sinks;
    };

    /*2.派生出具體的建造者類---局部日志器的建造者 & 全局日志器的建造者*/
    class LocalLoggerBuilder : public LoggerBuilder
    {
    public:
        Logger::ptr build() override
        {
            assert(_logger_name.empty() == false);
            if (_formatter.get() == nullptr)
            {
                _formatter = std::make_shared<Formatter>();
            }

            if (_sinks.empty())
            {
                buildSink<StdOutSink>();
            }

            if (_logger_type == LoggerType::LOGGER_ASYNC)
            {}
            return std::make_shared<SyncLogger>(_logger_name, _limit_level, _formatter, _sinks);
        }
    };
}
#endif

C++項(xiàng)目實(shí)戰(zhàn)——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng)-⑨-同步日志器類與日志器建造者類設(shè)計(jì),C++項(xiàng)目——基于多設(shè)計(jì)模式下的同步&amp;異步日志系統(tǒng),c++,設(shè)計(jì)模式,c++項(xiàng)目實(shí)戰(zhàn),c++項(xiàng)目文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-709648.html

到了這里,關(guān)于C++項(xiàng)目實(shí)戰(zhàn)——基于多設(shè)計(jì)模式下的同步&異步日志系統(tǒng)-⑨-同步日志器類與日志器建造者類設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包