Skip to content

Commit 5483881

Browse files
committed
Add logging
1 parent 6d87021 commit 5483881

File tree

6 files changed

+108
-8
lines changed

6 files changed

+108
-8
lines changed

ZuneModCore/Mods/WebservicesMod.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using OwlCore.AbstractUI.Models;
1+
using Microsoft.Extensions.Logging;
2+
using OwlCore.AbstractUI.Models;
23
using OwlCore.ComponentModel;
34
using System;
45
using System.Collections.Generic;
@@ -28,7 +29,7 @@ public class WebservicesModFactory : DIModFactoryBase<WebservicesMod>
2829
Description, Author, new(1, 2));
2930
}
3031

31-
public partial class WebservicesMod(ModMetadata metadata, IModCoreConfig modConfig) : Mod(metadata), IAsyncInit
32+
public partial class WebservicesMod(ModMetadata metadata, IModCoreConfig modConfig, ILogger<WebservicesMod> log) : Mod(metadata), IAsyncInit
3233
{
3334
private const int ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET = 0x14D60;
3435
private const int ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH = 0x884;
@@ -130,6 +131,8 @@ public Task InitAsync(CancellationToken token = default)
130131

131132
if (errorMessage is not null)
132133
{
134+
log.LogWarning("Binary patching failed, falling back to hosts file modification: {ErrorMessage}", errorMessage);
135+
133136
// Fallback to editing hosts file
134137
errorMessage = await AddEntriesToHostsFile(newHost);
135138

ZuneModCore/Services/FileLogger.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using Microsoft.Extensions.Logging;
2+
using System;
3+
using System.Diagnostics;
4+
using System.IO;
5+
6+
namespace ZuneModCore.Services;
7+
8+
public class FileLoggerProvider(string logDirectory) : ILoggerProvider
9+
{
10+
private StreamWriter? _writer;
11+
12+
public ILogger CreateLogger(string categoryName)
13+
{
14+
_writer ??= CreateLogFile();
15+
16+
return new FileLogger(_writer, categoryName);
17+
}
18+
19+
private StreamWriter CreateLogFile()
20+
{
21+
var logFilePath = Path.Combine(logDirectory, $"{DateTime.Now:yyyyMMdd_HHmmss}.log");
22+
var logFile = File.Open(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Read);
23+
24+
return new(logFile) { AutoFlush = true };
25+
}
26+
27+
public void Dispose() => _writer?.Dispose();
28+
}
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="FileLogger"/> class.
32+
/// </summary>
33+
/// <param name="name">The name of the logger.</param>
34+
internal sealed class FileLogger(TextWriter writer, string name) : ILogger
35+
{
36+
/// <inheritdoc />
37+
public IDisposable BeginScope<TState>(TState state) where TState : notnull => null!;
38+
39+
/// <inheritdoc />
40+
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
41+
42+
/// <inheritdoc />
43+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
44+
{
45+
if (!IsEnabled(logLevel))
46+
{
47+
return;
48+
}
49+
50+
ArgumentNullException.ThrowIfNull(formatter);
51+
52+
string formatted = formatter(state, exception);
53+
54+
if (string.IsNullOrEmpty(formatted) && exception == null)
55+
{
56+
// With no formatted message or exception, there's nothing to print.
57+
return;
58+
}
59+
60+
var message = $"{logLevel} [{name}]{Environment.NewLine}";
61+
if (string.IsNullOrEmpty(formatted))
62+
{
63+
Debug.Assert(exception != null);
64+
message += $"{exception}";
65+
}
66+
else if (exception == null)
67+
{
68+
message += $"{formatted}";
69+
}
70+
else
71+
{
72+
message += $"{formatted}{Environment.NewLine}{Environment.NewLine}{exception}";
73+
}
74+
75+
writer.WriteLine(message);
76+
}
77+
}

ZuneModCore/ZuneModCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12+
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
1213
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
1314
<PackageReference Include="OwlCore" Version="0.4.1" />
1415
<PackageReference Include="OwlCore.AbstractUI" Version="0.0.0" />

ZuneModdingHelper/App.xaml.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
2+
using System.IO;
23
using System.Text;
34
using System.Windows;
45
using CommunityToolkit.Mvvm.DependencyInjection;
56
using Microsoft.Extensions.DependencyInjection;
7+
using Microsoft.Extensions.Logging;
68
using ZuneModCore;
79
using ZuneModCore.Services;
810
using ZuneModdingHelper.Services;
@@ -57,7 +59,14 @@ public static void OpenIssueReport(ModMetadata modMetadata, string errorMessage)
5759

5860
private static void ConfigureServices()
5961
{
60-
ServiceCollection services = new();
62+
ServiceCollection services = [];
63+
64+
services.AddLogging(builder =>
65+
{
66+
var logDir = Path.Combine(Settings.AppDataDir, "Logs");
67+
Directory.CreateDirectory(logDir);
68+
builder.AddProvider(new FileLoggerProvider(logDir));
69+
});
6170

6271
Octokit.IGitHubClient github = new Octokit.GitHubClient(new Octokit.ProductHeaderValue(Title.Replace(" ", ""), VersionStr));
6372
services.AddSingleton(github);

ZuneModdingHelper/Pages/ModsPage.xaml.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using CommunityToolkit.Mvvm.DependencyInjection;
22
using CommunityToolkit.Mvvm.Input;
33
using CommunityToolkit.Mvvm.Messaging;
4+
using Microsoft.Extensions.Logging;
45
using OwlCore.AbstractUI.Models;
56
using OwlCore.ComponentModel;
7+
using System;
68
using System.Net.NetworkInformation;
79
using System.Threading.Tasks;
810
using System.Windows;
@@ -21,10 +23,12 @@ public partial class ModsPage : UserControl
2123
private const string MOD_MANAGER_TITLE = "MOD MANAGER";
2224

2325
private readonly Settings _settings;
26+
private readonly ILogger<ModsPage> _log;
2427

25-
public ModsPage(Settings settings)
28+
public ModsPage(Settings settings, ILogger<ModsPage> log)
2629
{
2730
_settings = settings;
31+
_log = log;
2832

2933
InitializeComponent();
3034
ModList.ItemsSource = ModManager.ModFactories;
@@ -84,6 +88,8 @@ private async void ApplyButton_Click(object sender, RoutedEventArgs e)
8488
Description = $"Successfully applied '{modTitle}'",
8589
OnAction = new AsyncRelayCommand<bool>(ShowDonationRequestDialog)
8690
}));
91+
92+
_log.LogInformation("Mod {ModId} applied", mod.Metadata.Id);
8793
}
8894

8995
private async void ResetButton_Click(object sender, RoutedEventArgs e)
@@ -130,6 +136,8 @@ private async void ResetButton_Click(object sender, RoutedEventArgs e)
130136
Title = MOD_MANAGER_TITLE,
131137
Description = $"Successfully reset '{modTitle}'",
132138
}));
139+
140+
_log.LogError("Mod {ModId} reset", mod.Metadata.Id);
133141
}
134142

135143
private static bool TryGetModFromControl(object sender, out IModFactory<Mod> modFactory)
@@ -148,8 +156,10 @@ private static async Task<Mod> CreateModInstance(IModFactory<Mod> modFactory)
148156
return mod;
149157
}
150158

151-
private static void ShowErrorDialog(Mod mod, string action, string errorMessage)
159+
private void ShowErrorDialog(Mod mod, string action, string errorMessage)
152160
{
161+
_log.LogError("Mod {ModId} failed to {Action}: {ErrorMessage}", mod.Metadata.Id, action, errorMessage);
162+
153163
DialogViewModel errorDialog = new()
154164
{
155165
Title = MOD_MANAGER_TITLE,

ZuneModdingHelper/Services/Settings.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22
using OwlCore.Storage;
33
using System.IO;
44
using System;
5-
using ZuneModCore;
65
using ZuneModCore.Services;
7-
using System.Collections.Generic;
86

97
namespace ZuneModdingHelper.Services;
108

119
public class Settings(IModifiableFolder folder) : SettingsBase(folder, SystemTextJsonStreamSerializer.Singleton), IModCoreConfig
1210
{
1311
static Settings()
1412
{
15-
string dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZuneModCore", "Settings");
13+
string dir = Path.Combine(AppDataDir, "Settings");
1614
Directory.CreateDirectory(dir);
1715

1816
OwlCore.Storage.SystemIO.SystemFolder settingsFolder = new(dir);
1917
Default = new(settingsFolder);
2018
}
2119

20+
public static string AppDataDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ZuneModCore");
21+
2222
public static Settings Default { get; }
2323

2424
public string ZuneInstallDir

0 commit comments

Comments
 (0)