Removing Serilog from the launcher

Rely on the standard .NET logging system, so it integrates better with external libraries we might be logging through.
This commit is contained in:
Aaron Powell 2025-12-11 12:35:52 +11:00
parent 9a713045d1
commit 4cef475348
4 changed files with 252 additions and 215 deletions

View file

@ -72,10 +72,6 @@
<PackageReference Include="Photino.Blazor" />
<PackageReference Include="Photino.Blazor.CustomWindow" />
<PackageReference Include="Photino.NET" />
<PackageReference Include="Serilog" />
<PackageReference Include="Serilog.Extensions.Logging" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Serilog.Sinks.Seq" />
</ItemGroup>
<ItemGroup>

View file

@ -1,8 +1,6 @@
using LANCommander.Launcher.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Events;
using System.Runtime.InteropServices;
using LANCommander.Launcher.Data;
using LANCommander.Launcher.Enums;
@ -17,78 +15,43 @@ class Program
[STAThread]
static void Main(string[] args)
{
// Map the Microsoft.Extensions.Logging.LogLevel to Serilog.LogEventLevel.
var serilogLogLevel = MapLogLevel(LogLevel.Debug);
using var Logger = new LoggerConfiguration()
.MinimumLevel.Is(serilogLogLevel)
.MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Components", LogEventLevel.Warning)
.MinimumLevel.Override("AntDesign", LogEventLevel.Warning)
.Enrich.WithProperty("Application", typeof(Program).Assembly.GetName().Name)
//.WriteTo.File(Path.Combine(settings.Debug.LoggingPath, "log-.txt"), rollingInterval: settings.Debug.LoggingArchivePeriod)
#if DEBUG
.WriteTo.Seq("http://localhost:5341")
#endif
.CreateLogger();
Logger?.Information("Starting launcher | Version: {Version}", UpdateService.GetCurrentVersion());
WindowService.CreateWindow<UI.App_Main>(new WindowOptions
{
Title = "LANCommander",
Type = WindowType.Main
}, null, async (app) =>
{
using var scope = app.Services.CreateScope();
var connectionClient = scope.ServiceProvider.GetRequiredService<IConnectionClient>();
var settingsProvider = scope.ServiceProvider.GetRequiredService<SettingsProvider<Settings.Settings>>();
var databaseContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
if (!(await connectionClient.PingAsync()))
await connectionClient.EnableOfflineModeAsync();
if (settingsProvider.CurrentValue.Games.InstallDirectories.Length == 0)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Path.GetPathRoot(AppContext.BaseDirectory) ?? "C:", "Games")];
});
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
});
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
});
}
var logger = app.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Starting launcher | Version: {Version}", UpdateService.GetCurrentVersion());
using var scope = app.Services.CreateScope();
var connectionClient = scope.ServiceProvider.GetRequiredService<IConnectionClient>();
var settingsProvider = scope.ServiceProvider.GetRequiredService<SettingsProvider<Settings.Settings>>();
var databaseContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
if (!(await connectionClient.PingAsync()))
await connectionClient.EnableOfflineModeAsync();
if (settingsProvider.CurrentValue.Games.InstallDirectories.Length == 0)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Path.GetPathRoot(AppContext.BaseDirectory) ?? "C:", "Games")];
});
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
});
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
settingsProvider.Update(s =>
{
s.Games.InstallDirectories = [Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Games")];
});
}
await databaseContext.Database.MigrateAsync();
}, args);
}
/// <summary>
/// Maps Microsoft.Extensions.Logging.LogLevel to Serilog.Events.LogEventLevel.
/// </summary>
private static LogEventLevel MapLogLevel(LogLevel level)
{
return level switch
{
LogLevel.Trace => LogEventLevel.Verbose,
LogLevel.Debug => LogEventLevel.Debug,
LogLevel.Information => LogEventLevel.Information,
LogLevel.Warning => LogEventLevel.Warning,
LogLevel.Error => LogEventLevel.Error,
LogLevel.Critical => LogEventLevel.Fatal,
// LogLevel.None indicates logging should be disabled.
// Serilog does not have a direct "Off" level so you might choose to
// either bypass logging configuration or set it high enough to ignore messages.
LogLevel.None => LogEventLevel.Fatal,
_ => LogEventLevel.Information
};
}
}

View file

@ -1,7 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Photino.Blazor;
using Serilog;
namespace LANCommander.Launcher.Startup;
@ -9,15 +8,93 @@ public static class Logging
{
public static PhotinoBlazorAppBuilder AddLogging(this PhotinoBlazorAppBuilder builder)
{
Log.Debug("Configuring logging...");
var logsDirectory = Path.Combine(AppContext.BaseDirectory, "Logs");
if (!Directory.Exists(logsDirectory))
Directory.CreateDirectory(logsDirectory);
/*builder.Services.AddLogging(loggingBuilder =>
builder.Services.AddLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
loggingBuilder.SetMinimumLevel(settings.Debug.LoggingLevel);
loggingBuilder.AddSerilog(Logger);
});*/
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
loggingBuilder.AddFile(logsDirectory);
loggingBuilder.SetMinimumLevel(LogLevel.Debug);
loggingBuilder.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Warning);
loggingBuilder.AddFilter("Microsoft.AspNetCore.Components", LogLevel.Warning);
loggingBuilder.AddFilter("AntDesign", LogLevel.Warning);
});
return builder;
}
private static ILoggingBuilder AddFile(this ILoggingBuilder builder, string logDirectory)
{
return builder.AddProvider(new FileLoggerProvider(logDirectory));
}
private class FileLogger : ILogger
{
private readonly string _logDirectory;
private readonly string _categoryName;
public FileLogger(string logDirectory, string categoryName)
{
_logDirectory = logDirectory;
_categoryName = categoryName;
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
return;
var logFilePath = Path.Combine(
_logDirectory,
$"log-{DateTime.Now:yyyy-MM-dd}.txt");
var message = formatter(state, exception);
var logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{logLevel}] [{_categoryName}] {message}";
if (exception != null)
logMessage += Environment.NewLine + exception;
try
{
lock (_logDirectory)
{
File.AppendAllText(logFilePath, logMessage + Environment.NewLine);
}
}
catch
{
// Silently fail if logging to file fails
}
}
}
private class FileLoggerProvider : ILoggerProvider
{
private readonly string _logDirectory;
public FileLoggerProvider(string logDirectory)
{
_logDirectory = logDirectory;
}
public ILogger CreateLogger(string categoryName)
{
return new FileLogger(_logDirectory, categoryName);
}
public void Dispose() { }
}
}

View file

@ -1,81 +1,82 @@
using System.Web;
using LANCommander.Launcher.Services;
using Microsoft.Extensions.DependencyInjection;
using Photino.Blazor;
using Photino.NET;
using Serilog;
namespace LANCommander.Launcher.Startup;
public static class MainWindow
{
public static PhotinoBlazorApp RegisterMainWindow(this PhotinoBlazorApp app)
{
app.MainWindow
.SetTitle("LANCommander Launcher")
.RegisterWebMessageReceivedHandler(ChatWindowMessageDelegate)
.SetChromeless(true);
app.MainWindow.WindowClosing += SaveWindowPosition;
return app;
}
public static PhotinoBlazorApp RegisterMediaHandler(this PhotinoBlazorApp app)
{
var settingsProvider = app.Services.GetRequiredService<SettingsProvider<Settings.Settings>>();
app.MainWindow.RegisterCustomSchemeHandler("media",
(object sender, string scheme, string url, out string? contentType) =>
{
try
{
var uri = new Uri(url);
var query = HttpUtility.ParseQueryString(uri.Query);
var id = query["id"];
var fileId = query["fileId"];
var crc32 = query["crc32"];
var mime = query["mime"];
contentType = mime;
var filePath = Path.Combine(settingsProvider.CurrentValue.Media.StoragePath, $"{fileId}-{crc32}");
if (File.Exists(filePath))
return new FileStream(filePath, FileMode.Open, FileAccess.Read);
else
return null;
}
catch (Exception ex)
{
Log.Warning(ex, "Unable to load media file from local disk {FileUrl}", url);
contentType = "";
}
return null;
});
return app;
}
public static PhotinoBlazorApp RegisterNotificationHandler(this PhotinoBlazorApp app)
{
app.MainWindow.RegisterWebMessageReceivedHandler((sender, message) =>
{
if (message == "notification")
app.MainWindow.SendNotification("Test", "test");
});
return app;
}
public static PhotinoBlazorApp RegisterImportHandler(this PhotinoBlazorApp app)
{
app.MainWindow.RegisterWebMessageReceivedHandler(async (sender, message) =>
{
using System.Web;
using LANCommander.Launcher.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Photino.Blazor;
using Photino.NET;
namespace LANCommander.Launcher.Startup;
public static class MainWindow
{
public static PhotinoBlazorApp RegisterMainWindow(this PhotinoBlazorApp app)
{
app.MainWindow
.SetTitle("LANCommander Launcher")
.RegisterWebMessageReceivedHandler(ChatWindowMessageDelegate)
.SetChromeless(true);
app.MainWindow.WindowClosing += SaveWindowPosition;
return app;
}
public static PhotinoBlazorApp RegisterMediaHandler(this PhotinoBlazorApp app)
{
var settingsProvider = app.Services.GetRequiredService<SettingsProvider<Settings.Settings>>();
var logger = app.Services.GetRequiredService<ILogger<PhotinoBlazorApp>>();
app.MainWindow.RegisterCustomSchemeHandler("media",
(object sender, string scheme, string url, out string? contentType) =>
{
try
{
var uri = new Uri(url);
var query = HttpUtility.ParseQueryString(uri.Query);
var id = query["id"];
var fileId = query["fileId"];
var crc32 = query["crc32"];
var mime = query["mime"];
contentType = mime;
var filePath = Path.Combine(settingsProvider.CurrentValue.Media.StoragePath, $"{fileId}-{crc32}");
if (File.Exists(filePath))
return new FileStream(filePath, FileMode.Open, FileAccess.Read);
else
return null;
}
catch (Exception ex)
{
logger.LogWarning(ex, "Unable to load media file from local disk {FileUrl}", url);
contentType = "";
}
return null;
});
return app;
}
public static PhotinoBlazorApp RegisterNotificationHandler(this PhotinoBlazorApp app)
{
app.MainWindow.RegisterWebMessageReceivedHandler((sender, message) =>
{
if (message == "notification")
app.MainWindow.SendNotification("Test", "test");
});
return app;
}
public static PhotinoBlazorApp RegisterImportHandler(this PhotinoBlazorApp app)
{
app.MainWindow.RegisterWebMessageReceivedHandler(async (sender, message) =>
{
if (message != "import" || sender is null)
return;
@ -87,64 +88,64 @@ public static class MainWindow
await importService.ImportAsync();
window.SendWebMessage("importComplete");
});
return app;
}
static void ChatWindowMessageDelegate(object? sender, string message)
{
if (sender == null)
return;
var parent = (PhotinoWindow)sender;
if (message == "openChat")
{
new PhotinoWindow(parent)
.SetTitle("LANCommander Chat")
.Load("wwwroot/index.html")
.WaitForClose();
}
}
public static PhotinoBlazorApp RestoreWindowPosition(this PhotinoBlazorApp app)
{
var settingsProvider = app.Services.GetRequiredService<SettingsProvider<Settings.Settings>>();
if (settingsProvider.CurrentValue.Window.Maximized)
app.MainWindow.SetMaximized(true);
else
{
if (settingsProvider.CurrentValue.Window.Width != 0 && settingsProvider.CurrentValue.Window.Height != 0)
{
app.MainWindow.SetSize(settingsProvider.CurrentValue.Window.Width, settingsProvider.CurrentValue.Window.Height);
app.MainWindow.SetLocation(new System.Drawing.Point(settingsProvider.CurrentValue.Window.X, settingsProvider.CurrentValue.Window.Y));
}
else
{
app.MainWindow.SetSize(1024, 768);
app.MainWindow.Center();
}
}
return app;
}
private static bool SaveWindowPosition(object sender, EventArgs e)
{
var window = sender as PhotinoWindow;
/*var settings = SettingService.GetSettings();
settings.Window.Maximized = window.Maximized;
settings.Window.Width = window.Width;
settings.Window.Height = window.Height;
settings.Window.X = window.Left;
settings.Window.Y = window.Top;
SettingService.SaveSettings(settings);*/
return true;
}
});
return app;
}
static void ChatWindowMessageDelegate(object? sender, string message)
{
if (sender == null)
return;
var parent = (PhotinoWindow)sender;
if (message == "openChat")
{
new PhotinoWindow(parent)
.SetTitle("LANCommander Chat")
.Load("wwwroot/index.html")
.WaitForClose();
}
}
public static PhotinoBlazorApp RestoreWindowPosition(this PhotinoBlazorApp app)
{
var settingsProvider = app.Services.GetRequiredService<SettingsProvider<Settings.Settings>>();
if (settingsProvider.CurrentValue.Window.Maximized)
app.MainWindow.SetMaximized(true);
else
{
if (settingsProvider.CurrentValue.Window.Width != 0 && settingsProvider.CurrentValue.Window.Height != 0)
{
app.MainWindow.SetSize(settingsProvider.CurrentValue.Window.Width, settingsProvider.CurrentValue.Window.Height);
app.MainWindow.SetLocation(new System.Drawing.Point(settingsProvider.CurrentValue.Window.X, settingsProvider.CurrentValue.Window.Y));
}
else
{
app.MainWindow.SetSize(1024, 768);
app.MainWindow.Center();
}
}
return app;
}
private static bool SaveWindowPosition(object sender, EventArgs e)
{
var window = sender as PhotinoWindow;
/*var settings = SettingService.GetSettings();
settings.Window.Maximized = window.Maximized;
settings.Window.Width = window.Width;
settings.Window.Height = window.Height;
settings.Window.X = window.Left;
settings.Window.Y = window.Top;
SettingService.SaveSettings(settings);*/
return true;
}
}