Delete log files after x days
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();
}
}
Related videos on Youtube
Freddy
Updated on April 03, 2020Comments
-
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 over 10 yearsWhat 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 over 10 years@UriAbramson IMHO these are mutual exclusive settings.
-
Edwin Stoteler over 8 years@ccellar I know this is old, but now you have: archiveNumbering="DateAndSequence"
-
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 over 7 yearsCool! Thx for that!
-
Frode Nilsen over 6 yearsIs "${basedir}/logs/logfile.txt" cleared after the archive is created?
-
ccellar almost 6 years@FrodeNilsen yes
-
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.