mystack
mystack

Reputation: 5492

Writing log to a text file not working as expected

I have a log class as given below.

public  class Log
{
    public  StreamWriter logFile
    { get; set; }

    public  string logFilePath = Environment.GetEnvironmentVariable("Temp")+"\\testlog.txt";

    public  string LogFilePath
    {
        get
        {
            return logFilePath;
        }
        set
        {
            value = logFilePath;
        }
    }

    public  void WriteLog(string logMessage)
    {
        try
        {
            if (!File.Exists(logFilePath))
            {
                logFile = new StreamWriter(logFilePath);
            }
            else
            {
                logFile = File.AppendText(logFilePath);
            }

            logFile.WriteLine(DateTime.Now);
            logFile.WriteLine(logMessage.ToString());
            logFile.WriteLine();
            logFile.Flush();
        }
        catch
        {
        }
    }
}

I called the above WriteLog function in Log class by using the object as given below.

Log lg = new Log();
lg.WriteLog("message1");
lg.WriteLog("message2");
lg.WriteLog("message3");
lg.WriteLog("message4");

Issue is that only "message1" is added to the log. All other other messages are not written.

How can I solve this?

Upvotes: 0

Views: 2479

Answers (4)

Roland Mai
Roland Mai

Reputation: 31077

There are two writers on the same file. The StremWriter and the second File.AppendText. The latter will open a new stream which won't be writeable. So, in code (untested), move the initialization of the stream in the constructor:

public class Log : IDisposable
{
    public const string logFilePath = Environment.GetEnvironmentVariable("Temp")+"\\testlog.txt";

    public Log() 
    {
            try
            {
                logFile = new StreamWriter(logFilePath);
            }
            catch
            {
                logFile = File.AppendText(logFilePath);
            }
    }

    public  StreamWriter logFile { get; set; }

    public  string LogFilePath
    {
        get
        {
            return logFilePath;
        }
        set
        {
            value = logFilePath;
        }
    }

    public  void WriteLog(string logMessage)
    {
        logFile.WriteLine(DateTime.Now);
        logFile.WriteLine(logMessage.ToString());
        logFile.WriteLine();
        logFile.Flush();
    }

    public void Dispose()
    {
        logfile.Dispose();
    }
}

Upvotes: 0

Matthew Watson
Matthew Watson

Reputation: 109567

Your problem is you are not closing the log file, so when you write to it the next time it's still open (because the garbage collector hasn't run yet and closed it for you).

That means you get an exception for subsequent calls to the logging function, which you are hiding with an empty catch (which is bad!).

You must close or dispose the file. The best way is to enclose it all in a using. That means you don't need the flush either (because closing/disposing a FileStream will flush it first).

A using will ensure that it closes even if an exception occurs. In fact, I think you can simplify the whole thing to this:

public void WriteLog(string logMessage)
{
    using (var logFile = File.AppendText(logFilePath))
    {
        logFile.WriteLine(DateTime.Now);
        logFile.WriteLine(logMessage);
        logFile.WriteLine();
    }
}

File.AppendText() will create a new file if one doesn't already exist, so you don't need to check first.

And about the empty catch that you had. Never do that. Always at least log the exception message. If you had done that, you would have seen that an exception was occurring, and you would have seen what it was - and that would probably have told you what was going wrong.

Upvotes: 3

Sandeep Kumar
Sandeep Kumar

Reputation: 803

you need to close the writestream after Flush

Add

          logFile.Close();

like

            logFile.WriteLine();
            logFile.Flush();
            logFile.Close();

Upvotes: 1

Darko Kenda
Darko Kenda

Reputation: 4960

Add a logFile.Close() after logFile.Close(). You are getting an exception about the file being in use but are silently ignoring it.

Also you should use

System.IO.Path.GetTempPath()

instead of

Environment.GetEnvironmentVariable("Temp")

since the former is more reliable.

Upvotes: 2

Related Questions