boost::log was in sandbox for well over 4 years. Very, very verbose! Might have changed since I last used it though. Uses template-based constructs to create filters... efficient but slow as all hell on compilation. Also doesn't have anything to handle removing log entries.

@LB
I wasn't aware that enum classes exist. I thought you were talking about doing something like

1234

class abc {
public:
constexprint a = 0, b = 1, c = 2;
};

I was also suggesting that maybe you should keep what you find annoying about other people's code to yourself when it's perfectly clear what they're doing. Instead of trying to be all clever with your little winky faces, you should have just said "You can use an enum class instead of doing that namespace/typedef thing".

Well, for one, while standard IO is thread-safe (but only in latest C++11 standard), it doesn't care to syncronize the IO. For instance, one thread can give IO and another thread can give IO at the same time so you can have messages like so:

"[Err[Warning]Library not found.or]Failed to initialize." or
"[E[Warrrniorng]L" well you get the picture...

So if you use a threaded application, you have to do this yourself. Some log libraries don't claim thread safety but claim output synchronization. This is what that means (I guess...)

Moving further, default IO has no facilities to handle things like assertions based on loglevel, giving different information given different log levels. You have to provide these facilities either yourself or given a log library.

Even further, you'd have to wrap any lines meant only for debugging in something that removes the code in non-debug builds. Again, log libraries can do this for you.

Even further, you can have configuration files that define what type of information you want which is easier to change on the fly and doesn't require you to recompile your code.

And there's probably more stuff I'm leaving out (like backtraces which some logging libraries can do). It's just one of those things that you use and kinda think it's silly not to use later on.

Even further, you'd have to wrap any lines meant only for debugging in something that removes the code in non-debug builds. Again, log libraries can do this for you.

Right, but I can't see how it can be achieved in any language with static compilation model. The problem is, you really don't want to ship two different binaries - one with debug logging and one without. If your customer hits a problem, the last thing he wishes to do is to reinstall the application and install binary that has debug logging compiled in. From my experience I can tell, that during this process 1 out of 3 customers would screw the application even further. The perfect solution is just turning debugging on in a config file without restarting the application and the app should pick it up.

The most useful thing that logging libraries provide is ability to configure different levels of logging for different modules of the application and dynamically change it without restarting the app (don't know whether C++ libs do that, but log4j does that extremely well). So you can have one suspected module logging at DEBUG, but all the rest at WARN or INFO. Therefore you don't get spammed, but you can still get to the fine details.

Some things are truly meant for verbose debugging and are sometimes just non-sense and/or should never happen. In real-time applications, you need to cut down on logging statements such as to reduce latency issues.

Well, for one, while standard IO is thread-safe (but only in latest C++11 standard), it doesn't care to syncronize the IO. For instance, one thread can give IO and another thread can give IO at the same time so you can have messages like so:

"[Err[Warning]Library not found.or]Failed to initialize." or
"[E[Warrrniorng]L" well you get the picture...

@Fredbill30
I think his point was that a synchronised, thread-safe logging library would implement the semaphores (actually you would want to use mutexes (although really a mutex is a type of semaphore) because a semaphore would still allow multiple threads to access IO at the same time) so you wouldn't have to do it yourself.

There are other methods... the main point is to simply make sure one message is finished before writing another, something a mutex is well used for. While a mutex sounds to fit, it could also be placed in an asyncronous queue and then executed in FIFO outside of the main application to perhaps minimize the time waiting. Sounds a bit naive though and I'm not familiar with common implementations.