首页 > 解决方案 > 在这个宏定义的消息传递、日志记录、错误处理系统中是否有任何不可预见的副作用?

问题描述

到目前为止,以下源代码已编译并运行,并且其行为符合我的预期。它正在将正确的消息记录到控制台,它正在抛出异常并基于 停止执行MsgTy,如果标志为真,它正在写入文本文件。如果一个文件不存在,它正在创建一个文件,如果它已经存在,它只是追加到它上面。到目前为止,它似乎正在工作。

我知道我本可以选择其他方法来创建日志记录、错误处理、消息传递系统,但这是一个练习,以刷新我编写可靠宏的技能。我知道它们更难调试,而且我已经尝试过测试所有情况,而且似乎没问题......我只想知道是否有任何我可能遗漏的东西。这不是生产代码,它是针对个人项目的,但我希望它像生产代码一样受到批评。

#include <exception>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <map>

enum MsgTy {
    OK = 0,
    WARNING,
    ERROR,
    CRITICAL,
};

static std::map<MsgTy, std::string> msg_id{
    {MsgTy::OK, {"OK: "}},
    {MsgTy::WARNING, {"WARNING: "}},  
    {MsgTy::ERROR, {"ERROR: "}},
    {MsgTy::CRITICAL, {"CRITICAL: "}}
};

class FileWriter {
    std::string filename_;
    std::ostringstream msg_;
public:
    FileWriter(const std::string& filename, std::ostringstream& msg) 
      : filename_{ filename } {
        operator()(msg);
    }

    void operator()(std::ostringstream& msg) {
        std::ofstream out("log.txt", std::ios::app);
        out << msg.str();        
    }
};

#define messaging(MsgTy, msg, log2file) do { \
    std::ostringstream strm; \
    if ((MsgTy) == OK) { \
        strm << msg_id[(MsgTy)] << (msg) << '\n'; \
        std::cout << strm.str(); \
        if((log2file) == true) \
            FileWriter fw("log.txt", strm); \
    } \
    if ((MsgTy) == WARNING) { \
        strm << msg_id[(MsgTy)] << (msg) << '\n'; \
        std::cout << strm.str(); \
        if((log2file) == true) \
            FileWriter fw("log.txt", strm);\
    } \
    if ((MsgTy) == ERROR) { \
        strm << msg_id[(MsgTy)] << (msg) << '\n'; \
        std::cerr << strm.str(); \
        if((log2file) == true) \
            FileWriter fw("log.txt", strm); \
        throw strm.str(); \
    } \
    if ((MsgTy) == CRITICAL) { \
        strm << msg_id[(MsgTy)] << (msg) << '\n'; \
        std::cerr << strm.str(); \
        if((log2file) == true) \
            FileWriter fw("log.txt", strm); \
        throw strm.str(); \
    } \
} while(0)

int main() {
    try {            
        messaging(MsgTy::OK, "Everything is good!", true);
        messaging(MsgTy::WARNING, "Something isn't quite right!", false);
        messaging(MsgTy::ERROR, "Something went wrong!", true);
        messaging(MsgTy::CRITICAL, "Something horribly went wrong!", true);           
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

标签: c++loggingerror-handlingmacrosc++17

解决方案


推荐阅读