views:

70

answers:

2

I am on MacOSX. I am writing a multi threaded program. One thread does logging. The non-logging threads may crash at any time.

What conventions should I adopt in the logger / what guarantees can I have?

I would prefer a solution where even if I crash during part of a write, previous writes still go to disk, and when reading back the log, I can figure out "ah, I wrote 100 complete enties, then I crashed on the 101th".

Thanks!

+1  A: 

I program on Linux, not MacOSX, but probably it's the same there.

If only one thread in your program logs, it means that you buffer the logging data in this logging thread and then it writes it to a file probably some larger portion to avoid too many I/O operations and make the logging process faster.

The bad thing is that if one thread segfaults, the whole process is destroyed along with the buffered data.

The solutions (for Linux) I know of are:

  1. Transfer the logging data through a socket, without using buffering logging thread (syslog for example). In this case the OS will probably take care of the data, written to the socket, and even if your application crashes, the data should be received on the other end and logged successfully.

  2. Don's use logging thread, every thread can log synchronously to a file. In this case the losses of the log data after the crash should be very small or none. It's slower though.

I don't know better solutions for this problem yet, it would be interesting to learn ones though.

Dmitry Yudakov
+1 Yes, very much the same. I don't see a great advantage of having a separate thread for logging, especially if you want to guarantee you have written the log output. If you call `flush()` on the output stream, you ensure the data is written. By logging asynchronously, you actually introduce a window where the process could crash before the logging thread has written its output.
gavinb
+1  A: 

As Dmitry says, there's only a few options to ensure you actually capture he logging output. Do you really need to write your own? And does it really need to be on another thread? This may introduce a timing window for a crash to miss logs, when you normally want to log synchronously.

The syslog facility on Unix is the standard means for reliable logging for system services. It essentially solves these sorts of problems you describe (ie. logs are processed out-of-process, so if you crash, your logs still get saved).

If your application is aimed only at Mac OS X, you should have a look at the Apple System Log facility (ASL). It provides a more sophisticated API than syslog and a superset of its functionality.

gavinb