diff --git a/CryptoExchange.Net/CryptoExchange.Net.xml b/CryptoExchange.Net/CryptoExchange.Net.xml
index 7995e9f..ed94e55 100644
--- a/CryptoExchange.Net/CryptoExchange.Net.xml
+++ b/CryptoExchange.Net/CryptoExchange.Net.xml
@@ -588,6 +588,11 @@
Uri
+
+
+ internal request id for tracing
+
+
Set byte content
@@ -628,12 +633,13 @@
-
+
Configure the requests created by this factory
Request timeout to use
Proxy settings to use
+ Should generate unique id for requests
@@ -2024,12 +2030,13 @@
Request object
-
+
Create request object for web request
+ if true, should assign unique id for request
@@ -2043,6 +2050,9 @@
+
+
+
@@ -2060,7 +2070,7 @@
WebRequest factory
-
+
diff --git a/CryptoExchange.Net/Interfaces/IRequest.cs b/CryptoExchange.Net/Interfaces/IRequest.cs
index 9e819cb..9d02651 100644
--- a/CryptoExchange.Net/Interfaces/IRequest.cs
+++ b/CryptoExchange.Net/Interfaces/IRequest.cs
@@ -27,6 +27,10 @@ namespace CryptoExchange.Net.Interfaces
///
Uri Uri { get; }
///
+ /// internal request id for tracing
+ ///
+ string? RequestId { get; }
+ ///
/// Set byte content
///
///
diff --git a/CryptoExchange.Net/Interfaces/IRequestFactory.cs b/CryptoExchange.Net/Interfaces/IRequestFactory.cs
index ceb7f8c..d519fe9 100644
--- a/CryptoExchange.Net/Interfaces/IRequestFactory.cs
+++ b/CryptoExchange.Net/Interfaces/IRequestFactory.cs
@@ -22,6 +22,7 @@ namespace CryptoExchange.Net.Interfaces
///
/// Request timeout to use
/// Proxy settings to use
- void Configure(TimeSpan requestTimeout, ApiProxy? proxy);
+ /// Should generate unique id for requests
+ void Configure(TimeSpan requestTimeout, ApiProxy? proxy, bool isTracingEnabled=false);
}
}
diff --git a/CryptoExchange.Net/Objects/Options.cs b/CryptoExchange.Net/Objects/Options.cs
index 75bca6c..edaa423 100644
--- a/CryptoExchange.Net/Objects/Options.cs
+++ b/CryptoExchange.Net/Objects/Options.cs
@@ -126,7 +126,7 @@ namespace CryptoExchange.Net.Objects
/// The time the server has to respond to a request before timing out
///
public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(30);
-
+ public bool IsRequestsTracingEnabled { get; set; } = false;
///
/// ctor
///
diff --git a/CryptoExchange.Net/Requests/Request.cs b/CryptoExchange.Net/Requests/Request.cs
index 5c4530c..0afa03e 100644
--- a/CryptoExchange.Net/Requests/Request.cs
+++ b/CryptoExchange.Net/Requests/Request.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
@@ -21,10 +22,15 @@ namespace CryptoExchange.Net.Requests
///
///
///
- public Request(HttpRequestMessage request, HttpClient client)
+ /// if true, should assign unique id for request
+ public Request(HttpRequestMessage request, HttpClient client, bool isTracingEnabled=false)
{
httpClient = client;
this.request = request;
+ if (isTracingEnabled)
+ {
+ RequestId = Path.GetRandomFileName();
+ }
}
///
@@ -45,6 +51,8 @@ namespace CryptoExchange.Net.Requests
///
public Uri Uri => request.RequestUri;
+ ///
+ public string? RequestId { get; }
///
public void SetContent(string data, string contentType)
diff --git a/CryptoExchange.Net/Requests/RequestFactory.cs b/CryptoExchange.Net/Requests/RequestFactory.cs
index 2434ca1..dd5d861 100644
--- a/CryptoExchange.Net/Requests/RequestFactory.cs
+++ b/CryptoExchange.Net/Requests/RequestFactory.cs
@@ -12,10 +12,11 @@ namespace CryptoExchange.Net.Requests
public class RequestFactory : IRequestFactory
{
private HttpClient? httpClient;
-
+ private bool isTracingEnabled;
///
- public void Configure(TimeSpan requestTimeout, ApiProxy? proxy)
+ public void Configure(TimeSpan requestTimeout, ApiProxy? proxy, bool isTracingEnabled = false)
{
+ this.isTracingEnabled = isTracingEnabled;
HttpMessageHandler handler = new HttpClientHandler()
{
Proxy = proxy == null ? null : new WebProxy
@@ -25,7 +26,7 @@ namespace CryptoExchange.Net.Requests
}
};
- httpClient = new HttpClient(handler) {Timeout = requestTimeout};
+ httpClient = new HttpClient(handler) { Timeout = requestTimeout };
}
///
@@ -34,7 +35,7 @@ namespace CryptoExchange.Net.Requests
if (httpClient == null)
throw new InvalidOperationException("Cant create request before configuring http client");
- return new Request(new HttpRequestMessage(method, uri), httpClient);
+ return new Request(new HttpRequestMessage(method, uri), httpClient, isTracingEnabled);
}
}
}
diff --git a/CryptoExchange.Net/RestClient.cs b/CryptoExchange.Net/RestClient.cs
index d3a0f55..1072ca8 100644
--- a/CryptoExchange.Net/RestClient.cs
+++ b/CryptoExchange.Net/RestClient.cs
@@ -83,7 +83,7 @@ namespace CryptoExchange.Net
throw new ArgumentNullException(nameof(exchangeOptions));
RequestTimeout = exchangeOptions.RequestTimeout;
- RequestFactory.Configure(exchangeOptions.RequestTimeout, exchangeOptions.Proxy);
+ RequestFactory.Configure(exchangeOptions.RequestTimeout, exchangeOptions.Proxy,exchangeOptions.IsRequestsTracingEnabled);
RateLimitBehaviour = exchangeOptions.RateLimitingBehaviour;
var rateLimiters = new List();
foreach (var rateLimiter in exchangeOptions.RateLimiters)
@@ -190,14 +190,14 @@ namespace CryptoExchange.Net
}
if (limitResult.Data > 0)
- log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} was limited by {limitResult.Data}ms by {limiter.GetType().Name}");
+ log.Write(LogVerbosity.Debug, $"Request {request.RequestId} {uri.AbsolutePath} was limited by {limitResult.Data}ms by {limiter.GetType().Name}");
}
string? paramString = null;
if (method == HttpMethod.Post)
paramString = " with request body " + request.Content;
- log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null? "": $" via proxy {apiProxy.Host}")}");
+ log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null? "": $" via proxy {apiProxy.Host}")} {(request.RequestId==null?"":$" with id {request.RequestId}")}");
return await GetResponse(request, cancellationToken).ConfigureAwait(false);
}
@@ -224,7 +224,7 @@ namespace CryptoExchange.Net
var data = await reader.ReadToEndAsync().ConfigureAwait(false);
responseStream.Close();
response.Close();
- log.Write(LogVerbosity.Debug, $"Data received: {data}");
+ log.Write(LogVerbosity.Debug, $"Data {(request.RequestId==null?"":$"for request {request.RequestId} ")}received: {data}");
var parseResult = ValidateJson(data);
if (!parseResult.Success)
@@ -249,7 +249,7 @@ namespace CryptoExchange.Net
{
using var reader = new StreamReader(responseStream);
var data = await reader.ReadToEndAsync().ConfigureAwait(false);
- log.Write(LogVerbosity.Debug, $"Error received: {data}");
+ log.Write(LogVerbosity.Debug, $"Error {(request.RequestId == null ? "" : $"for request {request.RequestId} ")}received: {data}");
responseStream.Close();
response.Close();
var parseResult = ValidateJson(data);
@@ -258,7 +258,7 @@ namespace CryptoExchange.Net
}
catch (HttpRequestException requestException)
{
- log.Write(LogVerbosity.Warning, "Request exception: " + requestException.Message);
+ log.Write(LogVerbosity.Warning, $"Request {request.RequestId} exception: " + requestException.Message);
return new WebCallResult(null, null, default, new ServerError(requestException.Message));
}
catch (TaskCanceledException canceledException)
@@ -266,14 +266,14 @@ namespace CryptoExchange.Net
if(canceledException.CancellationToken == cancellationToken)
{
// Cancellation token cancelled
- log.Write(LogVerbosity.Warning, "Request cancel requested");
+ log.Write(LogVerbosity.Warning, $"Request {request.RequestId} cancel requested");
return new WebCallResult(null, null, default, new CancellationRequestedError());
}
else
{
// Request timed out
- log.Write(LogVerbosity.Warning, "Request timed out");
- return new WebCallResult(null, null, default, new WebError("Request timed out"));
+ log.Write(LogVerbosity.Warning, $"Request {request.RequestId} timed out");
+ return new WebCallResult(null, null, default, new WebError($"Request {request.RequestId} timed out"));
}
}
}