Hey, I figured someone here might know this:
I'm trying to implement a very simple logger that does two things:
- log levels
- outputs log to as many streams as I want it to.
Roughly speaking, the usage looks something like:
Currently, I don't yet have the LogLevel stuff working. So if we ignore the loglevel, it's pretty straight forward:
Then, just keep shoving what you get into all the streams.
But right off the bat, I am seeing an annoyance: I'd like to be able to call flush() on each of my output streams ONCE per "line of code" (for the lack of a better way of saying it). In other words, for something like:
I want to call flush() just once, after the whole "12345" has been shoved into my streams. Is there a way to do this without having to write a Logger::flush and call it manually? I'm thinking 'no'. And I'm thinking it probably doesn't matter (depending on implementation of flush I guess), but it's worth a shot hehe.
Secondly, I'm not really sure how I'll put the log levels in there. Should I just change the operator<< above to have these two instead:
and then have the loglevel one maintain an ostringstream, and have the Logger's operator<< look at logLevel and decide whether to publish the data? The problem I forsee there is that there's probably no guarantee on order of execution, so instead of the desirable:
It might try something goofy like:
Which would not even compile...
Thoughts?
I'm trying to implement a very simple logger that does two things:
- log levels
- outputs log to as many streams as I want it to.
Roughly speaking, the usage looks something like:
Logger log(LogLevel::WARNING);
log.attachStream(std::cerr); // and any others, say file handles....
log << LogLevel::ERROR << "uh-oh, " << 75 << " errors occured...\n";
Currently, I don't yet have the LogLevel stuff working. So if we ignore the loglevel, it's pretty straight forward:
template< typename T >
Logger &operator<<(Logger &logger, const T &x)
Then, just keep shoving what you get into all the streams.
But right off the bat, I am seeing an annoyance: I'd like to be able to call flush() on each of my output streams ONCE per "line of code" (for the lack of a better way of saying it). In other words, for something like:
log << 1 << 2 << 3 << 4 << 5;
I want to call flush() just once, after the whole "12345" has been shoved into my streams. Is there a way to do this without having to write a Logger::flush and call it manually? I'm thinking 'no'. And I'm thinking it probably doesn't matter (depending on implementation of flush I guess), but it's worth a shot hehe.
Secondly, I'm not really sure how I'll put the log levels in there. Should I just change the operator<< above to have these two instead:
template< typename T >
LogLevel &operator<<(LogLevel &logLevel, const T &x)
Logger &operator<<(Logger &logger, LogLevel &logLevel);
and then have the loglevel one maintain an ostringstream, and have the Logger's operator<< look at logLevel and decide whether to publish the data? The problem I forsee there is that there's probably no guarantee on order of execution, so instead of the desirable:
operator<<(log, operator<<(LogLevel::WARNING, "test"));
It might try something goofy like:
operator<<( operator<<(log, LogLevel::WARNING), "test" );
Which would not even compile...
Thoughts?