Include gRPC messages in plugin log
This commit is contained in:
parent
ce1285bff9
commit
350da5e916
77
Pal.Client/Net/GrpcLogger.cs
Normal file
77
Pal.Client/Net/GrpcLogger.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using Dalamud.Logging;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Pal.Client.Net
|
||||||
|
{
|
||||||
|
internal class GrpcLogger : ILogger
|
||||||
|
{
|
||||||
|
private readonly string _name;
|
||||||
|
|
||||||
|
public GrpcLogger(string name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDisposable BeginScope<TState>(TState 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)
|
||||||
|
{
|
||||||
|
if (!IsEnabled(logLevel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (formatter == null)
|
||||||
|
throw new ArgumentNullException(nameof(formatter));
|
||||||
|
|
||||||
|
string message = $"gRPC[{_name}] {formatter(state, null)}";
|
||||||
|
if (string.IsNullOrEmpty(message))
|
||||||
|
return;
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
case LogLevel.Critical:
|
||||||
|
PluginLog.Fatal(exception, message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogLevel.Error:
|
||||||
|
PluginLog.Error(exception, message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogLevel.Warning:
|
||||||
|
PluginLog.Warning(exception, message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogLevel.Information:
|
||||||
|
PluginLog.Information(exception, message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogLevel.Debug:
|
||||||
|
PluginLog.Debug(exception, message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LogLevel.Trace:
|
||||||
|
PluginLog.Verbose(exception, message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#pragma warning restore CS8604
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NullScope : IDisposable
|
||||||
|
{
|
||||||
|
public static NullScope Instance { get; } = new NullScope();
|
||||||
|
|
||||||
|
private NullScope()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
Pal.Client/Net/GrpcLoggerProvider.cs
Normal file
14
Pal.Client/Net/GrpcLoggerProvider.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Pal.Client.Net
|
||||||
|
{
|
||||||
|
internal class GrpcLoggerProvider : ILoggerProvider
|
||||||
|
{
|
||||||
|
public ILogger CreateLogger(string categoryName) => new GrpcLogger(categoryName);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Palace;
|
using Palace;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -13,7 +14,7 @@ using System.Security.Cryptography.X509Certificates;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pal.Client
|
namespace Pal.Client.Net
|
||||||
{
|
{
|
||||||
internal class RemoteApi : IDisposable
|
internal class RemoteApi : IDisposable
|
||||||
{
|
{
|
||||||
@ -24,6 +25,8 @@ namespace Pal.Client
|
|||||||
#endif
|
#endif
|
||||||
private readonly string UserAgent = $"{typeof(RemoteApi).Assembly.GetName().Name?.Replace(" ", "")}/{typeof(RemoteApi).Assembly.GetName().Version?.ToString(2)}";
|
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 GrpcChannel? _channel;
|
private GrpcChannel? _channel;
|
||||||
private LoginReply? _lastLoginReply;
|
private LoginReply? _lastLoginReply;
|
||||||
private bool _warnedAboutUpgrade = false;
|
private bool _warnedAboutUpgrade = false;
|
||||||
@ -43,7 +46,7 @@ namespace Pal.Client
|
|||||||
private string PartialAccountId =>
|
private string PartialAccountId =>
|
||||||
AccountId?.ToString()?.PadRight(14).Substring(0, 13) ?? "[no account id]";
|
AccountId?.ToString()?.PadRight(14).Substring(0, 13) ?? "[no account id]";
|
||||||
|
|
||||||
private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken, bool retry = true)
|
private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken, ILoggerFactory? loggerFactory = null, bool retry = true)
|
||||||
{
|
{
|
||||||
if (Service.Configuration.Mode != Configuration.EMode.Online)
|
if (Service.Configuration.Mode != Configuration.EMode.Online)
|
||||||
{
|
{
|
||||||
@ -62,7 +65,8 @@ namespace Pal.Client
|
|||||||
{
|
{
|
||||||
ConnectTimeout = TimeSpan.FromSeconds(5),
|
ConnectTimeout = TimeSpan.FromSeconds(5),
|
||||||
SslOptions = GetSslClientAuthenticationOptions(),
|
SslOptions = GetSslClientAuthenticationOptions(),
|
||||||
}
|
},
|
||||||
|
LoggerFactory = loggerFactory,
|
||||||
});
|
});
|
||||||
|
|
||||||
PluginLog.Information($"TryConnect: Connecting to upstream service at {remoteUrl}");
|
PluginLog.Information($"TryConnect: Connecting to upstream service at {remoteUrl}");
|
||||||
@ -105,11 +109,11 @@ namespace Pal.Client
|
|||||||
_lastLoginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = AccountId?.ToString() }, headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
_lastLoginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = AccountId?.ToString() }, headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||||
if (_lastLoginReply.Success)
|
if (_lastLoginReply.Success)
|
||||||
{
|
{
|
||||||
PluginLog.Information($"TryConnect: Login successful with account id: {PartialAccountId}, auth token: {_lastLoginReply.AuthToken}");
|
PluginLog.Information($"TryConnect: Login successful with account id: {PartialAccountId}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PluginLog.Error($"TryConnect: Login failed with error { _lastLoginReply.Error}");
|
PluginLog.Error($"TryConnect: Login failed with error {_lastLoginReply.Error}");
|
||||||
if (_lastLoginReply.Error == LoginError.InvalidAccountId)
|
if (_lastLoginReply.Error == LoginError.InvalidAccountId)
|
||||||
{
|
{
|
||||||
AccountId = null;
|
AccountId = null;
|
||||||
@ -154,7 +158,7 @@ namespace Pal.Client
|
|||||||
{
|
{
|
||||||
_warnedAboutUpgrade = false;
|
_warnedAboutUpgrade = false;
|
||||||
|
|
||||||
var connectionResult = await TryConnect(cancellationToken);
|
var connectionResult = await TryConnect(cancellationToken, loggerFactory: _grpcToPluginLogLoggerFactory);
|
||||||
if (!connectionResult.Success)
|
if (!connectionResult.Success)
|
||||||
return $"Could not connect to server: {connectionResult.Error}";
|
return $"Could not connect to server: {connectionResult.Error}";
|
||||||
|
|
||||||
@ -217,7 +221,7 @@ namespace Pal.Client
|
|||||||
|
|
||||||
private Marker CreateMarkerFromNetworkObject(PalaceObject obj) =>
|
private Marker CreateMarkerFromNetworkObject(PalaceObject obj) =>
|
||||||
new Marker((Marker.EType)obj.Type, new Vector3(obj.X, obj.Y, obj.Z), Guid.Parse(obj.NetworkId));
|
new Marker((Marker.EType)obj.Type, new Vector3(obj.X, obj.Y, obj.Z), Guid.Parse(obj.NetworkId));
|
||||||
|
|
||||||
public async Task<(bool, List<FloorStatistics>)> FetchStatistics(CancellationToken cancellationToken = default)
|
public async Task<(bool, List<FloorStatistics>)> FetchStatistics(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!await Connect(cancellationToken))
|
if (!await Connect(cancellationToken))
|
@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<LangVersion>9.0</LangVersion>
|
<LangVersion>9.0</LangVersion>
|
||||||
<Version>1.17.0.0</Version>
|
<Version>1.18.0.0</Version>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@ -37,6 +37,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -8,6 +8,7 @@ using Dalamud.Game.Gui;
|
|||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
|
using Pal.Client.Net;
|
||||||
|
|
||||||
namespace Pal.Client
|
namespace Pal.Client
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user