Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Make a Self Length Limiting Log File

4.82/5 (3 votes)
8 Jun 2017CPOL1 min read 6.6K  
How to make a self length limiting log file

Introduction

It's a common problem. You need a log file, but you need to make sure it never gets too big. A common solution is to write two log files and switch between them, deleting the old one when the newer one reaches a maximum length. Another way is to have 7 log files, one for each day of the week and overwrite them as each day changes.

This is a twist on filling this requirement. If the log file is smaller than the maximum size [iMaxLogLength], this just appends the message to be logged to the log file. If the log file is larger than that, it grabs [iTrimmedLogLength] number of bytes from the end of the existing log file and holds on to them, opens the file log file empty, writes the bytes it held onto from the original file and then appends the new message that was supposed to be logged.

Now the log file can go over the maximum size if the message to be logged is large enough, but there should be no harm done and anyway, it is probably the wrong tool for the job then.

Background

This is just written because I never found it written elsewhere. I use it for logging what is needed from a dashboard application. I need to know what it is doing and need to know about errors, but the users are never going to maintain any log.

Using the Code

C++
private void buttonLog_Click(object sender, EventArgs e)
{
    c_Log.writeToFile(textBoxMessages.Text, "../../log.log", 1);
}


public static class c_Log
{
    static int iMaxLogLength = 15000;
    static int iTrimmedLogLength = -1000; // minimum of how much of the old log to leave

    static public void writeToFile(string strNewLogMessage, string strFile, int iLogLevel)
    {
        try
        {
            FileInfo fi = new FileInfo(strFile);

            Byte[] bytesSavedFromEndOfOldLog = null;

            if (fi.Length > iMaxLogLength) // if the log file length is already too long
            {
                using (BinaryReader br = new BinaryReader
                (File.Open(strFile, FileMode.Open)))
                {
                    // Seek to our required position of what you want saved.
                    br.BaseStream.Seek(iTrimmedLogLength, SeekOrigin.End);

                    // Read what you want to save and hang onto it.
                    bytesSavedFromEndOfOldLog = br.ReadBytes((-1 * iTrimmedLogLength));
                }
            }

            byte[] newLine = System.Text.ASCIIEncoding.ASCII.GetBytes(Environment.NewLine);

            FileStream fs = null;
            // If the log file is less than the max length,
            // just open it at the end to write there
            if (fi.Length < iMaxLogLength)
                fs = new FileStream
                (strFile, FileMode.Append, FileAccess.Write, FileShare.Read);
            else // If the log file is more than the max length, just open it empty
                fs = new FileStream
                (strFile, FileMode.Create, FileAccess.Write, FileShare.Read);

            using (fs)
            {
                // If you are trimming the file length, write what you saved.
                if (bytesSavedFromEndOfOldLog != null)
                {
                    Byte[] lineBreak = Encoding.ASCII.GetBytes
                    ("### " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
                    " *** *** *** Old Log Start Position *** *** *** *** ###");
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(lineBreak, 0, lineBreak.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(bytesSavedFromEndOfOldLog, 0, bytesSavedFromEndOfOldLog.Length);
                    fs.Write(newLine, 0, newLine.Length);
                }
                Byte[] sendBytes = Encoding.ASCII.GetBytes(strNewLogMessage);
                // Append your last log message.
                fs.Write(sendBytes, 0, sendBytes.Length);
                fs.Write(newLine, 0, newLine.Length);
            }
        }
        catch (Exception ex)
        {
            ; //Nothing to do...
              //writeEvent("writeToFile()
              //Failed to write to logfile : " + ex.Message + "...", 5);
        }
    }
}

History

  • First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)