Delete log files after x days

31,195

Solution 1

You could simply use the built-in archiving functionality. This setting will keep 7 old log files in addition to your current log. The cleanup is done by NLog automatically.

<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets>
        <target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}" 
            fileName="${basedir}/logs/logfile.txt" 
            archiveFileName="${basedir}/logs/log.{#}.txt"
            archiveEvery="Day"
            archiveNumbering="Rolling"
            maxArchiveFiles="7"
            concurrentWrites="true" />
    </targets>

    <rules>
        <logger name="*" minlevel="Debug" writeTo="file" />
    </rules>
</nlog>

See also the documentation of the file target

Solution 2

I found that if I archive files with date-stamps in the log filenames, the archive log gets confused and {#} always translates to "0" causing old logs to never get deleted. Also, if I use a GDC reference in the log filename, it doesn't switch logs at all.

I now have to manually delete old logs if I want these fancy log filenames. The fact that they have the date in the filename causes them to automatically switch files.

// Delete log files older than X days

var dirInfo = new DirectoryInfo(".");
var oldestArchiveDate = DateTime.Now - new TimeSpan(30, 0, 0, 0);
foreach (FileInfo fi in dirInfo.GetFiles())
    if (fi.Name.StartsWith("log-") && fi.Name.EndsWith(".txt") && fi.CreationTime < oldestArchiveDate)
        fi.Delete();

var midnight = DateTime.Today.AddDays(1);
_oldLogCleanUpThread = new System.Threading.Timer(OldLogCleanUpThreadMethod, null, midnight - DateTime.Now, TimeSpan.FromDays(1));

nlog target:

 filename="${environment:variable=HOMEDRIVE}${environment:variable=HOMEPATH}\logs\log-${gdc:item=MySpecialId}-${date:format=yyyyMMdd}.txt"
GDC.Set("MySpecialId", ...);

Solution 3

I don't know if this answers your question, but it looks like the maxArchiveFiles should do what you want. I have not actually used this option myself, so I can't say for sure. You can certainly "archive" your log files in the same folder.

If it were me, I would make a very small program that does some logging and set the time (archiveEvery="minute") so that it is easy to force the archiving logic to kick in. Set maxArchiveFiles to something like 5 and see if NLog keeps only 5 log files. Run your program for a while, maybe generating log messages via a timer so you can easily space the log messages over enough time that NLog's archiving/rolling logic kicks in.

Experiment with the archive file naming template. Using the archiveNumbering option gives you some control over how the archive files are numbered.

Sorry I could not give a more definitive answer or a concrete example, but I have not used those options either, so I would just have to do the same experiment(s) and I am pressed for time right now.

Solution 4

You can use the name of the day and set the maxArchiveFiles to a fixed number. For example, foreach day of the week you could store a max of 100 files of 100Kb:

<variable name="dayname" value="${date:format=dddd}" />

<target name="logfile" xsi:type="File"
        fileName="${basedir}/Logs/MyLog_${dayname}.txt"
        archiveFileName="${basedir}/Logs/Archives/MyLog_${dayname}.{#####}.txt"
        archiveAboveSize="102400"
        archiveNumbering="Sequence"            
        maxArchiveFiles="100"
        concurrentWrites="true"
        keepFileOpen="false"
        encoding="iso-8859-2" />   

Solution 5

     //Store the number of days after which you want to delete the logs.
     int Days = 30;

     // Storing the path of the directory where the logs are stored.
     String DirPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Substring(6) + "\\Log(s)\\";

     //Fetching all the folders.
     String[] objSubDirectory = Directory.GetDirectories(DirPath);

     //For each folder fetching all the files and matching with date given 
     foreach (String subdir in objSubDirectory)     
        {
            //Getting the path of the folder                 
            String strpath = Path.GetFullPath(subdir);
            //Fetching all the files from the folder.
            String[] strFiles = Directory.GetFiles(strpath);
            foreach (string files in strFiles)
            {
                //For each file checking the creation date with the current date.
                FileInfo objFile = new FileInfo(files);
                if (objFile.CreationTime <= DateTime.Now.AddDays(-Days))
                {
                    //Delete the file.
                    objFile.Delete();
                }
            }

            //If folder contains no file then delete the folder also.
            if (Directory.GetFiles(strpath).Length == 0)
            {
                DirectoryInfo objSubDir = new DirectoryInfo(subdir);
                //Delete the folder.
                objSubDir.Delete();
            }

        }
Share:
31,195

Related videos on Youtube

Freddy
Author by

Freddy

Updated on April 03, 2020

Comments

  • Freddy
    Freddy almost 4 years

    I would like to log with Nlog using the file target like in this example. How can I realize a deletion of the files after X days without archiving them? Or is it possible to archive the files to the same folder?

  • Uri Abramson
    Uri Abramson over 10 years
    What happens if i use archiveAboveSize? this will no longer work because if i have 7 files in a single day it would delete all the rest. Is there a solution for this?
  • ccellar
    ccellar over 10 years
    @UriAbramson IMHO these are mutual exclusive settings.
  • Edwin Stoteler
    Edwin Stoteler over 8 years
    @ccellar I know this is old, but now you have: archiveNumbering="DateAndSequence"
  • Julian
    Julian over 7 years
    @ccellar I would like to add this to the SO documentation, but I do need some votes: stackoverflow.com/documentation/nlog/commit. Could you help?
  • Julian
    Julian over 7 years
    Cool! Thx for that!
  • Frode Nilsen
    Frode Nilsen over 6 years
    Is "${basedir}/logs/logfile.txt" cleared after the archive is created?
  • ccellar
    ccellar almost 6 years
    @FrodeNilsen yes
  • Rudimentary
    Rudimentary over 5 years
    +1 After determining NLog may not have the exact feature needed, proposing the simple straightforward solution to the original question as opposed to a work around.

Related