c++ - 将 ostream 重定向到文件不起作用

标签 c++ logging file-io operator-overloading

我有一个自定义日志系统,它允许我根据当前选择的详细程度将信息发送到日志文件和控制台。现在,我遇到的问题是输出到文件,输出到控制台工作正常。

这是一个例子:

     ilra_talk << "Local IP: " << systemIP() << " |  Hostname: " << systemhostname() << endl;
     // the systemIP() and systemhostname() functions have already been defined

这应该会导致系统的当前本地 IP 和主机名被打印到文件中。然而,它只会导致信息被打印到控制台,尽管该函数如何过载导致它打印到两个控制台。

我在下面概述了代码。感谢您提供任何帮助(一如既往)。

ilra_talk 当前存在一个定义,它会导致创建一个新的类对象:

#define ilra_talk ilra(__FUNCTION__,0)

类定义如下:

class ilra
{
    static int ilralevel_set; // properly initialized in my main .cpp
    static int ilralevel_passed; // properly initialized in my main .cpp
    static bool relay_enabled; // properly initialized in my main .cpp
    static bool log_enabled; // properly initialized in my main .cpp
    static ofstream logfile; // properly initialized in my main .cpp
public:
    // constructor / destructor
    ilra(const std::string &funcName, int toset)
    {
        ilralevel_passed = toset;
    }
    ~ilra(){};

    // enable / disable irla functions
    static void ilra_verbose_level(int toset){
        ilralevel_set = toset;
    }
    static void ilra_log_enabled(bool toset){
        log_enabled = toset;

        if (log_enabled == true){
            // get current time
            time_t rawtime;
            time ( &rawtime );

            // name of log file (based on time of application start)
            stringstream logname_s;
            string logname = "rclient-";
            logname_s << rawtime;
            logname.append(logname_s.str());

            // open a log file
            logfile.open(logname.c_str());
        }
    }

    // output
    template <class T>
    ilra &operator<<(const T &v)
    {
        if(log_enabled == true){ // log_enabled is set to true
            logfile << v; 
            logfile << "Test" << endl;  // test will show up, but intended information will not appear
            }
        if(ilralevel_passed <= ilralevel_set)
            std::cout << v;
        return *this;
    }

    ilra &operator<<(std::ostream&(*f)(std::ostream&))
    {
        if(log_enabled == true) // log_enabled is set to true
            logfile << *f;
        if(ilralevel_passed <= ilralevel_set)
            std::cout << *f;
        return *this;
    }
};  // end of the class

最佳答案

我认为代码没有完全错误,但我个人会进行两处更改:

  1. 将 logfile.flush() 放入 ilra::~ilra()。日志记录和缓冲不是 friend 。

  2. static ofstream logfile 更改为 static ofstream *logfile:在 ilra_log_enabled() 中分配/删除它并添加 NULL checkin << 运算符。我更喜欢具有明确生命周期的对象。

总的来说,由于日志记录是一种性能消耗,我从不使用 iostreams 并坚持使用类似 printf() 的宏:日志检查是在没有函数调用的情况下进行的,就在宏中。这具有重要的副作用:如果不需要日志记录,则根本不会评估参数列表。在您的情况下,无法避免调用函数,例如systemIP()systemhostname(),因为日志级别/等的检查是在调用它们之后完成的。例如,使用宏,我还可以从发布版本中完全删除调试级别的日志记录(或推论:在调试版本中,我可以拥有尽可能多的日志记录)。

关于c++ - 将 ostream 重定向到文件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3189429/

相关文章:

c# - Nlog 和自定义级别

java - 从 Java 中的字符串在内存中创建 File 对象

C读取调用缓冲额外字符

java - Websphere 上的 Log4j LEVEL NULL

c++ - 编译 C++ 时 undefined reference

c++ - 成员未归零,一个 clang++ 错误?

c++ - 如何在 C++ 中重载模板的友元提取运算符 (>>)?

.net - 如何准确记录从 WCF 客户端发送和接收的消息

java - 如何在Java 7中递归读取文件?

c++ - 逐行读取文件并将其存储在 vector 中,对其进行处理