diff --git a/Directory.Packages.props b/Directory.Packages.props index 3f6acc3..78f37df 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,47 +1,50 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RomRepoMgr/Program.cs b/RomRepoMgr/Program.cs index 1610310..c49352d 100644 --- a/RomRepoMgr/Program.cs +++ b/RomRepoMgr/Program.cs @@ -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() .UsePlatformDetect() - .LogToTrace(LogEventLevel.Debug); +#if DEBUG + .LogToSerilog(LogEventLevel.Debug); +#else + .LogToSerilog(LogEventLevel.Information); +#endif } \ No newline at end of file diff --git a/RomRepoMgr/RomRepoMgr.csproj b/RomRepoMgr/RomRepoMgr.csproj index 3bac9e7..c0da146 100644 --- a/RomRepoMgr/RomRepoMgr.csproj +++ b/RomRepoMgr/RomRepoMgr.csproj @@ -31,6 +31,9 @@ + + + diff --git a/RomRepoMgr/SerilogSink.cs b/RomRepoMgr/SerilogSink.cs new file mode 100644 index 0000000..2040087 --- /dev/null +++ b/RomRepoMgr/SerilogSink.cs @@ -0,0 +1,49 @@ +#nullable enable +using System.Collections.Generic; +using Avalonia.Logging; + +namespace RomRepoMgr; + +public class SerilogSink(LogEventLevel minimumLevel, IList? areas = null) : ILogSink +{ + private readonly IList? _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 + }; + } +} \ No newline at end of file diff --git a/RomRepoMgr/SerilogSinkExtensions.cs b/RomRepoMgr/SerilogSinkExtensions.cs new file mode 100644 index 0000000..84456e3 --- /dev/null +++ b/RomRepoMgr/SerilogSinkExtensions.cs @@ -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; + } +} \ No newline at end of file diff --git a/RomRepoMgr/ViewModels/ImportRomFolderViewModel.cs b/RomRepoMgr/ViewModels/ImportRomFolderViewModel.cs index 076f5b6..ede5571 100644 --- a/RomRepoMgr/ViewModels/ImportRomFolderViewModel.cs +++ b/RomRepoMgr/ViewModels/ImportRomFolderViewModel.cs @@ -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; diff --git a/RomRepoMgr/ViewModels/MainWindowViewModel.cs b/RomRepoMgr/ViewModels/MainWindowViewModel.cs index 4ca7459..840272a 100644 --- a/RomRepoMgr/ViewModels/MainWindowViewModel.cs +++ b/RomRepoMgr/ViewModels/MainWindowViewModel.cs @@ -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; diff --git a/RomRepoMgr/ViewModels/SettingsViewModel.cs b/RomRepoMgr/ViewModels/SettingsViewModel.cs index 5dc6bee..d6c5d34 100644 --- a/RomRepoMgr/ViewModels/SettingsViewModel.cs +++ b/RomRepoMgr/ViewModels/SettingsViewModel.cs @@ -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; diff --git a/RomRepoMgr/ViewModels/SplashWindowViewModel.cs b/RomRepoMgr/ViewModels/SplashWindowViewModel.cs index 0df76b6..7290e31 100644 --- a/RomRepoMgr/ViewModels/SplashWindowViewModel.cs +++ b/RomRepoMgr/ViewModels/SplashWindowViewModel.cs @@ -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); } }); diff --git a/RomRepoMgr/ViewModels/UpdateStatsViewModel.cs b/RomRepoMgr/ViewModels/UpdateStatsViewModel.cs index 4580c6e..c9d71c6 100644 --- a/RomRepoMgr/ViewModels/UpdateStatsViewModel.cs +++ b/RomRepoMgr/ViewModels/UpdateStatsViewModel.cs @@ -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++; }