初始化记录器一次

问题描述 投票:0回答:1

我正在实现一个库,并且想提供简单的日志记录工具,而不使用日志记录框架。

我已经看到了这一小段代码,但它的作用比我预期的要多一些:

// logging.h
#ifndef LOGGING_H 
#define LOGGING_H 

#include <iostream>

enum LogLevel {
    // no log is the default
    NoLog       = 0,
    // written to stderr
    Err         = 1,
    Warning     = 2,
    // written to stdout
    Info        = 3,
    Debug       = 4
};

void initLogger(LogLevel level);

LogLevel loggerLevel();

#define LOG(level, msg) \
    do { \
        if (level > NoLog && level <= loggerLevel()) { \
            if (level <= Warning) \
                std::cerr << __FILE__ << "(" << __LINE__ << ") " << msg << std::endl; \
            else \
                std::cout << __FILE__ << "(" << __LINE__ << ") " << msg << std::endl; \
        } \
    } while (0)
        
#define LOG_ERR(msg)    LOG(Err, msg) 
#define LOG_WARN(msg)   LOG(Warning, msg)
#define LOG_INFO(msg)   LOG(Info, msg)
#define LOG_DEBUG(msg)  LOG(Debug, msg)

#endif // LOGGING_H 

// logging.cpp
include "logging.h"

static LogLevel logLevel = NoLog;

void initLogger(LogLevel level)
{
    logLevel = level;
}

LogLevel loggerLevel()
{
    return logLevel;
}

在这里,用户可以在运行时更改我不想要的日志记录级别:

initLogger(Err);
    
// not printed
LOG_INFO("info");
  
initLogger(Info);
    
// printed
LOG_INFO("info");

我更愿意让用户选择一劳永逸地初始化日志记录级别,或者完全跳过此步骤并回退到默认级别。我心里有一个单例,但是如何处理默认情况呢? (跳过初始化步骤)

我想应该有更直接的东西。 实现这一目标的最佳方法是什么?

谢谢你。

c++ c++17
1个回答
0
投票

例如像这样的东西:

#include <string_view>
#include <iostream>

namespace your_library
{
    struct reporting_itf
    {
        virtual ~reporting_itf() = default;
        virtual void report_method_called(const std::string_view method_name) const noexcept = 0;

        // add more report options here...
        // virtual void report_internal_error() const noexcept = 0;
    };

    struct no_reporting_t : public reporting_itf
    {
        void report_method_called(const std::string_view method_name) const noexcept override {};

        //void report_internal_error() const noexcept override {};
    };

    no_reporting_t no_reporting;
    const reporting_itf* g_reporting = &no_reporting;

    void set_reporting(const reporting_itf& reporting)
    {
        g_reporting = &reporting;
    }

    void some_function()
    {
        g_reporting->report_method_called(__FUNCTION__);
    }

}


namespace client_code
{
    struct client_logger_t : public your_library::reporting_itf
    {
        void report_method_called(const std::string_view method_name) const noexcept override
        {
            std::cout << "called : " << method_name << "\n";
            // should be something like LOG(Informational....)
        };

        // Internal logger classes
        // Logger m_log;
    };
}


int main()
{
    client_code::client_logger_t client_logger; 
    your_library::set_reporting(client_logger);

    your_library::some_function();
}
© www.soinside.com 2019 - 2024. All rights reserved.