TtT23
TtT23

Reputation: 7030

Better way to handle asynchronous log writing

public static class LogWriter
{
    private static ReaderWriterLockSlim writeLock = new ReaderWriterLockSlim();
    public static void WriteExceptionLog(string content)
    {
        #if DEBUG
        MessageBox.Show(content);
        #endif
        WriteLog(content, Constant.EXCEPTION_LOG_PATH);
    }
    public static void WriteLog(string content, string path)
    {
        try
        {
            writeLock.EnterWriteLock();
            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(Path.GetDirectoryName(directory)))
                Directory.CreateDirectory(directory);
            using (StreamWriter writeFile = new StreamWriter(path, true))
            {
                content = DateTime.Now + " : " + content;
                writeFile.WriteLine(content);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            writeLock.ExitWriteLock();
        }
    }
}

I have a class that writes logs. Because I am writing to a log asynchronously, I need to put a lock and release it when write is done but this seems to be somewhat of a clunky solution and maybe even bad for performance.

What is a better way to handle this?

Upvotes: 2

Views: 1727

Answers (2)

Aubin
Aubin

Reputation: 14853

For performance reason and also to avoid a very different behavior between log-ON and log-OFF, I suggest to run one buffered log file per thread.

  • One per thread to avoid locking: no contention
  • Buffered to avoid disk latency

The counterparts are:

  • a merging tools based on time (milliseconds) is needed to see application activity as a whole (vs thread activity)
  • buffering may hide last log records in case of brutal termination

To go one step more to real-time, you have to log in memory, and to develop a dedicated interface to extract log on request but this kind of log is generally reserved to hard real-time embedded application.

Other solution for safe logging with low CPU consumption (low level C programming):

  • place a log record buffer into shared memory
  • the observed process act as log record producer
  • create a log manager process, with higher priority, which acts as log record consumer
  • manage the communication between consumer and producer behind a flip/flop mechanism: a pointer assignment under critical section.

If the observed process crash, no log record will be lost since shared memory segment is attached to log manager process.

Upvotes: 3

Yam Marcovic
Yam Marcovic

Reputation: 8141

Opening, writing to, and then closing the file on each log request is both redundant and inefficient.

On your log class, use a buffer, and write that buffer's contents to the file, either every X requests, shutdown, or every Y minutes.

Upvotes: 0

Related Questions