0

Hey so I have a logger class that is called frequently, sometimes when its called fast repeatedly it will throw an exception that the file is already open being used by another application. The only way we found a way around this was to catch the exception then try to open it again... I'm not sure how to handle this properly.

    /// <summary>
    /// Open a log file based on a date
    /// </summary>
    /// <param name="date"> Date of the file to open </param>
    public static void OpenLogFile(DateTime date)
    {
        while (true)
        {
            try
            {
                logStream = File.Open("Logs/ems." + date.ToString("yyyy-MM-dd") + ".log", FileMode.Append);
                break;
            }
            catch
            {
                continue;
            }
        }
    }




    /// <summary>
    /// Writes to a log file the specified input
    /// </summary>
    /// <param name="input"> Content to write to the log file </param>
    public static void Log(string className, string methodName, string input)
    {
            OpenLogFile(DateTime.Now);

            using (StreamWriter s = new StreamWriter(logStream))
            {
                s.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + '[' + className + '.' + methodName + "] " + input);
            }

            CloseLogFile(); 
    }




    /// <summary>
    /// Closes the current log file
    /// </summary>
    public static void CloseLogFile()
    {
        if (logStream != null)
        {
            logStream.Close();
            logStream = null;
        }
    }
1
  • I'm guessing it's a multi-threaded application? You could use an AutoResetEvent to control access to the file. Commented Dec 12, 2012 at 1:45

2 Answers 2

5

Since this is a log file, I think the obvious (and correct) solution, is to leave the file open for the duration of your program's execution.

If you don't want to use an already-implemented 3rd party logger, like Apache's log4net, you could write your own little logger class that uses thread-safe mechanisms for writing lines to the file.

It would probably be a static class, or singleton. Generally, execution at the beginning and end of your program is quite predictable, so it should be clear where to initialize, and close out the object/class.

Sign up to request clarification or add additional context in comments.

3 Comments

Make sure you use flush after each write (so the log is kept current).
opening a file can have pretty high overhead relative to actually writing to it, i'd only close it if absolutely necessary.
I would add a lock(threadObject) in your Log function. To second the other's if you are writing to the file that much I would leave it open. Microsoft Enterprise Library is another out of the box logging solution you can use. It will create the file, cut if off after certain sizes, purge after so long, do your laundry, ...
1

A bit of order is required, not a disk free-for-all. Store log messages in a queue and have a single thread dequeue and write items.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.