Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;同时记录到控制台和日志文件_C++_Logging_Stream - Fatal编程技术网

C++ C++;同时记录到控制台和日志文件

C++ C++;同时记录到控制台和日志文件,c++,logging,stream,C++,Logging,Stream,我有一个基类,例如“ProcessingThread”,它有几个派生。每个派生都有一个特定的名称,例如“派生1”、“派生2”。。。现在,对我来说,将格式化的输出输出到控制台似乎很有用,它可以打印如下内容: [DerivationOne]: Action X took place! [DerivationTwo]: Action Y took place! [DerivationTwo]: Action Z took place! 同时,它应该将每个内容写入特定于派生的日志文件。我想到了一个可以

我有一个基类,例如“ProcessingThread”,它有几个派生。每个派生都有一个特定的名称,例如“派生1”、“派生2”。。。现在,对我来说,将格式化的输出输出到控制台似乎很有用,它可以打印如下内容:

[DerivationOne]: Action X took place!
[DerivationTwo]: Action Y took place!
[DerivationTwo]: Action Z took place!

同时,它应该将每个内容写入特定于派生的日志文件。我想到了一个可以用标准方式调用的类,例如“custom_out我认为这是一个很好的问题

实际上,在我看来,考虑两个不同的事情:

  • 通过自定义流重新格式化输出(前缀)
  • 将其重定向到多个流
  • 我不会在一个类中同时做这两件事。我会为每个特性编写类


    首先,我将使用一个简单的类,传递一个
    std::ostream
    引用和一个字符串(对于前缀,尽管这里可能不只是概括前缀)对于构造函数,然后重载
    operator这是我在评论中讨论的想法的入门工具包。您需要决定如何处理写入磁盘文件的错误-返回false、抛出异常或其他。我将其编辑为返回true/false。true表示无错误。正在进行中

    #include <iostream>
    #include <mutex>
    #include <string>
    #include <fstream>
    #include <string_view>
    #include <iomanip>
    
    namespace dj {
    
        inline bool print(std::ostream& out) {
            return !!(out << std::endl);
        }
    
        template<typename T>
        bool print(std::ostream& out, T&& value)
        {
            return !!(out << std::forward<T>(value) << std::endl);
        }
    
        template<typename First, typename ... Rest>
        bool print(std::ostream& out, First&& first, Rest&& ... rest)
        {
            return !!(out << std::forward<First>(first)) && print(out, std::forward<Rest>(rest)...);
        }
    
        inline std::mutex logger_mtx;
    
        class log_stream {
        public:
            log_stream(std::string_view str, std::ostream& ifile)
                : name(str)
                , file(ifile)
            {
                std::string s{ "[" };
                name = s + name + "] ";
            }
    
            template <typename... Args>
            bool operator() (Args&&... args) {
                bool OK = print(file, std::forward<Args>(args)...);
                {
                    std::lock_guard<std::mutex> lck(logger_mtx);
                    print(std::cout, name, std::forward<Args>(args)...);
                    if (!OK) {
                        print(std::cout, name, "-- Error writing to log file. --");
                    }
                }
                return OK;
            }
    
        private:
            std::string name;
            std::ostream& file;
        };
    
    
    }
    int main()
    {
        std::ofstream outfile("DerivationOne.log.txt");
        dj::log_stream log("DerivationOne", outfile);
    
        std::ofstream outfile2; // ERROR. File not opened
        dj::log_stream log2("DerivationTwo", outfile2);
    
        log("Life. See ", 42, ", meaning of.");
        bool OK = 
          log2("log", std::setw(4), 2.01, " That's all, folks. -", 30, '-');
        std::cout << (OK ? "OK" : "So not OK") << std::endl;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    命名空间dj{
    内联bool打印(标准::ostream&out){
    
    返回!!(在运算符上使用链接是否是一项要求?…函数将接受任意数量的参数,但它们将用逗号分隔,而不是@JiveDadson:我完全可以自由选择实现。所以当然,这也没问题。它最多应该简单明了,因为我想节省时间和精力通过实现它来增加复杂性。我不知道如何通过编写诸如loggerI之类的东西来处理动态数量的参数。我想我会尝试一下。这是您想到的一个例子吗?这个策略是否能够处理多个串联变量,如自定义输出多个流的事情当然是这样的。另一个是也是,但实现并没有那么简单。例如,您可以查找
    std::endl
    (或
    '\n'
    )然后,好吧,开始新的一行。考虑到这一点,我可能会坚持使用
    std::endl
    来触发一个新的前缀,然后我甚至可以使用
    '\n'
    进行多行输出。这也使得实现更加容易。非常感谢你!变量模板仅在C++17中可用?我目前正在C++11和prob中开发ably不会很快被选为17。但也许我可以通过某种方式改变它,以实现与C++11函数相同的效果…变量模板在C++11中首次亮相完美,你就是那个人!再次非常感谢!