1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-20 12:53:02 +00:00

Implement high-performance logging (#193)

* Implement high-performance logging
This commit is contained in:
Jonnern
2024-03-22 16:39:32 +01:00
committed by GitHub
parent 108c8fc183
commit de72fe4fb9
11 changed files with 1293 additions and 112 deletions
+33 -32
View File
@@ -6,11 +6,10 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using CryptoExchange.Net.Objects;
using System.Net.WebSockets;
using System.IO;
using CryptoExchange.Net.Objects.Sockets;
using System.Diagnostics;
using CryptoExchange.Net.Clients;
using CryptoExchange.Net.Converters.JsonNet;
using CryptoExchange.Net.Logging.Extensions;
using System.Threading;
namespace CryptoExchange.Net.Sockets
@@ -130,7 +129,7 @@ namespace CryptoExchange.Net.Sockets
if (_pausedActivity != value)
{
_pausedActivity = value;
_logger.Log(LogLevel.Information, $"[Sckt {SocketId}] paused activity: " + value);
_logger.ActivityPaused(SocketId, value);
if(_pausedActivity) _ = Task.Run(() => ActivityPaused?.Invoke());
else _ = Task.Run(() => ActivityUnpaused?.Invoke());
}
@@ -150,7 +149,7 @@ namespace CryptoExchange.Net.Sockets
var oldStatus = _status;
_status = value;
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] status changed from {oldStatus} to {_status}");
_logger.SocketStatusChanged(SocketId, oldStatus, value);
}
}
@@ -301,7 +300,7 @@ namespace CryptoExchange.Net.Sockets
var reconnectSuccessful = await ProcessReconnectAsync().ConfigureAwait(false);
if (!reconnectSuccessful)
{
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] failed reconnect processing: {reconnectSuccessful.Error}, reconnecting again");
_logger.FailedReconnectProcessing(SocketId, reconnectSuccessful.Error?.ToString());
_ = _socket.ReconnectAsync().ConfigureAwait(false);
}
else
@@ -316,7 +315,7 @@ namespace CryptoExchange.Net.Sockets
}
catch(Exception ex)
{
_logger.Log(LogLevel.Warning, ex, $"[Sckt {SocketId}] Unknown exception while processing reconnection, reconnecting again");
_logger.UnkownExceptionWhileProcessingReconnection(SocketId, ex);
_ = _socket.ReconnectAsync().ConfigureAwait(false);
}
});
@@ -331,9 +330,9 @@ namespace CryptoExchange.Net.Sockets
protected virtual Task HandleErrorAsync(Exception e)
{
if (e is WebSocketException wse)
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] error: Websocket error code {wse.WebSocketErrorCode}, details: " + e.ToLogString());
_logger.WebSocketErrorCodeAndDetails(SocketId, wse.WebSocketErrorCode, wse.Message, wse);
else
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] error: " + e.ToLogString());
_logger.WebSocketError(SocketId, e.Message, e);
return Task.CompletedTask;
}
@@ -352,7 +351,7 @@ namespace CryptoExchange.Net.Sockets
if (query == null)
{
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] msg {requestId} - message sent, but not pending");
_logger.MessageSentNotPending(SocketId, requestId);
return Task.CompletedTask;
}
@@ -379,18 +378,20 @@ namespace CryptoExchange.Net.Sockets
_accessor.Read(data);
try
{
if (ApiClient.ApiOptions.OutputOriginalData ?? ApiClient.ClientOptions.OutputOriginalData)
bool outputOriginalData = ApiClient.ApiOptions.OutputOriginalData ?? ApiClient.ClientOptions.OutputOriginalData;
if (outputOriginalData)
{
originalData = _accessor.GetOriginalString();
_logger.LogTrace("[Sckt {SocketId}] received {Data}", SocketId, originalData);
_logger.ReceivedData(SocketId, originalData);
}
// 3. Determine the identifying properties of this message
var listenId = ApiClient.GetListenerIdentifier(_accessor);
if (listenId == null)
{
originalData = outputOriginalData ? _accessor.GetOriginalString() : "[OutputOriginalData is false]";
if (!ApiClient.UnhandledMessageExpected)
_logger.LogWarning("[Sckt {SocketId}] failed to evaluate message", SocketId);
_logger.FailedToEvaluateMessage(SocketId, originalData);
UnhandledMessage?.Invoke(_accessor);
return;
@@ -408,14 +409,14 @@ namespace CryptoExchange.Net.Sockets
List<string> listenerIds;
lock (_listenersLock)
listenerIds = _listeners.Where(l => l.CanHandleData).SelectMany(l => l.ListenerIdentifiers).ToList();
_logger.LogWarning("[Sckt {SocketId}] received message not matched to any listener. ListenId: {ListenId}, current listeners: {ListenIds}", SocketId, listenId, listenerIds);
_logger.ReceivedMessageNotMatchedToAnyListener(SocketId, listenId, string.Join(",", listenerIds));
UnhandledMessage?.Invoke(_accessor);
}
return;
}
_logger.LogTrace("[Sckt {SocketId}] {Count} processor(s) matched to message with listener identifier {ListenerId}", SocketId, processors.Count, listenId);
_logger.ProcessorMatched(SocketId, processors.Count, listenId);
var totalUserTime = 0;
Dictionary<Type, object>? desCache = null;
if (processors.Count > 1)
@@ -430,7 +431,7 @@ namespace CryptoExchange.Net.Sockets
var messageType = processor.GetMessageType(_accessor);
if (messageType == null)
{
_logger.LogWarning("[Sckt {SocketId}] received message not recognized by handler {Id}", SocketId, processor.Id);
_logger.ReceivedMessageNotRecognized(SocketId, processor.Id);
continue;
}
@@ -443,7 +444,7 @@ namespace CryptoExchange.Net.Sockets
var desResult = processor.Deserialize(_accessor, messageType);
if (!desResult)
{
_logger.LogWarning("[Sckt {SocketId}] deserialization failed: {Error}", SocketId, desResult.Error);
_logger.FailedToDeserializeMessage(SocketId, desResult.Error?.ToString());
continue;
}
deserialized = desResult.Data;
@@ -459,13 +460,13 @@ namespace CryptoExchange.Net.Sockets
}
catch (Exception ex)
{
_logger.LogWarning("[Sckt {SocketId}] user message processing failed: {Exception}", SocketId, ex.ToLogString());
_logger.UserMessageProcessingFailed(SocketId, ex.ToLogString(), ex);
if (processor is Subscription subscription)
subscription.InvokeExceptionHandler(ex);
}
}
_logger.LogTrace($"[Sckt {SocketId}] message processed in {(int)sw.ElapsedMilliseconds}ms ({sw.ElapsedMilliseconds - totalUserTime}ms parsing)");
_logger.MessageProcessed(SocketId, sw.ElapsedMilliseconds, sw.ElapsedMilliseconds - totalUserTime);
}
finally
{
@@ -529,7 +530,7 @@ namespace CryptoExchange.Net.Sockets
if (Status == SocketStatus.Closing || Status == SocketStatus.Closed || Status == SocketStatus.Disposed)
return;
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] closing subscription {subscription.Id}");
_logger.ClosingSubscription(SocketId, subscription.Id);
if (subscription.CancellationTokenRegistration.HasValue)
subscription.CancellationTokenRegistration.Value.Dispose();
@@ -548,12 +549,12 @@ namespace CryptoExchange.Net.Sockets
}
else
{
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] not unsubscribing subscription as there is still a duplicate subscription running");
_logger.NotUnsubscribingSubscriptionBecauseDuplicateRunning(SocketId);
}
if (Status == SocketStatus.Closing)
{
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] already closing");
_logger.AlreadyClosing(SocketId);
return;
}
@@ -567,7 +568,7 @@ namespace CryptoExchange.Net.Sockets
if (shouldCloseConnection)
{
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] closing as there are no more subscriptions");
_logger.ClosingNoMoreSubscriptions(SocketId);
await CloseAsync().ConfigureAwait(false);
}
@@ -605,7 +606,7 @@ namespace CryptoExchange.Net.Sockets
_listeners.Add(subscription);
if (subscription.UserSubscription)
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] adding new subscription with id {subscription.Id}, total subscriptions on connection: {UserSubscriptionCount}");
_logger.AddingNewSubscription(SocketId, subscription.Id, UserSubscriptionCount);
return true;
}
@@ -713,7 +714,7 @@ namespace CryptoExchange.Net.Sockets
return new CallResult(new InvalidOperationError(info));
}
_logger.Log(LogLevel.Trace, $"[Sckt {SocketId}] msg {requestId} - sending messsage: {data}");
_logger.SendingData(SocketId, requestId, data);
try
{
_socket.Send(requestId, data, weight);
@@ -736,7 +737,7 @@ namespace CryptoExchange.Net.Sockets
if (!anySubscriptions)
{
// No need to resubscribe anything
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] nothing to resubscribe, closing connection");
_logger.NothingToResubscribeCloseConnection(SocketId);
_ = _socket.CloseAsync();
return new CallResult<bool>(true);
}
@@ -750,12 +751,12 @@ namespace CryptoExchange.Net.Sockets
var authResult = await ApiClient.AuthenticateSocketAsync(this).ConfigureAwait(false);
if (!authResult)
{
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] authentication failed on reconnected socket. Disconnecting and reconnecting.");
_logger.FailedAuthenticationDisconnectAndRecoonect(SocketId);
return authResult;
}
Authenticated = true;
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] authentication succeeded on reconnected socket.");
_logger.AuthenticationSucceeded(SocketId);
}
// Get a list of all subscriptions on the socket
@@ -769,7 +770,7 @@ namespace CryptoExchange.Net.Sockets
var result = await ApiClient.RevitalizeRequestAsync(subscription).ConfigureAwait(false);
if (!result)
{
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] failed request revitalization: " + result.Error);
_logger.FailedRequestRevitalization(SocketId, result.Error?.ToString());
return result;
}
}
@@ -807,7 +808,7 @@ namespace CryptoExchange.Net.Sockets
if (!_socket.IsOpen)
return new CallResult<bool>(new WebError("Socket not connected"));
_logger.Log(LogLevel.Debug, $"[Sckt {SocketId}] all subscription successfully resubscribed on reconnected socket.");
_logger.AllSubscriptionResubscribed(SocketId);
return new CallResult<bool>(true);
}
@@ -818,7 +819,7 @@ namespace CryptoExchange.Net.Sockets
return;
await SendAndWaitQueryAsync(unsubscribeRequest).ConfigureAwait(false);
_logger.Log(LogLevel.Information, $"[Sckt {SocketId}] subscription {subscription!.Id} unsubscribed");
_logger.SubscriptionUnsubscribed(SocketId, subscription.Id);
}
internal async Task<CallResult> ResubscribeAsync(Subscription subscription)
@@ -869,7 +870,7 @@ namespace CryptoExchange.Net.Sockets
if (query == null)
continue;
_logger.Log(LogLevel.Trace, $"[Sckt {SocketId}] sending periodic {identifier}");
_logger.SendingPeriodic(SocketId, identifier);
try
{
@@ -878,7 +879,7 @@ namespace CryptoExchange.Net.Sockets
}
catch (Exception ex)
{
_logger.Log(LogLevel.Warning, $"[Sckt {SocketId}] Periodic send {identifier} failed: " + ex.ToLogString());
_logger.PeriodicSendFailed(SocketId, identifier, ex.ToLogString(), ex);
}
}
});