Logging: Update PluginLog to use Microsoft.Extensions.Logging instead

This commit is contained in:
Liza 2023-02-17 00:54:23 +01:00
parent a5456a54a0
commit 0bb7301ca1
21 changed files with 216 additions and 94 deletions

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text.Json.Serialization;
using Dalamud.Logging;
using Microsoft.Extensions.Logging;
using Pal.Client.DependencyInjection.Logging;
namespace Pal.Client.Configuration
{
@ -10,6 +12,9 @@ namespace Pal.Client.Configuration
{
private const int DefaultEntropyLength = 16;
private static readonly ILogger _logger =
DependencyInjectionContext.LoggerProvider.CreateLogger<AccountConfigurationV7>();
[JsonConstructor]
public AccountConfigurationV7()
{
@ -74,7 +79,7 @@ namespace Pal.Client.Configuration
}
catch (Exception e)
{
PluginLog.Verbose(e, $"Could not load account id {EncryptedId}");
_logger.LogTrace(e, "Could not load account id {Id}", EncryptedId);
return null;
}
}

View File

@ -2,11 +2,16 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using Microsoft.Extensions.Logging;
using Pal.Client.DependencyInjection.Logging;
namespace Pal.Client.Configuration
{
internal static class ConfigurationData
{
private static readonly ILogger _logger =
DependencyInjectionContext.LoggerProvider.CreateLogger(typeof(ConfigurationData));
[Obsolete("for V1 import")]
internal static readonly byte[] FixedV1Entropy = { 0x22, 0x4b, 0xe7, 0x21, 0x44, 0x83, 0x69, 0x55, 0x80, 0x38 };
@ -30,7 +35,7 @@ namespace Pal.Client.Configuration
_supportsDpapi = false;
}
PluginLog.Verbose($"DPAPI support: {_supportsDpapi}");
_logger.LogTrace("DPAPI support: {Supported}", _supportsDpapi);
}
return _supportsDpapi.Value;
}

View File

@ -8,6 +8,7 @@ using Dalamud.Logging;
using Dalamud.Plugin;
using ImGuiNET;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Pal.Client.Database;
using NJson = Newtonsoft.Json;
@ -15,13 +16,15 @@ namespace Pal.Client.Configuration
{
internal sealed class ConfigurationManager
{
private readonly ILogger<ConfigurationManager> _logger;
private readonly DalamudPluginInterface _pluginInterface;
private readonly IServiceProvider _serviceProvider;
public event EventHandler<IPalacePalConfiguration>? Saved;
public ConfigurationManager(DalamudPluginInterface pluginInterface, IServiceProvider serviceProvider)
public ConfigurationManager(ILogger<ConfigurationManager> logger, DalamudPluginInterface pluginInterface, IServiceProvider serviceProvider)
{
_logger = logger;
_pluginInterface = pluginInterface;
_serviceProvider = serviceProvider;
@ -54,12 +57,12 @@ namespace Pal.Client.Configuration
{
if (_pluginInterface.ConfigFile.Exists)
{
PluginLog.Information("Migrating config file from v1-v6 format");
_logger.LogInformation("Migrating config file from v1-v6 format");
ConfigurationV1 configurationV1 =
NJson.JsonConvert.DeserializeObject<ConfigurationV1>(
File.ReadAllText(_pluginInterface.ConfigFile.FullName)) ?? new ConfigurationV1();
configurationV1.Migrate(_pluginInterface);
configurationV1.Migrate(_pluginInterface, _serviceProvider.GetRequiredService<ILogger<ConfigurationV1>>());
configurationV1.Save(_pluginInterface);
var v7 = MigrateToV7(configurationV1);
@ -72,7 +75,7 @@ namespace Pal.Client.Configuration
foreach (var importHistory in configurationV1.ImportHistory)
{
PluginLog.Information($"Migrating import {importHistory.Id}");
_logger.LogInformation("Migrating import {Id}", importHistory.Id);
dbContext.Imports.Add(new ImportHistory
{
Id = importHistory.Id,

View File

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Numerics;
using Dalamud.Plugin;
using Microsoft.Extensions.Logging;
namespace Pal.Client.Configuration
{
@ -50,11 +51,11 @@ namespace Pal.Client.Configuration
public string BetaKey { get; set; } = "";
#endregion
public void Migrate(DalamudPluginInterface pluginInterface)
public void Migrate(DalamudPluginInterface pluginInterface, ILogger<ConfigurationV1> logger)
{
if (Version == 1)
{
PluginLog.Information("Updating config to version 2");
logger.LogInformation("Updating config to version 2");
if (DebugAccountId != null && Guid.TryParse(DebugAccountId, out Guid debugAccountId))
AccountIds["http://localhost:5145"] = debugAccountId;
@ -68,7 +69,7 @@ namespace Pal.Client.Configuration
if (Version == 2)
{
PluginLog.Information("Updating config to version 3");
logger.LogInformation("Updating config to version 3");
Accounts = AccountIds.ToDictionary(x => x.Key, x => new AccountInfo
{

View File

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Pal.Client.Database;
@ -24,12 +27,12 @@ namespace Pal.Client.DependencyInjection
dbContext.SaveChanges();
}
public ImportHistory? FindLast()
public async Task<ImportHistory?> FindLast(CancellationToken token = default)
{
using var scope = _serviceProvider.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<PalClientContext>();
await using var scope = _serviceProvider.CreateAsyncScope();
await using var dbContext = scope.ServiceProvider.GetRequiredService<PalClientContext>();
return dbContext.Imports.OrderByDescending(x => x.ImportedAt).ThenBy(x => x.Id).FirstOrDefault();
return await dbContext.Imports.OrderByDescending(x => x.ImportedAt).ThenBy(x => x.Id).FirstOrDefaultAsync(cancellationToken: token);
}
public List<ImportHistory> FindForServer(string server)

View File

@ -1,27 +1,33 @@
using Dalamud.Logging;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Pal.Client.Net
namespace Pal.Client.DependencyInjection.Logging
{
internal sealed class GrpcLogger : ILogger
internal sealed class DalamudLogger : ILogger
{
private readonly string _name;
private readonly IExternalScopeProvider? _scopeProvider;
public GrpcLogger(string name)
public DalamudLogger(string name, IExternalScopeProvider? scopeProvider)
{
_name = name;
_scopeProvider = scopeProvider;
}
public IDisposable BeginScope<TState>(TState state)
where TState : notnull
=> NullScope.Instance;
=> _scopeProvider?.Push(state) ?? NullScope.Instance;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
[MethodImpl(MethodImplOptions.NoInlining)] // PluginLog detects the plugin name as `Microsoft.Extensions.Logging` if inlined
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
// PluginLog detects the plugin name as `Microsoft.Extensions.Logging` if inlined
[MethodImpl(MethodImplOptions.NoInlining)]
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
return;
@ -29,9 +35,23 @@ namespace Pal.Client.Net
if (formatter == null)
throw new ArgumentNullException(nameof(formatter));
string message = $"gRPC[{_name}] {formatter(state, null)}";
if (string.IsNullOrEmpty(message))
return;
StringBuilder sb = new StringBuilder();
_scopeProvider?.ForEachScope((scope, builder) =>
{
if (scope is IEnumerable<KeyValuePair<string, object>> properties)
{
foreach (KeyValuePair<string, object> pair in properties)
{
builder.Append('<').Append(pair.Key).Append('=').Append(pair.Value)
.Append("> ");
}
}
else if (scope != null)
builder.Append('<').Append(scope).Append("> ");
},
sb);
sb.Append('[').Append(_name).Append("] ").Append(formatter(state, null));
string message = sb.ToString();
#pragma warning disable CS8604 // the nullability on PluginLog methods is wrong and allows nulls for exceptions, WriteLog even declares the parameter as `Exception? exception = null`
switch (logLevel)
@ -63,7 +83,7 @@ namespace Pal.Client.Net
#pragma warning restore CS8604
}
private class NullScope : IDisposable
private sealed class NullScope : IDisposable
{
public static NullScope Instance { get; } = new();

View File

@ -0,0 +1,31 @@
using Microsoft.Extensions.Logging;
using System;
namespace Pal.Client.DependencyInjection.Logging
{
internal sealed class DalamudLoggerProvider : ILoggerProvider, ISupportExternalScope
{
private IExternalScopeProvider? _scopeProvider;
public ILogger CreateLogger(string categoryName) => new DalamudLogger(categoryName, _scopeProvider);
/// <summary>
/// Manual logger creation, doesn't handle scopes.
/// </summary>
public ILogger CreateLogger(Type type) => CreateLogger(type.FullName ?? type.ToString());
/// <summary>
/// Manual logger creation, doesn't handle scopes.
/// </summary>
public ILogger CreateLogger<T>() => CreateLogger(typeof(T));
public void SetScopeProvider(IExternalScopeProvider scopeProvider)
{
_scopeProvider = scopeProvider;
}
public void Dispose()
{
}
}
}

View File

@ -2,16 +2,17 @@
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Dalamud.Plugin;
using Microsoft.Extensions.Logging;
using Pal.Client.Extensions;
using Pal.Client.Properties;
namespace Pal.Client.DependencyInjection
{
public class RepoVerification
internal sealed class RepoVerification
{
public RepoVerification(DalamudPluginInterface pluginInterface, ChatGui chatGui)
public RepoVerification(ILogger<RepoVerification> logger, DalamudPluginInterface pluginInterface, ChatGui chatGui)
{
PluginLog.Information($"Install source: {pluginInterface.SourceRepository}");
logger.LogInformation("Install source: {Repo}", pluginInterface.SourceRepository);
if (!pluginInterface.IsDev
&& !pluginInterface.SourceRepository.StartsWith("https://raw.githubusercontent.com/carvelli/")
&& !pluginInterface.SourceRepository.StartsWith("https://github.com/carvelli/"))

View File

@ -16,10 +16,12 @@ using Dalamud.Plugin;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Pal.Client.Commands;
using Pal.Client.Configuration;
using Pal.Client.Database;
using Pal.Client.DependencyInjection;
using Pal.Client.DependencyInjection.Logging;
using Pal.Client.Net;
using Pal.Client.Properties;
using Pal.Client.Rendering;
@ -34,6 +36,9 @@ namespace Pal.Client
// ReSharper disable once UnusedType.Global
internal sealed class DependencyInjectionContext : IDalamudPlugin
{
public static DalamudLoggerProvider LoggerProvider { get; } = new();
private readonly ILogger _logger = LoggerProvider.CreateLogger<DependencyInjectionContext>();
private readonly string _sqliteConnectionString;
private readonly CancellationTokenSource _initCts = new();
private ServiceProvider? _serviceProvider;
@ -50,11 +55,16 @@ namespace Pal.Client
CommandManager commandManager,
DataManager dataManager)
{
PluginLog.Information("Building service container");
// Temporary logger, will be overriden later
_logger.LogInformation("Building service container");
CancellationToken token = _initCts.Token;
IServiceCollection services = new ServiceCollection();
services.AddLogging(builder =>
builder.AddFilter("Microsoft.EntityFrameworkCore.Database", LogLevel.Warning)
.AddFilter("Grpc", LogLevel.Debug)
.ClearProviders()
.AddProvider(LoggerProvider));
// dalamud
services.AddSingleton<IDalamudPlugin>(this);
services.AddSingleton(pluginInterface);
@ -134,21 +144,24 @@ namespace Pal.Client
//
// There's 2-3 seconds of slowdown primarily caused by the sqlite init, but that needs to happen for
// config stuff.
PluginLog.Information("Service container built, triggering async init");
_logger = _serviceProvider.GetRequiredService<ILogger<DependencyInjectionContext>>();
_logger.LogInformation("Service container built, triggering async init");
Task.Run(async () =>
{
using IDisposable? logScope = _logger.BeginScope("AsyncInit");
try
{
PluginLog.Information("Starting async init");
_logger.LogInformation("Starting async init");
// initialize database
await using (var scope = _serviceProvider.CreateAsyncScope())
{
PluginLog.Log("Loading database & running migrations");
_logger.LogInformation("Loading database & running migrations");
await using var dbContext = scope.ServiceProvider.GetRequiredService<PalClientContext>();
await dbContext.Database.MigrateAsync();
PluginLog.Log("Completed database migrations");
_logger.LogInformation("Completed database migrations");
}
token.ThrowIfCancellationRequested();
@ -169,14 +182,14 @@ namespace Pal.Client
token.ThrowIfCancellationRequested();
_serviceProvider.GetRequiredService<Plugin>();
PluginLog.Information("Async init complete");
_logger.LogInformation("Async init complete");
}
catch (ObjectDisposedException)
{
}
catch (Exception e)
{
PluginLog.Error(e, "Async load failed");
_logger.LogError(e, "Async load failed");
chatGui.PrintError($"Async loading failed: {e.GetType()}: {e.Message}");
}
});

View File

@ -6,12 +6,14 @@ using Dalamud.Utility.Signatures;
using System;
using System.Text;
using Dalamud.Game.ClientState.Objects;
using Microsoft.Extensions.Logging;
using Pal.Client.DependencyInjection;
namespace Pal.Client
{
internal sealed unsafe class Hooks : IDisposable
{
private readonly ILogger<Hooks> _logger;
private readonly ObjectTable _objectTable;
private readonly TerritoryState _territoryState;
private readonly FrameworkService _frameworkService;
@ -23,8 +25,9 @@ namespace Pal.Client
private Hook<ActorVfxCreateDelegate> ActorVfxCreateHook { get; init; } = null!;
#pragma warning restore CS0649
public Hooks(ObjectTable objectTable, TerritoryState territoryState, FrameworkService frameworkService)
public Hooks(ILogger<Hooks> logger, ObjectTable objectTable, TerritoryState territoryState, FrameworkService frameworkService)
{
_logger = logger;
_objectTable = objectTable;
_territoryState = territoryState;
_frameworkService = frameworkService;
@ -86,7 +89,7 @@ namespace Pal.Client
}
catch (Exception e)
{
PluginLog.Error(e, "VFX Create Hook failed");
_logger.LogError(e, "VFX Create Hook failed");
}
return ActorVfxCreateHook.Original(a1, a2, a3, a4, a5, a6, a7);
}

View File

@ -1,14 +0,0 @@
using Microsoft.Extensions.Logging;
using System;
namespace Pal.Client.Net
{
internal sealed class GrpcLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName) => new GrpcLogger(categoryName);
public void Dispose()
{
}
}
}

View File

@ -1,5 +1,4 @@
using Account;
using Dalamud.Logging;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
@ -19,9 +18,11 @@ namespace Pal.Client.Net
{
private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken, ILoggerFactory? loggerFactory = null, bool retry = true)
{
using IDisposable? logScope = _logger.BeginScope("TryConnect");
if (_configuration.Mode != EMode.Online)
{
PluginLog.Debug("TryConnect: Not Online, not attempting to establish a connection");
_logger.LogDebug("Not Online, not attempting to establish a connection");
return (false, Localization.ConnectionError_NotOnline);
}
@ -29,7 +30,7 @@ namespace Pal.Client.Net
{
Dispose();
PluginLog.Information("TryConnect: Creating new gRPC channel");
_logger.LogInformation("Creating new gRPC channel");
_channel = GrpcChannel.ForAddress(RemoteUrl, new GrpcChannelOptions
{
HttpHandler = new SocketsHttpHandler
@ -40,7 +41,7 @@ namespace Pal.Client.Net
LoggerFactory = loggerFactory,
});
PluginLog.Information($"TryConnect: Connecting to upstream service at {RemoteUrl}");
_logger.LogInformation("Connecting to upstream service at {Url}", RemoteUrl);
await _channel.ConnectAsync(cancellationToken);
}
@ -50,7 +51,7 @@ namespace Pal.Client.Net
IAccountConfiguration? configuredAccount = _configuration.FindAccount(RemoteUrl);
if (configuredAccount == null)
{
PluginLog.Information($"TryConnect: No account information saved for {RemoteUrl}, creating new account");
_logger.LogInformation("No account information saved for {Url}, creating new account", RemoteUrl);
var createAccountReply = await accountClient.CreateAccountAsync(new CreateAccountRequest(), headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
if (createAccountReply.Success)
{
@ -58,13 +59,13 @@ namespace Pal.Client.Net
throw new InvalidOperationException("invalid account id returned");
configuredAccount = _configuration.CreateAccount(RemoteUrl, accountId);
PluginLog.Information($"TryConnect: Account created with id {accountId.ToPartialId()}");
_logger.LogInformation("Account created with id {AccountId}", accountId.ToPartialId());
_configurationManager.Save(_configuration);
}
else
{
PluginLog.Error($"TryConnect: Account creation failed with error {createAccountReply.Error}");
_logger.LogError("Account creation failed with error {Error}", createAccountReply.Error);
if (createAccountReply.Error == CreateAccountError.UpgradeRequired && !_warnedAboutUpgrade)
{
_chatGui.PalError(Localization.ConnectionError_OldVersion);
@ -79,17 +80,17 @@ namespace Pal.Client.Net
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (configuredAccount == null)
{
PluginLog.Warning("TryConnect: No account to login with");
_logger.LogWarning("No account to login with");
return (false, Localization.ConnectionError_CreateAccountReturnedNoId);
}
if (!_loginInfo.IsValid)
{
PluginLog.Information($"TryConnect: Logging in with account id {configuredAccount.AccountId.ToPartialId()}");
_logger.LogInformation("Logging in with account id {AccountId}", configuredAccount.AccountId.ToPartialId());
LoginReply loginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = configuredAccount.AccountId.ToString() }, headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
if (loginReply.Success)
{
PluginLog.Information($"TryConnect: Login successful with account id: {configuredAccount.AccountId.ToPartialId()}");
_logger.LogInformation("Login successful with account id: {AccountId}", configuredAccount.AccountId.ToPartialId());
_loginInfo = new LoginInfo(loginReply.AuthToken);
bool save = configuredAccount.EncryptIfNeeded();
@ -106,7 +107,7 @@ namespace Pal.Client.Net
}
else
{
PluginLog.Error($"TryConnect: Login failed with error {loginReply.Error}");
_logger.LogError("Login failed with error {Error}", loginReply.Error);
_loginInfo = new LoginInfo(null);
if (loginReply.Error == LoginError.InvalidAccountId)
{
@ -114,7 +115,7 @@ namespace Pal.Client.Net
_configurationManager.Save(_configuration);
if (retry)
{
PluginLog.Information("TryConnect: Attempting connection retry without account id");
_logger.LogInformation("Attempting connection retry without account id");
return await TryConnect(cancellationToken, retry: false);
}
else
@ -131,7 +132,7 @@ namespace Pal.Client.Net
if (!_loginInfo.IsValid)
{
PluginLog.Error($"TryConnect: Login state is loggedIn={_loginInfo.IsLoggedIn}, expired={_loginInfo.IsExpired}");
_logger.LogError("Login state is loggedIn={LoggedIn}, expired={Expired}", _loginInfo.IsLoggedIn, _loginInfo.IsExpired);
return (false, Localization.ConnectionError_LoginReturnedNoToken);
}
@ -147,17 +148,19 @@ namespace Pal.Client.Net
public async Task<string> VerifyConnection(CancellationToken cancellationToken = default)
{
using IDisposable? logScope = _logger.BeginScope("VerifyConnection");
_warnedAboutUpgrade = false;
var connectionResult = await TryConnect(cancellationToken, loggerFactory: _grpcToPluginLogLoggerFactory);
var connectionResult = await TryConnect(cancellationToken, loggerFactory: _loggerFactory);
if (!connectionResult.Success)
return string.Format(Localization.ConnectionError_CouldNotConnectToServer, connectionResult.Error);
PluginLog.Information("VerifyConnection: Connection established, trying to verify auth token");
_logger.LogInformation("Connection established, trying to verify auth token");
var accountClient = new AccountService.AccountServiceClient(_channel);
await accountClient.VerifyAsync(new VerifyRequest(), headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
PluginLog.Information("VerifyConnection: Verification returned no errors.");
_logger.LogInformation("Verification returned no errors.");
return Localization.ConnectionSuccessful;
}

View File

@ -3,6 +3,7 @@ using Dalamud.Logging;
using Grpc.Core;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Logging;
namespace Pal.Client.Net
{
@ -40,7 +41,7 @@ namespace Pal.Client.Net
throw new InvalidOperationException();
var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.DefaultKeySet);
PluginLog.Debug($"Using client certificate {certificate.GetCertHashString()}");
_logger.LogDebug("Using client certificate {CertificateHash}", certificate.GetCertHashString());
return new SslClientAuthenticationOptions
{
ClientCertificates = new X509CertificateCollection()
@ -49,7 +50,7 @@ namespace Pal.Client.Net
},
};
#else
PluginLog.Debug("Not using client certificate");
_logger.LogDebug("Not using client certificate");
return null;
#endif
}

View File

@ -17,9 +17,8 @@ namespace Pal.Client.Net
private readonly string _userAgent =
$"{typeof(RemoteApi).Assembly.GetName().Name?.Replace(" ", "")}/{typeof(RemoteApi).Assembly.GetName().Version?.ToString(2)}";
private readonly ILoggerFactory _grpcToPluginLogLoggerFactory = LoggerFactory.Create(builder =>
builder.AddProvider(new GrpcLoggerProvider()).AddFilter("Grpc", LogLevel.Trace));
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger<RemoteApi> _logger;
private readonly ChatGui _chatGui;
private readonly ConfigurationManager _configurationManager;
private readonly IPalacePalConfiguration _configuration;
@ -28,9 +27,15 @@ namespace Pal.Client.Net
private LoginInfo _loginInfo = new(null);
private bool _warnedAboutUpgrade;
public RemoteApi(ChatGui chatGui, ConfigurationManager configurationManager,
public RemoteApi(
ILoggerFactory loggerFactory,
ILogger<RemoteApi> logger,
ChatGui chatGui,
ConfigurationManager configurationManager,
IPalacePalConfiguration configuration)
{
_loggerFactory = loggerFactory;
_logger = logger;
_chatGui = chatGui;
_configurationManager = configurationManager;
_configuration = configuration;
@ -38,7 +43,7 @@ namespace Pal.Client.Net
public void Dispose()
{
PluginLog.Debug("Disposing gRPC channel");
_logger.LogDebug("Disposing gRPC channel");
_channel?.Dispose();
_channel = null;
}

View File

@ -13,6 +13,7 @@ using System.Numerics;
using System.Reflection;
using Dalamud.Game.ClientState;
using Dalamud.Game.Gui;
using Microsoft.Extensions.Logging;
using Pal.Client.DependencyInjection;
using Pal.Client.Extensions;
@ -22,19 +23,24 @@ namespace Pal.Client.Rendering
{
private const long OnTerritoryChange = -2;
private readonly ILogger<SplatoonRenderer> _logger;
private readonly DebugState _debugState;
private readonly ClientState _clientState;
private readonly ChatGui _chatGui;
public SplatoonRenderer(DalamudPluginInterface pluginInterface, IDalamudPlugin dalamudPlugin,
public SplatoonRenderer(
ILogger<SplatoonRenderer> logger,
DalamudPluginInterface pluginInterface,
IDalamudPlugin dalamudPlugin,
DebugState debugState,
ClientState clientState, ChatGui chatGui)
{
_logger = logger;
_debugState = debugState;
_clientState = clientState;
_chatGui = chatGui;
PluginLog.Information("Initializing splatoon...");
_logger.LogInformation("Initializing splatoon...");
ECommonsMain.Init(pluginInterface, dalamudPlugin, ECommons.Module.SplatoonAPI);
}
@ -53,7 +59,7 @@ namespace Pal.Client.Rendering
}
catch (Exception e)
{
PluginLog.Error(e, $"Could not create splatoon layer {layer} with {elements.Count} elements");
_logger.LogError(e, "Could not create splatoon layer {Layer} with {Count} elements", layer, elements.Count);
_debugState.SetFromException(e);
}
});
@ -67,7 +73,7 @@ namespace Pal.Client.Rendering
}
catch (Exception e)
{
PluginLog.Error(e, $"Could not reset splatoon layer {layer}");
_logger.LogError(e, "Could not reset splatoon layer {Layer}", layer);
}
}

View File

@ -1,4 +1,6 @@
using Dalamud.Logging;
using System.Reflection.Metadata;
using Dalamud.Logging;
using Microsoft.Extensions.Logging;
namespace Pal.Client.Scheduled
{
@ -12,18 +14,25 @@ namespace Pal.Client.Scheduled
internal abstract class Handler<T> : IHandler
where T : IQueueOnFrameworkThread
{
protected readonly ILogger<Handler<T>> _logger;
protected Handler(ILogger<Handler<T>> logger)
{
_logger = logger;
}
protected abstract void Run(T queued, ref bool recreateLayout, ref bool saveMarkers);
public void RunIfCompatible(IQueueOnFrameworkThread queued, ref bool recreateLayout, ref bool saveMarkers)
{
if (queued is T t)
{
PluginLog.Information($"Handling {queued.GetType()} with handler {GetType()}");
_logger.LogInformation("Handling {QueuedType}", queued.GetType());
Run(t, ref recreateLayout, ref saveMarkers);
}
else
{
PluginLog.Error($"Could not use queue handler {GetType()} with type {queued.GetType()}");
_logger.LogError("Could not use queue handler {QueuedType}", queued.GetType());
}
}
}

View File

@ -1,4 +1,5 @@
using Pal.Client.Configuration;
using Microsoft.Extensions.Logging;
using Pal.Client.Configuration;
using Pal.Client.DependencyInjection;
namespace Pal.Client.Scheduled
@ -11,8 +12,9 @@ namespace Pal.Client.Scheduled
private readonly FloorService _floorService;
private readonly TerritoryState _territoryState;
public Handler(IPalacePalConfiguration configuration, FloorService floorService,
public Handler(ILogger<Handler> logger, IPalacePalConfiguration configuration, FloorService floorService,
TerritoryState territoryState)
: base(logger)
{
_configuration = configuration;
_floorService = floorService;

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Numerics;
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Microsoft.Extensions.Logging;
using Pal.Client.Database;
using Pal.Client.DependencyInjection;
using Pal.Client.Extensions;
@ -36,10 +37,12 @@ namespace Pal.Client.Scheduled
private readonly ConfigWindow _configWindow;
public Handler(
ILogger<Handler> logger,
ChatGui chatGui,
FloorService floorService,
ImportService importService,
ConfigWindow configWindow)
: base(logger)
{
_chatGui = chatGui;
_floorService = floorService;
@ -83,14 +86,14 @@ namespace Pal.Client.Scheduled
});
_configWindow.UpdateLastImport();
PluginLog.Information(
_logger.LogInformation(
$"Imported {import.ExportId} for {import.ImportedTraps} traps, {import.ImportedHoardCoffers} hoard coffers");
_chatGui.PalMessage(string.Format(Localization.ImportCompleteStatistics, import.ImportedTraps,
import.ImportedHoardCoffers));
}
catch (Exception e)
{
PluginLog.Error(e, "Import failed");
_logger.LogError(e, "Import failed");
_chatGui.PalError(string.Format(Localization.Error_ImportFailed, e));
}
}
@ -99,15 +102,15 @@ namespace Pal.Client.Scheduled
{
if (import.Export.ExportVersion != ExportConfig.ExportVersion)
{
PluginLog.Error(
$"Import: Different version in export file, {import.Export.ExportVersion} != {ExportConfig.ExportVersion}");
_logger.LogError(
"Import: Different version in export file, {ExportVersion} != {ConfiguredVersion}", import.Export.ExportVersion, ExportConfig.ExportVersion);
_chatGui.PalError(Localization.Error_ImportFailed_IncompatibleVersion);
return false;
}
if (!Guid.TryParse(import.Export.ExportId, out Guid exportId) || exportId == Guid.Empty)
{
PluginLog.Error($"Import: Invalid export id ({import.Export.ExportId})");
_logger.LogError("Import: Invalid export id '{Id}'", import.Export.ExportId);
_chatGui.PalError(Localization.Error_ImportFailed_InvalidFile);
return false;
}
@ -117,7 +120,7 @@ namespace Pal.Client.Scheduled
if (string.IsNullOrEmpty(import.Export.ServerUrl))
{
// If we allow for backups as import/export, this should be removed
PluginLog.Error("Import: No server URL");
_logger.LogError("Import: No server URL");
_chatGui.PalError(Localization.Error_ImportFailed_InvalidFile);
return false;
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using Pal.Client.Configuration;
using Pal.Client.DependencyInjection;
using Pal.Client.Extensions;
@ -22,7 +23,13 @@ namespace Pal.Client.Scheduled
private readonly TerritoryState _territoryState;
private readonly DebugState _debugState;
public Handler(IPalacePalConfiguration configuration, FloorService floorService, TerritoryState territoryState, DebugState debugState)
public Handler(
ILogger<Handler> logger,
IPalacePalConfiguration configuration,
FloorService floorService,
TerritoryState territoryState,
DebugState debugState)
: base(logger)
{
_configuration = configuration;
_floorService = floorService;

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Pal.Client.Configuration;
using Pal.Client.DependencyInjection;
using Pal.Client.Windows;
@ -22,7 +23,8 @@ namespace Pal.Client.Scheduled
private readonly FloorService _floorService;
private readonly ConfigWindow _configWindow;
public Handler(ImportService importService, FloorService floorService, ConfigWindow configWindow)
public Handler(ILogger<Handler> logger, ImportService importService, FloorService floorService, ConfigWindow configWindow)
: base(logger)
{
_importService = importService;
_floorService = floorService;

View File

@ -19,6 +19,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Game.Gui;
using Microsoft.Extensions.Logging;
using Pal.Client.Properties;
using Pal.Client.Configuration;
using Pal.Client.Database;
@ -31,6 +32,7 @@ namespace Pal.Client.Windows
{
private const string WindowId = "###PalPalaceConfig";
private readonly ILogger<ConfigWindow> _logger;
private readonly WindowSystem _windowSystem;
private readonly ConfigurationManager _configurationManager;
private readonly IPalacePalConfiguration _configuration;
@ -60,8 +62,10 @@ namespace Pal.Client.Windows
private ImportHistory? _lastImport;
private CancellationTokenSource? _testConnectionCts;
private CancellationTokenSource? _lastImportCts;
public ConfigWindow(
ILogger<ConfigWindow> logger,
WindowSystem windowSystem,
ConfigurationManager configurationManager,
IPalacePalConfiguration configuration,
@ -75,6 +79,7 @@ namespace Pal.Client.Windows
ImportService importService)
: base(WindowId)
{
_logger = logger;
_windowSystem = windowSystem;
_configurationManager = configurationManager;
_configuration = configuration;
@ -105,6 +110,7 @@ namespace Pal.Client.Windows
public void Dispose()
{
_windowSystem.RemoveWindow(this);
_lastImportCts?.Cancel();
_testConnectionCts?.Cancel();
}
@ -454,11 +460,11 @@ namespace Pal.Client.Windows
{
if (cts == _testConnectionCts)
{
PluginLog.Error(e, "Could not establish remote connection");
_logger.LogError(e, "Could not establish remote connection");
_connectionText = e.ToString();
}
else
PluginLog.Warning(e,
_logger.LogWarning(e,
"Could not establish a remote connection, but user also clicked 'test connection' again so not updating UI");
}
});
@ -476,7 +482,14 @@ namespace Pal.Client.Windows
internal void UpdateLastImport()
{
_lastImport = _importService.FindLast();
_lastImportCts?.Cancel();
CancellationTokenSource cts = new CancellationTokenSource();
_lastImportCts = cts;
Task.Run(async () =>
{
_lastImport = await _importService.FindLast(cts.Token);
}, cts.Token);
}
private void DoExport(string destinationPath)
@ -500,7 +513,7 @@ namespace Pal.Client.Windows
}
catch (Exception e)
{
PluginLog.Error(e, "Export failed");
_logger.LogError(e, "Export failed");
_chatGui.PalError($"Export failed: {e}");
}
});