tags:

views:

136

answers:

4

I'm a newbie C++ developer and I'm working on an application which needs to write out a log file every so often, and we've noticed that the log file has been corrupted a few times when running the app. The main scenarios seems to be when the program is shutting down, or crashes, but I'm concerned that this isn't the only time that something may go wrong, as the application was born out of a fairly "quick and dirty" project.

It's not critical to have to the most absolute up-to-date data saved, so one idea that someone mentioned was to alternatively write to two log files, and then if the program crashes at least one will still have proper integrity. But this doesn't smell right to me as I haven't really seen any other application use this method.

Are there any "best practises" or standard "patterns" or frameworks to deal with this problem?

At the moment I'm thinking of doing something like this -

  1. Write data to a temp file
  2. Check the data was written correctly with a hash
  3. Rename the original file, and put the temp file in place.
  4. Delete the original

Then if anything fails I can just roll back by just deleting the temp, and the original be untouched.

+2  A: 

You probably forgot to call fsync() every so often, or the data comes in from different threads without proper synchronization among them. Hard to tell without more information (platform, form of corruption you see).

A workaround would be to use logfile rollover, ie. starting a new file every so often.

+2  A: 

I really think that you (and others) are wasting your time when you start adding complexity to log files. The whole point of a log is that it should be simple to use and implement, and should work most of the time. To that end, just write the log to an unbuffered stream (l;ike cerr in a C++ program) and live with any, very occasional in my experience, snafus.

OTOH, if you really need an audit trail of everything your app does, for legal reasons, then you should be using some form of transactional storage such as a SQL database.

anon
+3  A: 

You must find the reason why the file gets corrupted. If the app crashes unexpectedly, it can't corrupt the file. The only thing that can happen is that the file is truncated (i.e. the last log messages are missing). But the app can't really jump around in the file and modify something elsewhere (unless you call seek in the logging code which would surprise me).

My guess is that the app is multi threaded and the logging code is being called from several threads which can easily lead to data corrupted before the data is written to the log.

Aaron Digulla
+1 This is most likely whats going on
luke
+1 Yeah, most probably.
neuro
Yes the application is multithreaded, so I'm starting by making the logging thread safe, to see how much that fixes the problems
J_men
+1  A: 

Not sure if your app is multi-threaded -- if so, consider using Active Object Pattern (PDF) to put a queue in front of the log and make all writes within a single thread. That thread can commit the log in the background. All logs writes will be asynchronous, and in order, but not necessarily written immediately.

The active object can also batch writes.

Lou Franco
+1 correct way to handle the MT problem ...
neuro