mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Implement manual log file rotating and culling
This commit is contained in:
parent
f66e5ca08b
commit
61b5b2631f
2 changed files with 132 additions and 13 deletions
|
|
@ -128,12 +128,58 @@ namespace Dalamud.Injector
|
||||||
levelSwitch.MinimumLevel = LogEventLevel.Information;
|
levelSwitch.MinimumLevel = LogEventLevel.Information;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CullLogFile(logPath, 1 * 1024 * 1024);
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.WriteTo.Async(a => a.File(logPath))
|
.WriteTo.Async(a => a.File(logPath))
|
||||||
.MinimumLevel.ControlledBy(levelSwitch)
|
.MinimumLevel.ControlledBy(levelSwitch)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CullLogFile(string logPath, int cullingFileSize)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var bufferSize = 4096;
|
||||||
|
|
||||||
|
var logFile = new FileInfo(logPath);
|
||||||
|
|
||||||
|
if (!logFile.Exists)
|
||||||
|
logFile.Create();
|
||||||
|
|
||||||
|
if (logFile.Length <= cullingFileSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var amountToCull = logFile.Length - cullingFileSize;
|
||||||
|
|
||||||
|
if (amountToCull < bufferSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
|
using var writer = new BinaryWriter(logFile.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite));
|
||||||
|
|
||||||
|
reader.BaseStream.Seek(amountToCull, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var read = -1;
|
||||||
|
var total = 0;
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
while (read != 0)
|
||||||
|
{
|
||||||
|
read = reader.Read(buffer, 0, buffer.Length);
|
||||||
|
writer.Write(buffer, 0, read);
|
||||||
|
total += read;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.BaseStream.SetLength(total);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
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 Process GetProcess(string arg)
|
private static Process GetProcess(string arg)
|
||||||
{
|
{
|
||||||
Process process;
|
Process process;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ using Serilog;
|
||||||
using Serilog.Core;
|
using Serilog.Core;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
|
using static Dalamud.NativeFunctions;
|
||||||
|
|
||||||
namespace Dalamud
|
namespace Dalamud
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -43,11 +45,16 @@ namespace Dalamud
|
||||||
/// <param name="info">The <see cref="DalamudStartInfo"/> containing information needed to initialize Dalamud.</param>
|
/// <param name="info">The <see cref="DalamudStartInfo"/> containing information needed to initialize Dalamud.</param>
|
||||||
private static void RunThread(DalamudStartInfo info)
|
private static void RunThread(DalamudStartInfo info)
|
||||||
{
|
{
|
||||||
|
// Setup logger
|
||||||
|
var levelSwitch = InitLogging(info.WorkingDirectory);
|
||||||
|
|
||||||
// Load configuration first to get some early persistent state, like log level
|
// Load configuration first to get some early persistent state, like log level
|
||||||
var configuration = DalamudConfiguration.Load(info.ConfigurationPath);
|
var configuration = DalamudConfiguration.Load(info.ConfigurationPath);
|
||||||
|
|
||||||
// Setup logger
|
// Set the appropriate logging level from the configuration
|
||||||
var levelSwitch = InitLogging(info.WorkingDirectory, configuration);
|
#if !DEBUG
|
||||||
|
levelSwitch.MinimumLevel = configuration.LogLevel;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log any unhandled exception.
|
// Log any unhandled exception.
|
||||||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||||
|
|
@ -88,30 +95,96 @@ namespace Dalamud
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LoggingLevelSwitch InitLogging(string baseDirectory, DalamudConfiguration configuration)
|
private static LoggingLevelSwitch InitLogging(string baseDirectory)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var logPath = Path.Combine(baseDirectory, "dalamud.log");
|
var logPath = Path.Combine(baseDirectory, "dalamud.log");
|
||||||
|
var oldPath = Path.Combine(baseDirectory, "dalamud.log.old");
|
||||||
#else
|
#else
|
||||||
var logPath = Path.Combine(baseDirectory, "..", "..", "..", "dalamud.log");
|
var logPath = Path.Combine(baseDirectory, "..", "..", "..", "dalamud.log");
|
||||||
|
var oldPath = Path.Combine(baseDirectory, "..", "..", "..", "dalamud.log.old");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var levelSwitch = new LoggingLevelSwitch();
|
CullLogFile(logPath, oldPath, 1 * 1024 * 1024);
|
||||||
|
CullLogFile(oldPath, null, 10 * 1024 * 1024);
|
||||||
|
|
||||||
#if DEBUG
|
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Verbose);
|
||||||
levelSwitch.MinimumLevel = LogEventLevel.Verbose;
|
|
||||||
#else
|
|
||||||
levelSwitch.MinimumLevel = configuration.LogLevel;
|
|
||||||
#endif
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.WriteTo.Async(a => a.File(logPath, fileSizeLimitBytes: 5 * 1024 * 1024, rollOnFileSizeLimit: true))
|
.WriteTo.Async(a => a.File(logPath))
|
||||||
.WriteTo.Sink(SerilogEventSink.Instance)
|
.WriteTo.Sink(SerilogEventSink.Instance)
|
||||||
.MinimumLevel.ControlledBy(levelSwitch)
|
.MinimumLevel.ControlledBy(levelSwitch)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
||||||
return levelSwitch;
|
return levelSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CullLogFile(string logPath, string? oldPath, int cullingFileSize)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var bufferSize = 4096;
|
||||||
|
|
||||||
|
var logFile = new FileInfo(logPath);
|
||||||
|
|
||||||
|
if (!logFile.Exists)
|
||||||
|
logFile.Create();
|
||||||
|
|
||||||
|
if (logFile.Length <= cullingFileSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var amountToCull = logFile.Length - cullingFileSize;
|
||||||
|
|
||||||
|
if (amountToCull < bufferSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (oldPath != null)
|
||||||
|
{
|
||||||
|
var oldFile = new FileInfo(oldPath);
|
||||||
|
|
||||||
|
if (!oldFile.Exists)
|
||||||
|
oldFile.Create();
|
||||||
|
|
||||||
|
using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read));
|
||||||
|
using var writer = new BinaryWriter(oldFile.Open(FileMode.Append, FileAccess.Write));
|
||||||
|
|
||||||
|
var read = -1;
|
||||||
|
var total = 0;
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
while (read != 0 && total < amountToCull)
|
||||||
|
{
|
||||||
|
read = reader.Read(buffer, 0, buffer.Length);
|
||||||
|
writer.Write(buffer, 0, read);
|
||||||
|
total += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
|
using var writer = new BinaryWriter(logFile.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite));
|
||||||
|
|
||||||
|
reader.BaseStream.Seek(amountToCull, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
var read = -1;
|
||||||
|
var total = 0;
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
while (read != 0)
|
||||||
|
{
|
||||||
|
read = reader.Read(buffer, 0, buffer.Length);
|
||||||
|
writer.Write(buffer, 0, read);
|
||||||
|
total += read;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.BaseStream.SetLength(total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
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)
|
private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args)
|
||||||
{
|
{
|
||||||
switch (args.ExceptionObject)
|
switch (args.ExceptionObject)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue