Added Serilog for logging.

This commit is contained in:
2025-07-24 16:20:22 +01:00
parent 69fb3c768b
commit 55a6af0c74
10 changed files with 176 additions and 60 deletions

View File

@@ -23,8 +23,10 @@
// Copyright © 2020-2024 Natalia Portillo
*******************************************************************************/
using System;
using Avalonia;
using Avalonia.Logging;
using Serilog;
namespace RomRepoMgr;
@@ -33,10 +35,40 @@ internal static class Program
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
#if DEBUG
.MinimumLevel.Debug()
#else
.MinimumLevel.Information()
#endif
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting up");
Log.Debug("Testing debug logging");
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
catch(Exception ex)
{
Log.Fatal(ex, "Application start-up failed");
}
finally
{
Log.CloseAndFlush();
}
}
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace(LogEventLevel.Debug);
#if DEBUG
.LogToSerilog(LogEventLevel.Debug);
#else
.LogToSerilog(LogEventLevel.Information);
#endif
}

View File

@@ -31,6 +31,9 @@
<PackageReference Include="Roslynator.Analyzers"/>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers"/>
<PackageReference Include="Roslynator.Formatting.Analyzers"/>
<PackageReference Include="Serilog"/>
<PackageReference Include="Serilog.Extensions.Logging"/>
<PackageReference Include="Serilog.Sinks.Console"/>
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer"/>
<PackageReference Include="Text.Analyzers"/>
</ItemGroup>

49
RomRepoMgr/SerilogSink.cs Normal file
View File

@@ -0,0 +1,49 @@
#nullable enable
using System.Collections.Generic;
using Avalonia.Logging;
namespace RomRepoMgr;
public class SerilogSink(LogEventLevel minimumLevel, IList<string>? areas = null) : ILogSink
{
private readonly IList<string>? _areas = areas?.Count > 0 ? areas : null;
public bool IsEnabled(LogEventLevel level, string area) =>
level >= minimumLevel && (_areas?.Contains(area) ?? true);
public void Log(LogEventLevel level, string area, object? source, string messageTemplate)
{
if(IsEnabled(level, area))
Serilog.Log.Write(LogLevelToSerilogLevel(level),
"[{Area} {Source}] {MessageTemplate}",
area,
source,
messageTemplate);
}
public void Log(LogEventLevel level, string area, object? source, string messageTemplate,
params object?[] propertyValues)
{
if(IsEnabled(level, area))
Serilog.Log.Write(LogLevelToSerilogLevel(level),
"[{Area} {Source}] {MessageTemplate}",
propertyValues,
area,
source,
messageTemplate);
}
private static Serilog.Events.LogEventLevel LogLevelToSerilogLevel(LogEventLevel level)
{
return level switch
{
LogEventLevel.Verbose => Serilog.Events.LogEventLevel.Verbose,
LogEventLevel.Debug => Serilog.Events.LogEventLevel.Debug,
LogEventLevel.Information => Serilog.Events.LogEventLevel.Information,
LogEventLevel.Warning => Serilog.Events.LogEventLevel.Warning,
LogEventLevel.Error => Serilog.Events.LogEventLevel.Error,
LogEventLevel.Fatal => Serilog.Events.LogEventLevel.Fatal,
_ => Serilog.Events.LogEventLevel.Verbose
};
}
}

View File

@@ -0,0 +1,15 @@
using Avalonia;
using Avalonia.Logging;
namespace RomRepoMgr;
public static class SerilogSinkExtensions
{
public static AppBuilder LogToSerilog(this AppBuilder builder, LogEventLevel level = LogEventLevel.Warning,
params string[] areas)
{
Logger.Sink = new SerilogSink(level, areas);
return builder;
}
}

View File

@@ -18,6 +18,7 @@ using RomRepoMgr.Database;
using RomRepoMgr.Database.Models;
using RomRepoMgr.Models;
using RomRepoMgr.Resources;
using Serilog;
namespace RomRepoMgr.ViewModels;
@@ -235,7 +236,7 @@ public sealed partial class ImportRomFolderViewModel : ViewModelBase
});
_stopwatch.Stop();
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process files.");
Log.Debug("Took {TotalSeconds} seconds to process files", _stopwatch.Elapsed.TotalSeconds);
_rootImporter.SaveChanges();
@@ -325,7 +326,7 @@ public sealed partial class ImportRomFolderViewModel : ViewModelBase
});
_stopwatch.Stop();
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process archives.");
Log.Debug("Took {TotalSeconds} seconds to process archives", _stopwatch.Elapsed.TotalSeconds);
Progress2Visible = false;
StatusMessage2Visible = false;
@@ -336,7 +337,7 @@ public sealed partial class ImportRomFolderViewModel : ViewModelBase
void CheckArchivesFinished(object sender, EventArgs e)
{
_stopwatch.Stop();
Console.WriteLine("Took {0} seconds to check archives.", _stopwatch.Elapsed.TotalSeconds);
Log.Debug("Took {TotalSeconds} seconds to check archives", _stopwatch.Elapsed.TotalSeconds);
Progress2Visible = false;
StatusMessage2Visible = false;

View File

@@ -44,6 +44,7 @@ using RomRepoMgr.Core.Filesystem;
using RomRepoMgr.Core.Models;
using RomRepoMgr.Resources;
using RomRepoMgr.Views;
using Serilog;
namespace RomRepoMgr.ViewModels;
@@ -270,8 +271,10 @@ public sealed partial class MainWindowViewModel : ViewModelBase
Vfs.Umounted += VfsOnUmounted;
Vfs.MountTo(result[0].Path.LocalPath);
}
catch(Exception)
catch(Exception ex)
{
Log.Error(ex, "Error mounting VFS");
if(Debugger.IsAttached) throw;
Vfs = null;

View File

@@ -230,7 +230,7 @@ public sealed partial class SettingsViewModel : ViewModelBase
var ctx = Context.Create(result);
await ctx.Database.MigrateAsync();
}
catch(Exception)
catch
{
btnResult = await MessageBoxManager
.GetMessageBoxStandard(Localization.DatabaseFileUnusableMsgBoxTitle,
@@ -245,7 +245,7 @@ public sealed partial class SettingsViewModel : ViewModelBase
{
File.Delete(result);
}
catch(Exception)
catch
{
await MessageBoxManager
.GetMessageBoxStandard(Localization.DatabaseFileCannotDeleteTitle,
@@ -254,9 +254,13 @@ public sealed partial class SettingsViewModel : ViewModelBase
Icon.Error)
.ShowWindowDialogAsync(_view);
#pragma warning disable ERP022
return;
#pragma warning restore ERP022
}
#pragma warning disable ERP022
}
#pragma warning restore ERP022
}
else
{
@@ -273,7 +277,7 @@ public sealed partial class SettingsViewModel : ViewModelBase
{
File.Delete(result);
}
catch(Exception)
catch
{
await MessageBoxManager
.GetMessageBoxStandard(Localization.DatabaseFileCannotDeleteTitle,
@@ -282,7 +286,9 @@ public sealed partial class SettingsViewModel : ViewModelBase
Icon.Error)
.ShowWindowDialogAsync(_view);
#pragma warning disable ERP022
return;
#pragma warning restore ERP022
}
}
}
@@ -292,7 +298,7 @@ public sealed partial class SettingsViewModel : ViewModelBase
var ctx = Context.Create(result);
await ctx.Database.MigrateAsync();
}
catch(Exception)
catch
{
await MessageBoxManager
.GetMessageBoxStandard(Localization.DatabaseFileUnusableMsgBoxTitle,
@@ -301,7 +307,9 @@ public sealed partial class SettingsViewModel : ViewModelBase
Icon.Error)
.ShowWindowDialogAsync(_view);
#pragma warning disable ERP022
return;
#pragma warning restore ERP022
}
DatabasePath = result;

View File

@@ -38,6 +38,7 @@ using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Models;
using RomRepoMgr.Core.Workers;
using RomRepoMgr.Database;
using Serilog;
namespace RomRepoMgr.ViewModels;
@@ -119,7 +120,7 @@ public sealed partial class SplashWindowViewModel : ViewModelBase
}
catch(Exception e)
{
// TODO: Log error
Log.Error(e, "Error loading settings");
Dispatcher.UIThread.Post(FailedLoadingSettings);
}
});
@@ -148,7 +149,7 @@ public sealed partial class SplashWindowViewModel : ViewModelBase
}
catch(Exception e)
{
// TODO: Log error
Log.Error(e, "Error checking unar");
Dispatcher.UIThread.Post(FailedCheckUnAr);
}
});
@@ -180,7 +181,7 @@ public sealed partial class SplashWindowViewModel : ViewModelBase
}
catch(Exception e)
{
// TODO: Log error
Log.Error(e, "Error loading database");
Dispatcher.UIThread.Post(FailedLoadingDatabase);
}
});
@@ -210,7 +211,7 @@ public sealed partial class SplashWindowViewModel : ViewModelBase
}
catch(Exception e)
{
// TODO: Log error
Log.Error(e, "Error migrating database");
Dispatcher.UIThread.Post(FailedMigratingDatabase);
}
});
@@ -270,7 +271,7 @@ public sealed partial class SplashWindowViewModel : ViewModelBase
}
catch(Exception e)
{
// TODO: Log error
Log.Error(e, "Error loading ROM sets");
Dispatcher.UIThread.Post(FailedLoadingRomSets);
}
});

View File

@@ -23,7 +23,6 @@
// Copyright © 2020-2024 Natalia Portillo
*******************************************************************************/
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
@@ -187,10 +186,12 @@ public sealed partial class UpdateStatsViewModel : ViewModelBase
});
});
}
catch(Exception)
catch
#pragma warning disable PH2098
{
// Ignored
}
#pragma warning restore PH2098
pos++;
}