Reputation: 61
So I have a C++ program, that normally when it executes writes out things to a log file. This is done using an fstream. However, now I want to include functionality to turn the logging off. Essentially, my code looks like this:
bool isLogging;
fstream* logFilePtr;
throughout my code, there are a bunch of statements like:
(*logFilePtr) << " Kernel call time in seconds: " << kTime << endl;
...
Now, if the "isLogging" is true, I don't want these to print. I could just go surround them with a bunch of if statements, but I'd prefer something cleaner than that. I thought there was some way to take a C++ stream and redirect it to point to "nothing" so that when the << operator is used, nothing will print.
Does anyone know how to redirect the stream, or have any other ideas on how to handle this in an elegant way?
Thanks, Colin
Upvotes: 0
Views: 2069
Reputation: 158364
Under "other ideas on how to handle this":
Upvotes: 0
Reputation: 24612
std::ostream& Debug(int level) {
std::clog.clear(levell <= shown_level ? std::ios_base::goodbit: std::ios_base::badbit);
return std::clog;
}
From comp.lang.c++.
Upvotes: 0
Reputation: 25293
std::iostream doesn't allow OS-level redirection, however, you can share std::streambufs between std::iostreams:
int main() {
// redirect stdout to stderr:
std::streambuf * const oldstdout = std::cout.rdbuf();
std::cout.rdbuf( std::cerr.rdbuf() );
// test
std::cout << "Hello ";
std::cerr << "World" << std::endl;
// re-set, so streambufs are properly deleted:
std::cout.rdbuf( oldstdout );
// test
std::cout << "Hello ";
std::cerr << "World" << std::endl;
return 0;
}
This way, you can redirect logging to somewhere else (e.g. "/dev/null" :), or, if you follow avakar's answer, use nullbuf.
Upvotes: 1
Reputation: 32635
Take a look at rdbuf
member function. You can create a discarding stream buffer and associate it with your stream.
struct nullbuf: std::streambuf
{
int overflow(int c) { return traits_type::not_eof(c); }
};
Upvotes: 4
Reputation: 3699
I use POCO library's logging feature. It supports configuring channels - console, file, both. Configuring format of output and logging levels (trace, debug, error etc). I then surround the logging functionality with functions such as
inline void logError(const std::string & str)
{
#ifdef COMPILE_ERROR_LOGGING
g_pMyPocoLogger->error(str);
#endif
}
You can choose not to use the library but I still recommend surrounding your logging with a wrapper.
Upvotes: 0
Reputation: 27119
platform? if you are under unix you can write the file to /dev/null
Upvotes: 0
Reputation: 40224
You could wrap it up in a class.
class Log {
Log (fstream &s) : stream(s), enabled(false) { }
void Enable () { enabled = true; }
void Disable () { enabled = false; }
template<class T>
Log &operator<< (T const& rhs) {
if (enabled) stream << rhs;
return *this;
}
private:
fstream &stream;
bool enabled;
};
this isn't tested .. but the basic idea should be there.
Upvotes: 6