我有一个自定义日志记录系统,它允许我根据当前选择的详细程度将信息发送到日志文件和控制台。现在,我遇到的麻烦是输出到文件,输出到控制台工作正常。
以下是一个例子:
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
答案 0 :(得分:1)
我发现代码没有完全错,但我本人会做出两处修改:
将logfile.flush()放入ilra :: ~ilra()。记录和缓冲不是朋友。
将static ofstream logfile
更改为static ofstream *logfile
:在ilra_log_enabled()
中分配/删除它,并在&lt;&lt;&lt;&lt;&lt;运营商。我喜欢具有明确生命周期的物体。
总的来说,由于日志记录是一种性能问题,我从来没有使用iostreams并坚持使用printf() - 就像宏一样:在没有函数调用的情况下进行日志记录检查,就在宏中。这具有重要的副作用:如果不需要记录,则根本不评估参数列表。在你的情况下,不可能避免被调用的函数,例如systemIP()
和systemhostname()
,因为日志级别/等的检查是在已经调用之后完成的。使用宏我还可以从发布版本中删除完全调试级别的日志记录(或者推论:在调试版本中,我可以根据需要获得尽可能多的日志记录)。
答案 1 :(得分:0)
看起来“测试”最有可能是从其他地方打印出来的,实际上log_enabled
未设置在您将数据插入流中的位置。您是否曾尝试无条件地将数据插入logfile
流,或者每次调用log_enabled
时打印出operator<<
?
或者,cout
的类型为ostream
,logfile
的类型为ofstream
。转发操纵器的功能是否可能无法完成ofstream
的工作?