From 9270c6d1f10e156812b5e7ee552dc54640d21ad3 Mon Sep 17 00:00:00 2001
From: BlossomiShymae <87099578+BlossomiShymae@users.noreply.github.com>
Date: Tue, 17 Dec 2024 23:36:28 -0600
Subject: [PATCH] Add logging
---
Needlework.Net/Needlework.Net.csproj | 1 -
Needlework.Net/Program.cs | 11 +++++-
.../MainWindow/MainWindowViewModel.cs | 37 ++++++++++++++-----
.../ViewModels/Pages/ConsoleViewModel.cs | 6 ++-
.../Pages/Endpoints/EndpointViewModel.cs | 6 ++-
.../Endpoints/EndpointsNavigationViewModel.cs | 6 ++-
.../Pages/Endpoints/EndpointsTabViewModel.cs | 9 ++++-
.../Pages/Endpoints/EndpointsViewModel.cs | 9 ++++-
.../Pages/Endpoints/PathOperationViewModel.cs | 5 ++-
.../Pages/Websocket/WebsocketViewModel.cs | 14 +++++--
.../ViewModels/Shared/LcuRequestViewModel.cs | 11 ++++++
11 files changed, 88 insertions(+), 27 deletions(-)
diff --git a/Needlework.Net/Needlework.Net.csproj b/Needlework.Net/Needlework.Net.csproj
index 9ead956..f9b29b0 100644
--- a/Needlework.Net/Needlework.Net.csproj
+++ b/Needlework.Net/Needlework.Net.csproj
@@ -41,7 +41,6 @@
-
diff --git a/Needlework.Net/Program.cs b/Needlework.Net/Program.cs
index 8d4c623..0a1cc67 100644
--- a/Needlework.Net/Program.cs
+++ b/Needlework.Net/Program.cs
@@ -6,8 +6,10 @@ using Needlework.Net.ViewModels.MainWindow;
using Needlework.Net.ViewModels.Pages;
using Projektanker.Icons.Avalonia;
using Projektanker.Icons.Avalonia.FontAwesome;
+using Serilog;
using System;
using System.IO;
+using System.Reflection;
namespace Needlework.Net;
@@ -44,9 +46,16 @@ class Program
builder.AddSingleton();
builder.AddSingleton();
builder.AddSingletonsFromAssemblies();
-
builder.AddHttpClient();
+ var logger = new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.File("Logs/NeedleworkDotNet.log", rollingInterval: RollingInterval.Day, shared: true)
+ .CreateLogger();
+ logger.Debug("NeedleworkDotNet version: {Version}", Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0.0.0.0");
+ logger.Debug("OS description: {Description}", System.Runtime.InteropServices.RuntimeInformation.OSDescription);
+ builder.AddLogging(builder => builder.AddSerilog(logger));
+
var services = builder.BuildServiceProvider();
return services;
}
diff --git a/Needlework.Net/ViewModels/MainWindow/MainWindowViewModel.cs b/Needlework.Net/ViewModels/MainWindow/MainWindowViewModel.cs
index 2d473e6..30872d4 100644
--- a/Needlework.Net/ViewModels/MainWindow/MainWindowViewModel.cs
+++ b/Needlework.Net/ViewModels/MainWindow/MainWindowViewModel.cs
@@ -3,6 +3,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using FluentAvalonia.UI.Controls;
+using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Needlework.Net.Messages;
using Needlework.Net.Models;
@@ -42,8 +43,12 @@ public partial class MainWindowViewModel
[ObservableProperty] private ObservableCollection _infoBarItems = [];
- public MainWindowViewModel(IEnumerable pages, HttpClient httpClient, DialogService dialogService)
+ private readonly ILogger _logger;
+
+ public MainWindowViewModel(IEnumerable pages, HttpClient httpClient, DialogService dialogService, ILogger logger)
{
+ _logger = logger;
+
MenuItems = new AvaloniaList(pages
.OrderBy(p => p.Index)
.ThenBy(p => p.DisplayName)
@@ -83,7 +88,11 @@ public partial class MainWindowViewModel
var response = await HttpClient.SendAsync(request);
var release = await response.Content.ReadFromJsonAsync();
- if (release == null) return;
+ if (release == null)
+ {
+ _logger.LogWarning("Release response is null");
+ return;
+ }
var currentVersion = int.Parse(Version.Replace(".", ""));
@@ -101,18 +110,28 @@ public partial class MainWindowViewModel
});
}
}
- catch (Exception) { }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to check for latest version");
+ }
}
private async Task FetchDataAsync()
{
- var document = await Resources.GetOpenApiDocumentAsync(HttpClient);
- HostDocument = document;
- var handler = new OpenApiDocumentWrapper(document);
- OpenApiDocumentWrapper = handler;
+ try
+ {
+ var document = await Resources.GetOpenApiDocumentAsync(HttpClient);
+ HostDocument = document;
+ var handler = new OpenApiDocumentWrapper(document);
+ OpenApiDocumentWrapper = handler;
- WeakReferenceMessenger.Default.Send(new DataReadyMessage(handler));
- IsBusy = false;
+ WeakReferenceMessenger.Default.Send(new DataReadyMessage(handler));
+ IsBusy = false;
+ }
+ catch (HttpRequestException ex)
+ {
+ _logger.LogError(ex, "Failed to fetch OpenAPI data");
+ }
}
public void Receive(DataRequestMessage message)
diff --git a/Needlework.Net/ViewModels/Pages/ConsoleViewModel.cs b/Needlework.Net/ViewModels/Pages/ConsoleViewModel.cs
index f3be89c..59ae6e1 100644
--- a/Needlework.Net/ViewModels/Pages/ConsoleViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/ConsoleViewModel.cs
@@ -2,6 +2,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Messages;
using Needlework.Net.ViewModels.Shared;
using System.Threading.Tasks;
@@ -14,10 +15,11 @@ public partial class ConsoleViewModel : PageBase, IRecipient
public IAvaloniaList RequestPaths { get; } = new AvaloniaList();
[ObservableProperty] private bool _isBusy = true;
- [ObservableProperty] private LcuRequestViewModel _lcuRequest = new();
+ [ObservableProperty] private LcuRequestViewModel _lcuRequest;
- public ConsoleViewModel() : base("Console", "terminal", -200)
+ public ConsoleViewModel(ILogger lcuRequestViewModelLogger) : base("Console", "terminal", -200)
{
+ _lcuRequest = new(lcuRequestViewModelLogger);
WeakReferenceMessenger.Default.Register(this);
}
diff --git a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointViewModel.cs b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointViewModel.cs
index 713ebdb..921ba54 100644
--- a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointViewModel.cs
@@ -1,7 +1,9 @@
using Avalonia.Collections;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Messages;
+using Needlework.Net.ViewModels.Shared;
using System;
using System.Linq;
@@ -21,12 +23,12 @@ public partial class EndpointViewModel : ObservableObject
public event EventHandler? PathOperationSelected;
- public EndpointViewModel(string endpoint)
+ public EndpointViewModel(string endpoint, ILogger lcuRequestViewModelLogger)
{
Endpoint = endpoint;
var handler = WeakReferenceMessenger.Default.Send().Response;
- PathOperations = new AvaloniaList(handler.Plugins[endpoint].Select(x => new PathOperationViewModel(x)));
+ PathOperations = new AvaloniaList(handler.Plugins[endpoint].Select(x => new PathOperationViewModel(x, lcuRequestViewModelLogger)));
FilteredPathOperations = new AvaloniaList(PathOperations);
}
diff --git a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsNavigationViewModel.cs b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsNavigationViewModel.cs
index fe04b72..71a3d48 100644
--- a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsNavigationViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsNavigationViewModel.cs
@@ -1,6 +1,8 @@
using Avalonia.Collections;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using Microsoft.Extensions.Logging;
+using Needlework.Net.ViewModels.Shared;
using System;
namespace Needlework.Net.ViewModels.Pages.Endpoints;
@@ -15,9 +17,9 @@ public partial class EndpointsNavigationViewModel : ObservableObject
private readonly Action _onEndpointNavigation;
- public EndpointsNavigationViewModel(IAvaloniaList plugins, Action onEndpointNavigation)
+ public EndpointsNavigationViewModel(IAvaloniaList plugins, Action onEndpointNavigation, ILogger lcuRequestViewModelLogger)
{
- _activeViewModel = _endpointsViewModel = new EndpointsViewModel(plugins, OnClicked);
+ _activeViewModel = _endpointsViewModel = new EndpointsViewModel(plugins, OnClicked, lcuRequestViewModelLogger);
_onEndpointNavigation = onEndpointNavigation;
}
diff --git a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsTabViewModel.cs b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsTabViewModel.cs
index 0b50f7e..cf9e6a8 100644
--- a/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsTabViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/Endpoints/EndpointsTabViewModel.cs
@@ -4,7 +4,9 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using FluentAvalonia.UI.Controls;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Messages;
+using Needlework.Net.ViewModels.Shared;
using System;
namespace Needlework.Net.ViewModels.Pages.Endpoints;
@@ -16,8 +18,11 @@ public partial class EndpointsTabViewModel : PageBase, IRecipient _lcuRequestViewModelLogger;
+
+ public EndpointsTabViewModel(ILogger lcuRequestViewModelLogger) : base("Endpoints", "list-alt", -500)
{
+ _lcuRequestViewModelLogger = lcuRequestViewModelLogger;
WeakReferenceMessenger.Default.RegisterAll(this);
}
@@ -35,7 +40,7 @@ public partial class EndpointsTabViewModel : PageBase, IRecipient OnClicked { get; }
- public EndpointsViewModel(IAvaloniaList plugins, Action onClicked)
+ private readonly ILogger _lcuRequestViewModelLogger;
+
+ public EndpointsViewModel(IAvaloniaList plugins, Action onClicked, ILogger lcuRequestViewModelLogger)
{
Plugins = new AvaloniaList(plugins);
Query = new AvaloniaList(plugins);
OnClicked = onClicked;
+ _lcuRequestViewModelLogger = lcuRequestViewModelLogger;
}
partial void OnSearchChanged(string value)
@@ -37,6 +42,6 @@ public partial class EndpointsViewModel : ObservableObject
{
if (string.IsNullOrEmpty(value)) return;
- OnClicked.Invoke(new EndpointViewModel(value));
+ OnClicked.Invoke(new EndpointViewModel(value, _lcuRequestViewModelLogger));
}
}
diff --git a/Needlework.Net/ViewModels/Pages/Endpoints/PathOperationViewModel.cs b/Needlework.Net/ViewModels/Pages/Endpoints/PathOperationViewModel.cs
index 726828a..977cec6 100644
--- a/Needlework.Net/ViewModels/Pages/Endpoints/PathOperationViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/Endpoints/PathOperationViewModel.cs
@@ -1,5 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Models;
using Needlework.Net.ViewModels.Shared;
using System;
@@ -16,11 +17,11 @@ public partial class PathOperationViewModel : ObservableObject
[ObservableProperty] private bool _isBusy;
[ObservableProperty] private Lazy _lcuRequest;
- public PathOperationViewModel(PathOperation pathOperation)
+ public PathOperationViewModel(PathOperation pathOperation, ILogger lcuRequestViewModelLogger)
{
Path = pathOperation.Path;
Operation = new OperationViewModel(pathOperation.Operation);
- LcuRequest = new(() => new LcuRequestViewModel()
+ LcuRequest = new(() => new LcuRequestViewModel(lcuRequestViewModelLogger)
{
Method = pathOperation.Method.ToUpper()
});
diff --git a/Needlework.Net/ViewModels/Pages/Websocket/WebsocketViewModel.cs b/Needlework.Net/ViewModels/Pages/Websocket/WebsocketViewModel.cs
index 7f0fa4b..ea51159 100644
--- a/Needlework.Net/ViewModels/Pages/Websocket/WebsocketViewModel.cs
+++ b/Needlework.Net/ViewModels/Pages/Websocket/WebsocketViewModel.cs
@@ -3,11 +3,11 @@ using BlossomiShymae.GrrrLCU;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Messages;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
@@ -45,8 +45,11 @@ public partial class WebsocketViewModel : PageBase
public IReadOnlyList FilteredEventLog => string.IsNullOrWhiteSpace(Search) ? EventLog : [.. EventLog.Where(x => x.Key.Contains(Search, StringComparison.InvariantCultureIgnoreCase))];
- public WebsocketViewModel(HttpClient httpClient) : base("Event Viewer", "plug", -100)
+ private readonly ILogger _logger;
+
+ public WebsocketViewModel(HttpClient httpClient, ILogger logger) : base("Event Viewer", "plug", -100)
{
+ _logger = logger;
HttpClient = httpClient;
EventLog.CollectionChanged += (s, e) => OnPropertyChanged(nameof(FilteredEventLog));
Task.Run(async () =>
@@ -66,6 +69,7 @@ public partial class WebsocketViewModel : PageBase
}
catch (HttpRequestException ex)
{
+ _logger.LogError(ex, "Failed to get event types");
WeakReferenceMessenger.Default.Send(new InfoBarUpdateMessage(new("Failed to get event types", true, ex.Message, FluentAvalonia.UI.Controls.InfoBarSeverity.Error, TimeSpan.FromSeconds(10))));
}
}
@@ -76,6 +80,7 @@ public partial class WebsocketViewModel : PageBase
{
if (Client != null)
{
+ _logger.LogDebug("Disposing old connection");
foreach (var disposable in ClientDisposables)
disposable.Dispose();
ClientDisposables.Clear();
@@ -105,6 +110,7 @@ public partial class WebsocketViewModel : PageBase
})
{ IsBackground = true };
thread.Start();
+ _logger.LogDebug("Initialized new connection: {EventType}", EventType);
TokenSource = tokenSource;
}
}
@@ -129,12 +135,12 @@ public partial class WebsocketViewModel : PageBase
private void OnReconnection(ReconnectionInfo info)
{
- Trace.WriteLine($"-- Reconnection --\nType{info.Type}");
+ _logger.LogTrace("Reconnected: {Type}", info.Type);
}
private void OnDisconnection(DisconnectionInfo info)
{
- Trace.WriteLine($"-- Disconnection --\nType:{info.Type}\nSubProtocol:{info.SubProtocol}\nCloseStatus:{info.CloseStatus}\nCloseStatusDescription:{info.CloseStatusDescription}\nExceptionMessage:{info?.Exception?.Message}\n:InnerException:{info?.Exception?.InnerException}");
+ _logger.LogTrace("Disconnected: {Type}", info.Type);
InitializeWebsocket();
}
diff --git a/Needlework.Net/ViewModels/Shared/LcuRequestViewModel.cs b/Needlework.Net/ViewModels/Shared/LcuRequestViewModel.cs
index 52ceef8..fbe9c92 100644
--- a/Needlework.Net/ViewModels/Shared/LcuRequestViewModel.cs
+++ b/Needlework.Net/ViewModels/Shared/LcuRequestViewModel.cs
@@ -2,6 +2,7 @@
using BlossomiShymae.GrrrLCU;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
+using Microsoft.Extensions.Logging;
using Needlework.Net.Messages;
using Needlework.Net.ViewModels.MainWindow;
using System;
@@ -31,6 +32,13 @@ public partial class LcuRequestViewModel : ObservableObject
public event EventHandler? RequestText;
public event EventHandler? UpdateText;
+ private readonly ILogger _logger;
+
+ public LcuRequestViewModel(ILogger logger)
+ {
+ _logger = logger;
+ }
+
partial void OnMethodChanged(string? oldValue, string? newValue)
{
if (newValue == null) return;
@@ -59,6 +67,8 @@ public partial class LcuRequestViewModel : ObservableObject
_ => throw new Exception("Method is not selected or missing."),
};
+ _logger.LogDebug("Sending request: {Tuple}", (Method, RequestPath));
+
var processInfo = ProcessFinder.GetProcessInfo();
RequestText?.Invoke(this, this);
var content = new StringContent(RequestBody ?? string.Empty, new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
@@ -88,6 +98,7 @@ public partial class LcuRequestViewModel : ObservableObject
}
catch (Exception ex)
{
+ _logger.LogError(ex, "Request failed: {Tuple}", (Method, RequestPath));
WeakReferenceMessenger.Default.Send(new InfoBarUpdateMessage(new InfoBarViewModel("Request Failed", true, ex.Message, FluentAvalonia.UI.Controls.InfoBarSeverity.Error, TimeSpan.FromSeconds(5))));
UpdateText?.Invoke(this, string.Empty);