using System; using System.IO; using System.Linq; namespace ExtremelySimpleLogger { /// /// A that writes log output to a set of directories. /// This sink differs from in that it manages multiple log files in a directory, where a new file will be created every time the sink is created. /// Additionally, this sink will automatically delete the oldest log files if the amount of files exceeds a set limit. /// public class DirectorySink : Sink { private const string DefaultDateFormat = "yy-MM-dd_HH-mm-ss"; private readonly FileInfo file; private readonly StreamWriter writer; private readonly bool reopenOnWrite; /// /// Creates a new directory sink with the given settings. /// /// The directory that this sink should operate in /// The maximum amount of files that can exist in the directory before the oldest one gets deleted. 10 by default. /// Whether this sink should reopen the file every time it logs to it. If this is false, the file will be kept open by this sink. /// The way the name of the current log file gets formatted. yy-MM-dd_HH-mm-ss by default. public DirectorySink(string directory, int maxFiles = 10, bool reopenOnWrite = false, string dateFormat = DefaultDateFormat) : this(new DirectoryInfo(directory), maxFiles, reopenOnWrite, dateFormat) { } /// /// Creates a new directory sink with the given settings. /// /// The directory that this sink should operate in /// The maximum amount of files that can exist in the directory before the oldest one gets deleted. 10 by default. /// Whether this sink should reopen the file every time it logs to it. If this is false, the file will be kept open by this sink. /// The way the name of the current log file gets formatted. yy-MM-dd_HH-mm-ss by default. public DirectorySink(DirectoryInfo directory, int maxFiles = 10, bool reopenOnWrite = false, string dateFormat = DefaultDateFormat) { this.reopenOnWrite = reopenOnWrite; if (!directory.Exists) directory.Create(); // delete old files var files = directory.GetFiles(); if (files.Length >= maxFiles) { // order files by their creation time so that older files are deleted first var ordered = files.OrderBy(f => f.CreationTime).ToList(); while (ordered.Count >= maxFiles) { ordered[0].Delete(); ordered.RemoveAt(0); } } var date = DateTime.Now.ToString(dateFormat); this.file = new FileInfo(Path.Combine(directory.FullName, $"{date}.txt")); if (!reopenOnWrite) { this.writer = this.file.AppendText(); this.writer.AutoFlush = true; } } /// /// Logs the given message, which has already been formatted using . /// /// The logger that the message was passed to /// The importance level of this message /// The message to log protected override void Log(Logger logger, LogLevel level, string s) { lock (this.file) { if (this.reopenOnWrite) { using (var w = this.file.AppendText()) w.WriteLine(s); } else { this.writer.WriteLine(s); } } } /// /// Disposes this sink, freeing all of the resources it uses. /// public override void Dispose() { base.Dispose(); lock (this.file) { if (!this.reopenOnWrite) this.writer.Dispose(); } } } }