diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 33e09e221..26ff396d1 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Logging.Internal;
+using Dalamud.Logging.Retention;
using Dalamud.Plugin.Internal;
using Dalamud.Support;
using Dalamud.Utility;
@@ -88,58 +89,35 @@ public sealed class EntryPoint
var logFileName = logName.IsNullOrEmpty() ? "dalamud" : $"dalamud-{logName}";
#if DEBUG
- var logPath = Path.Combine(baseDirectory, $"{logFileName}.log");
- var oldPath = Path.Combine(baseDirectory, $"{logFileName}.old.log");
- var oldPathOld = Path.Combine(baseDirectory, $"{logFileName}.log.old");
+ var logPath = new FileInfo(Path.Combine(baseDirectory, $"{logFileName}.log"));
+ var oldPath = new FileInfo(Path.Combine(baseDirectory, $"{logFileName}.old.log"));
#else
var logPath = Path.Combine(baseDirectory, "..", "..", "..", $"{logFileName}.log");
var oldPath = Path.Combine(baseDirectory, "..", "..", "..", $"{logFileName}.old.log");
- var oldPathOld = Path.Combine(baseDirectory, "..", "..", "..", $"{logFileName}.log.old");
#endif
Log.CloseAndFlush();
-
-#if DEBUG
- var oldFileOld = new FileInfo(oldPathOld);
- if (oldFileOld.Exists)
- {
- var oldFile = new FileInfo(oldPath);
- if (oldFile.Exists)
- oldFileOld.Delete();
- else
- oldFileOld.MoveTo(oldPath);
- }
- CullLogFile(logPath, 1 * 1024 * 1024, oldPath, 10 * 1024 * 1024);
+ RetentionBehaviour behaviour;
+#if DEBUG
+ behaviour = new DebugRetentionBehaviour();
#else
- try
- {
- if (File.Exists(logPath))
- File.Delete(logPath);
-
- if (File.Exists(oldPath))
- File.Delete(oldPath);
-
- if (File.Exists(oldPathOld))
- File.Delete(oldPathOld);
- }
- catch
- {
- // ignored
- }
+ behaviour = new ReleaseRetentionBehaviour();
#endif
+ behaviour.Apply(logPath, oldPath);
+
var config = new LoggerConfiguration()
.WriteTo.Sink(SerilogEventSink.Instance)
.MinimumLevel.ControlledBy(LogLevelSwitch);
if (logSynchronously)
{
- config = config.WriteTo.File(logPath, fileSizeLimitBytes: null);
+ config = config.WriteTo.File(logPath.FullName, fileSizeLimitBytes: null);
}
else
{
config = config.WriteTo.Async(a => a.File(
- logPath,
+ logPath.FullName,
fileSizeLimitBytes: null,
buffered: false,
flushToDiskInterval: TimeSpan.FromSeconds(1)));
@@ -265,86 +243,6 @@ public sealed class EntryPoint
}
}
- ///
- /// Trim existing log file to a specified length, and optionally move the excess data to another file.
- ///
- /// Target log file to trim.
- /// Maximum size of target log file.
- /// .old file to move excess data to.
- /// Maximum size of .old file.
- private static void CullLogFile(string logPath, int logMaxSize, string oldPath, int oldMaxSize)
- {
- var logFile = new FileInfo(logPath);
- var oldFile = new FileInfo(oldPath);
- var targetFiles = new[]
- {
- (logFile, logMaxSize),
- (oldFile, oldMaxSize),
- };
- var buffer = new byte[4096];
-
- try
- {
- if (!logFile.Exists)
- logFile.Create().Close();
-
- // 1. Move excess data from logFile to oldFile
- if (logFile.Length > logMaxSize)
- {
- using var reader = logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- using var writer = oldFile.Open(FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
-
- var amountToMove = (int)Math.Min(logFile.Length - logMaxSize, oldMaxSize);
- reader.Seek(-(logMaxSize + amountToMove), SeekOrigin.End);
-
- for (var i = 0; i < amountToMove; i += buffer.Length)
- writer.Write(buffer, 0, reader.Read(buffer, 0, Math.Min(buffer.Length, amountToMove - i)));
- }
-
- // 2. Cull each of .log and .old files
- foreach (var (file, maxSize) in targetFiles)
- {
- if (!file.Exists || file.Length <= maxSize)
- continue;
-
- using var reader = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- using var writer = file.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
-
- reader.Seek(file.Length - maxSize, SeekOrigin.Begin);
- for (int read; (read = reader.Read(buffer, 0, buffer.Length)) > 0;)
- writer.Write(buffer, 0, read);
-
- writer.SetLength(maxSize);
- }
- }
- catch (Exception ex)
- {
- if (ex is IOException)
- {
- foreach (var (file, _) in targetFiles)
- {
- try
- {
- if (file.Exists)
- file.Delete();
- }
- catch (Exception ex2)
- {
- Log.Error(ex2, "Failed to delete {file}", file.FullName);
- }
- }
- }
-
- Log.Error(ex, "Log cull failed");
-
- /*
- var caption = "XIVLauncher Error";
- var message = $"Log cull threw an exception: {ex.Message}\n{ex.StackTrace ?? string.Empty}";
- _ = MessageBoxW(IntPtr.Zero, message, caption, MessageBoxType.IconError | MessageBoxType.Ok);
- */
- }
- }
-
private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
{
switch (args.ExceptionObject)
diff --git a/Dalamud/Logging/Retention/DebugRetentionBehaviour.cs b/Dalamud/Logging/Retention/DebugRetentionBehaviour.cs
new file mode 100644
index 000000000..719ff8ece
--- /dev/null
+++ b/Dalamud/Logging/Retention/DebugRetentionBehaviour.cs
@@ -0,0 +1,15 @@
+using System.IO;
+
+namespace Dalamud.Logging.Retention;
+
+///
+/// Class implementing log retention behaviour for debug builds.
+///
+internal class DebugRetentionBehaviour : RetentionBehaviour
+{
+ ///
+ public override void Apply(FileInfo logFile, FileInfo rolloverFile)
+ {
+ CullLogFile(logFile, 1 * 1024 * 1024, rolloverFile, 10 * 1024 * 1024);
+ }
+}
diff --git a/Dalamud/Logging/Retention/ReleaseRetentionBehaviour.cs b/Dalamud/Logging/Retention/ReleaseRetentionBehaviour.cs
new file mode 100644
index 000000000..79f272c46
--- /dev/null
+++ b/Dalamud/Logging/Retention/ReleaseRetentionBehaviour.cs
@@ -0,0 +1,15 @@
+using System.IO;
+
+namespace Dalamud.Logging.Retention;
+
+///
+/// Class implementing log retention behaviour for release builds.
+///
+internal class ReleaseRetentionBehaviour : RetentionBehaviour
+{
+ ///
+ public override void Apply(FileInfo logFile, FileInfo rolloverFile)
+ {
+ CullLogFile(logFile, 0, rolloverFile, 10 * 1024 * 1024);
+ }
+}
diff --git a/Dalamud/Logging/Retention/RetentionBehaviour.cs b/Dalamud/Logging/Retention/RetentionBehaviour.cs
new file mode 100644
index 000000000..66c4c5f97
--- /dev/null
+++ b/Dalamud/Logging/Retention/RetentionBehaviour.cs
@@ -0,0 +1,91 @@
+using System;
+using System.IO;
+
+using Serilog;
+
+namespace Dalamud.Logging.Retention;
+
+///
+/// Class implementing retention behaviour for log files.
+///
+internal abstract class RetentionBehaviour
+{
+ ///
+ /// Apply the specified retention behaviour to log files.
+ ///
+ /// The regular log file path.
+ /// The rollover "old" log file path.
+ public abstract void Apply(FileInfo logFile, FileInfo rolloverFile);
+
+ ///
+ /// Trim existing log file to a specified length, and optionally move the excess data to another file.
+ ///
+ /// Target log file to trim.
+ /// Maximum size of target log file.
+ /// .old file to move excess data to.
+ /// Maximum size of .old file.
+ protected static void CullLogFile(FileInfo logFile, int logMaxSize, FileInfo oldFile, int oldMaxSize)
+ {
+ var targetFiles = new[]
+ {
+ (logFile, logMaxSize),
+ (oldFile, oldMaxSize),
+ };
+ var buffer = new byte[4096];
+
+ try
+ {
+ if (!logFile.Exists)
+ logFile.Create().Close();
+
+ // 1. Move excess data from logFile to oldFile
+ if (logFile.Length > logMaxSize)
+ {
+ using var reader = logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ using var writer = oldFile.Open(FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
+
+ var amountToMove = (int)Math.Min(logFile.Length - logMaxSize, oldMaxSize);
+ reader.Seek(-(logMaxSize + amountToMove), SeekOrigin.End);
+
+ for (var i = 0; i < amountToMove; i += buffer.Length)
+ writer.Write(buffer, 0, reader.Read(buffer, 0, Math.Min(buffer.Length, amountToMove - i)));
+ }
+
+ // 2. Cull each of .log and .old files
+ foreach (var (file, maxSize) in targetFiles)
+ {
+ if (!file.Exists || file.Length <= maxSize)
+ continue;
+
+ using var reader = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ using var writer = file.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
+
+ reader.Seek(file.Length - maxSize, SeekOrigin.Begin);
+ for (int read; (read = reader.Read(buffer, 0, buffer.Length)) > 0;)
+ writer.Write(buffer, 0, read);
+
+ writer.SetLength(maxSize);
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex is IOException)
+ {
+ foreach (var (file, _) in targetFiles)
+ {
+ try
+ {
+ if (file.Exists)
+ file.Delete();
+ }
+ catch (Exception ex2)
+ {
+ Log.Error(ex2, "Failed to delete {file}", file.FullName);
+ }
+ }
+ }
+
+ Log.Error(ex, "Log cull failed");
+ }
+ }
+}