we are using Poco logging (v1.4.1) on Windows and Linux x86-64, and we noticed that, when using a high log level, it's very slow on Windows, which suggested unbuffered I/O. The Poco documentation did not mention any way to change this behavior, so I looked at the Poco source code. It turned out that LogFileImpl for Win32 always first calls WriteFile which directly passes the message to the OS, then FlushFileBuffers which is a flush to disk operation.
On Unix however, the LogFile_std.cpp does
- Code: Select all
_str << text << std::endl;
which effectively calls flush() on the underlying std::ostream every time, which is a flush to OS operation. So this would be equivalent to calling WriteFile but not FlushFileBuffers on Win32.
For our purposes, and I guess for most applications, flushing every message to disk is excessive as this is only adds additional safety in the event of a system crash, hard reset, power failure or maybe sudden unplugging of the device. On the other hand, this greatly limits the performance of logging and may affect the performance of other parts of the application if they perform some activity on the same disk. This is a problem when generating debug or trace logs, as our customers will occasionally have to do when there's an issue with our application. As mentioned above, this only affects Windows, on Linux there is no flush to disk but only to the operating system. This means, when the logging call returns, the data is guaranteed to be in the OS cache but probably not the device yet. This is ok for our purposes since we are mostly concerned about application crashes and not system crashes.
For now, we consider creating a custom subclass of Poco::FileLogger and overriding the write method at least to only use WriteFile. Shouldn't there be an easier way though especially given that Win32 and Unix behavior are different? It's quite unusual for a logging framework to perform a flush to disk after every message also.
EDIT: Completed the post after submitting too early.