Add logging

This commit is contained in:
Yoshi Askharoun
2025-09-02 01:58:53 -07:00
parent 6d87021011
commit 5483881994
6 changed files with 108 additions and 8 deletions
+5 -2
View File
@@ -1,4 +1,5 @@
using OwlCore.AbstractUI.Models;
using Microsoft.Extensions.Logging;
using OwlCore.AbstractUI.Models;
using OwlCore.ComponentModel;
using System;
using System.Collections.Generic;
@@ -28,7 +29,7 @@ public class WebservicesModFactory : DIModFactoryBase<WebservicesMod>
Description, Author, new(1, 2));
}
public partial class WebservicesMod(ModMetadata metadata, IModCoreConfig modConfig) : Mod(metadata), IAsyncInit
public partial class WebservicesMod(ModMetadata metadata, IModCoreConfig modConfig, ILogger<WebservicesMod> log) : Mod(metadata), IAsyncInit
{
private const int ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET = 0x14D60;
private const int ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH = 0x884;
@@ -130,6 +131,8 @@ public partial class WebservicesMod(ModMetadata metadata, IModCoreConfig modConf
if (errorMessage is not null)
{
log.LogWarning("Binary patching failed, falling back to hosts file modification: {ErrorMessage}", errorMessage);
// Fallback to editing hosts file
errorMessage = await AddEntriesToHostsFile(newHost);
+77
View File
@@ -0,0 +1,77 @@
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
namespace ZuneModCore.Services;
public class FileLoggerProvider(string logDirectory) : ILoggerProvider
{
private StreamWriter? _writer;
public ILogger CreateLogger(string categoryName)
{
_writer ??= CreateLogFile();
return new FileLogger(_writer, categoryName);
}
private StreamWriter CreateLogFile()
{
var logFilePath = Path.Combine(logDirectory, $"{DateTime.Now:yyyyMMdd_HHmmss}.log");
var logFile = File.Open(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read);
return new(logFile) { AutoFlush = true };
}
public void Dispose() => _writer?.Dispose();
}
/// <summary>
/// Initializes a new instance of the <see cref="FileLogger"/> class.
/// </summary>
/// <param name="name">The name of the logger.</param>
internal sealed class FileLogger(TextWriter writer, string name) : ILogger
{
/// <inheritdoc />
public IDisposable BeginScope<TState>(TState state) where TState : notnull => null!;
/// <inheritdoc />
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
/// <inheritdoc />
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
ArgumentNullException.ThrowIfNull(formatter);
string formatted = formatter(state, exception);
if (string.IsNullOrEmpty(formatted) && exception == null)
{
// With no formatted message or exception, there's nothing to print.
return;
}
var message = $"{logLevel} [{name}]{Environment.NewLine}";
if (string.IsNullOrEmpty(formatted))
{
Debug.Assert(exception != null);
message += $"{exception}";
}
else if (exception == null)
{
message += $"{formatted}";
}
else
{
message += $"{formatted}{Environment.NewLine}{Environment.NewLine}{exception}";
}
writer.WriteLine(message);
}
}
+1
View File
@@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="OwlCore" Version="0.4.1" />
<PackageReference Include="OwlCore.AbstractUI" Version="0.0.0" />
+10 -1
View File
@@ -1,8 +1,10 @@
using System;
using System.IO;
using System.Text;
using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ZuneModCore;
using ZuneModCore.Services;
using ZuneModdingHelper.Services;
@@ -57,7 +59,14 @@ namespace ZuneModdingHelper
private static void ConfigureServices()
{
ServiceCollection services = new();
ServiceCollection services = [];
services.AddLogging(builder =>
{
var logDir = Path.Combine(Settings.AppDataDir, "Logs");
Directory.CreateDirectory(logDir);
builder.AddProvider(new FileLoggerProvider(logDir));
});
Octokit.IGitHubClient github = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(Title.Replace(" ", ""), VersionStr));
services.AddSingleton(github);
+12 -2
View File
@@ -1,8 +1,10 @@
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.Logging;
using OwlCore.AbstractUI.Models;
using OwlCore.ComponentModel;
using System;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using System.Windows;
@@ -21,10 +23,12 @@ namespace ZuneModdingHelper.Pages
private const string MOD_MANAGER_TITLE = "MOD MANAGER";
private readonly Settings _settings;
private readonly ILogger<ModsPage> _log;
public ModsPage(Settings settings)
public ModsPage(Settings settings, ILogger<ModsPage> log)
{
_settings = settings;
_log = log;
InitializeComponent();
ModList.ItemsSource = ModManager.ModFactories;
@@ -84,6 +88,8 @@ namespace ZuneModdingHelper.Pages
Description = $"Successfully applied '{modTitle}'",
OnAction = new AsyncRelayCommand<bool>(ShowDonationRequestDialog)
}));
_log.LogInformation("Mod {ModId} applied", mod.Metadata.Id);
}
private async void ResetButton_Click(object sender, RoutedEventArgs e)
@@ -130,6 +136,8 @@ namespace ZuneModdingHelper.Pages
Title = MOD_MANAGER_TITLE,
Description = $"Successfully reset '{modTitle}'",
}));
_log.LogError("Mod {ModId} reset", mod.Metadata.Id);
}
private static bool TryGetModFromControl(object sender, out IModFactory<Mod> modFactory)
@@ -148,8 +156,10 @@ namespace ZuneModdingHelper.Pages
return mod;
}
private static void ShowErrorDialog(Mod mod, string action, string errorMessage)
private void ShowErrorDialog(Mod mod, string action, string errorMessage)
{
_log.LogError("Mod {ModId} failed to {Action}: {ErrorMessage}", mod.Metadata.Id, action, errorMessage);
DialogViewModel errorDialog = new()
{
Title = MOD_MANAGER_TITLE,
+3 -3
View File
@@ -2,9 +2,7 @@
using OwlCore.Storage;
using System.IO;
using System;
using ZuneModCore;
using ZuneModCore.Services;
using System.Collections.Generic;
namespace ZuneModdingHelper.Services;
@@ -12,13 +10,15 @@ public class Settings(IModifiableFolder folder) : SettingsBase(folder, SystemTex
{
static Settings()
{
string dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZuneModCore", "Settings");
string dir = Path.Combine(AppDataDir, "Settings");
Directory.CreateDirectory(dir);
OwlCore.Storage.SystemIO.SystemFolder settingsFolder = new(dir);
Default = new(settingsFolder);
}
public static string AppDataDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZuneModCore");
public static Settings Default { get; }
public string ZuneInstallDir