将 ostream 重定向到文件不起作用
我有一个自定义日志记录系统,它允许我根据当前选择的详细程度将信息发送到日志文件和控制台。现在,我遇到的问题是输出到文件,输出到控制台工作正常。
下面是一个示例:
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
I have a custom logging system which allows me to send information to a log file and the console depending on the verbosity currently selected. Right now, the trouble I am having is with the output to the file, with output to the console working fine.
Here is an example:
ilra_talk << "Local IP: " << systemIP() << " | Hostname: " << systemhostname() << endl;
// the systemIP() and systemhostname() functions have already been defined
This should result in the current local IP and hostname of the system being printed to a file. However, it is only resulting in the information being printed to the console, despite how the function is overloaded to result in it printing to both.
I've outlined the code below. Any assistance is appreciated (as always).
A definition currently exists for ilra_talk which results in a new class object being created:
#define ilra_talk ilra(__FUNCTION__,0)
The class definition the following:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为代码没有完全错误,尽管我个人会进行两项更改:
将 logfile.flush() 放入 ilra::~ilra() 中。日志记录和缓冲不是朋友。
将
static ofstream logfile
更改为static ofstream *logfile
:在ilra_log_enabled()
中分配/删除它,并在ilra_log_enabled()
中添加 NULL 检查。 <运营商。我更喜欢具有明确生命周期的对象。总的来说,由于日志记录非常消耗性能,因此我从不使用 iostream,而是坚持使用类似 printf() 的宏:日志记录检查是在宏中进行的,无需函数调用。这有一个重要的副作用:如果不需要日志记录,则根本不会评估参数列表。在您的情况下,不可能避免调用函数,例如
systemIP()
和systemhostname()
,因为对日志级别/等的检查是在它们已经完成之后完成的。已被调用。例如,使用宏,我还可以从发布版本中完全删除调试级日志记录(或推论:在调试版本中,我可以拥有尽可能多的日志记录)。I see nothing totally wrong with the code, though I personally would have made two changes:
Put the logfile.flush() into the ilra::~ilra(). Logging and buffering are no friends.
Change
static ofstream logfile
tostatic ofstream *logfile
: allocated/delete it inilra_log_enabled()
and add NULL check in the << operators. I prefer objects with explicit life cycle.Overall, since logging is a performance hog, I never use the iostreams for it and stick with the printf()-like macros: logging check is made without a function call, right in the macro. That has important side-effect: if no logging is needed then the parameter list isn't evaluated at all. In your case it is impossible to avoid the functions being called, e.g.
systemIP()
andsystemhostname()
, since the check for log level/etc is done after they are already have been called. With the macros I can also for example remove completely debug-level logging from release builds (or corollary: in a debug build I can have as much logging as I want).看起来“Test”很可能是从其他地方打印出来的,事实上
log_enabled
在您将数据插入流中时并未设置。您是否尝试过无条件地将数据插入到logfile
流中,或者在每次调用operator<<
时打印出log_enabled
?或者,
cout
的类型为ostream
,logfile
的类型为ofstream
。您的转发操纵器功能是否有可能没有为ofstream
完成其工作?It looks like "Test" is most likely being printed from somewhere else, and that in fact
log_enabled
isn't set at the point you're inserting data into the stream. Have you tried unconditionally inserting the data into thelogfile
stream, or printing outlog_enabled
every timeoperator<<
is called?Alternately,
cout
has typeostream
andlogfile
has typeofstream
. Is it possible that your function to forward manipulators isn't doing its job forofstream
?