Click here to Skip to main content
15,888,610 members
Articles / Programming Languages / C#
Tip/Trick

Make a Self Length Limiting Log File

Rate me:
Please Sign up or sign in to vote.
4.82/5 (3 votes)
8 Jun 2017CPOL1 min read 6.2K   3   2
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)


Written By
Software Developer (Senior) Magellan Health Services
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionInteresting, but why not use log4net Pin
ahagel9-Jun-17 18:55
professionalahagel9-Jun-17 18:55 
Questioncharacter encoding Pin
sx20089-Jun-17 15:21
sx20089-Jun-17 15:21 
Encoding:
Windows -> ANSI
MS DOS -> ASCII

C#
Byte[] sendBytes = Encoding.ASCII.GetBytes(strNewLogMessage);  // wrong
byte[] sendBytes = Encoding.Default.GetBytes(strNewLogMessage);  // correct

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.