diff --git a/DarkRift.Server/Plugins/LogWriters/FileWriter.cs b/DarkRift.Server/Plugins/LogWriters/FileWriter.cs
index 37bae64..918e0a4 100644
--- a/DarkRift.Server/Plugins/LogWriters/FileWriter.cs
+++ b/DarkRift.Server/Plugins/LogWriters/FileWriter.cs
@@ -23,38 +23,138 @@ public sealed class FileWriter : LogWriter
///
/// The stream to the log file to write to.
///
- private StreamWriter LogFileStream { get; }
+ private StreamWriter LogFileStream { get; set; }
+
+ private readonly object streamLock = new object();
///
/// The directory we are writing to.
///
public string LogFilePath { get; private set; }
+ ///
+ /// The format of the path (used for rotation).
+ ///
+ public string LogFilePathFormat { get; private set; }
+
+ ///
+ /// The time this file started (for rotation).
+ ///
+ public DateTime LogCreated { get; private set; }
+
+ ///
+ /// Number of bytes written.
+ ///
+ public int LogBytesWritten { get; private set; }
+
+ ///
+ /// Maximum number of bytes (before rotating). 0 to disable.
+ ///
+ public int LogMaxBytes { get; private set; }
+
+ ///
+ /// Maximum number of seconds per log file (before rotating). 0 to disable.
+ ///
+ public int LogMaxTimeSeconds { get; private set; }
+
///
/// Creates a new file writer with the given plugin load data.
///
/// The data for this plugin.
public FileWriter(LogWriterLoadData logWriterLoadData) : base(logWriterLoadData)
{
- //Get the log directory concatenated with the date
- LogFilePath = string.Format(logWriterLoadData.Settings["file"], DateTime.Now);
- //Create the actual log directory (will do nothing if it already exists)
- Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
+ // Sore the format for creating the filename
+ LogFilePathFormat = logWriterLoadData.Settings["file"] ?? "Logs/{0:yyyy-MM-dd}/{0:HH-mm-ss}.txt";
+
+ // Get the maximum size (in MB, convert to bytes)
+ try
+ {
+ int logMaxSizeMB = int.Parse(logWriterLoadData.Settings["maxSize"] ?? "100");
+ LogMaxBytes = Math.Max(0, logMaxSizeMB * 1000000);
+ }
+ catch (FormatException)
+ {
+ LogMaxBytes = 0;
+ }
+
+ // Get the maximum time before rotation (in seconds)
+ try
+ {
+ LogMaxTimeSeconds = int.Parse(logWriterLoadData.Settings["maxTime"] ?? "86400");
+ }
+ catch (FormatException)
+ {
+ LogMaxTimeSeconds = 0;
+ }
+
+ CreateStream();
+ }
+
+ private void CreateStream()
+ {
+ // Only create a new stream if the file name is different from existing.
+ string newFilePath = string.Format(LogFilePathFormat, DateTime.Now);
+ if (LogFilePath is null || newFilePath != LogFilePath)
+ {
+ // Close the old stream, if open
+ if (!(LogFilePath is null))
+ {
+ LogFileStream.WriteLine($"Log File Continues in {newFilePath}");
+ CloseStream();
+ }
+
+ //Get the log directory concatenated with the date
+ LogFilePath = string.Format(LogFilePathFormat, DateTime.Now);
- //Create the log file and stream for it
- LogFileStream = new StreamWriter(LogFilePath);
+ //Create the actual log directory (will do nothing if it already exists)
+ Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
+
+ //Create the log file and stream for it
+ LogFileStream = new StreamWriter(LogFilePath);
+
+ // Write
+ if (!(LogFilePath is null))
+ {
+ LogFileStream.WriteLine($"Log File Continued from {LogFilePath}");
+ LogFileStream.Flush();
+ }
+
+
+ // Reset the counters
+ LogFilePath = newFilePath;
+ LogBytesWritten = 0;
+ LogCreated = DateTime.Now;
+ }
+ }
+
+ private void CloseStream()
+ {
+ LogFileStream.Flush();
+ LogFileStream.Close();
+ LogFileStream.Dispose();
}
///
public override void WriteEvent(WriteEventArgs args)
{
//Write to file
- lock (LogFileStream)
+ lock (streamLock)
{
LogFileStream.WriteLine(args.FormattedMessage);
LogFileStream.Flush();
+
+ // Remember number of btyes written
+ LogBytesWritten += args.FormattedMessage.Length + 2;
+
+ // If limits exceeded, then rotate while lock still in place
+ // Will only rotate is log file older than a second (to avoid naming clashes)
+ if ((LogMaxBytes > 0 && LogBytesWritten >= LogMaxBytes)
+ || (LogMaxTimeSeconds > 0 && (int)DateTime.Now.Subtract(LogCreated).TotalSeconds >= LogMaxTimeSeconds)
+ ) {
+ CreateStream();
+ }
}
}
@@ -63,8 +163,8 @@ protected override void Dispose(bool disposing)
{
if (disposing)
{
- lock (LogFileStream)
- LogFileStream.Dispose();
+ lock (streamLock)
+ CloseStream();
}
base.Dispose(disposing);
}