mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-10 17:36:19 +00:00
added optional request tracing id for much better logs reading
This commit is contained in:
parent
4b1baf8b82
commit
9b8950747f
@ -588,6 +588,11 @@
|
||||
Uri
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Interfaces.IRequest.RequestId">
|
||||
<summary>
|
||||
internal request id for tracing
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.IRequest.SetContent(System.Byte[])">
|
||||
<summary>
|
||||
Set byte content
|
||||
@ -628,12 +633,13 @@
|
||||
<param name="uri"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Interfaces.IRequestFactory.Configure(System.TimeSpan,CryptoExchange.Net.Objects.ApiProxy)">
|
||||
<member name="M:CryptoExchange.Net.Interfaces.IRequestFactory.Configure(System.TimeSpan,CryptoExchange.Net.Objects.ApiProxy,System.Boolean)">
|
||||
<summary>
|
||||
Configure the requests created by this factory
|
||||
</summary>
|
||||
<param name="requestTimeout">Request timeout to use</param>
|
||||
<param name="proxy">Proxy settings to use</param>
|
||||
<param name="isTracingEnabled">Should generate unique id for requests</param>
|
||||
</member>
|
||||
<member name="T:CryptoExchange.Net.Interfaces.IResponse">
|
||||
<summary>
|
||||
@ -1772,7 +1778,7 @@
|
||||
</member>
|
||||
<member name="E:CryptoExchange.Net.OrderBook.SymbolOrderBook.OnOrderBookUpdate">
|
||||
<summary>
|
||||
Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets
|
||||
Event when order book was updated, containing the changed bids and asks. Be careful! It can generate a lot of events at high-liquidity markets
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.OrderBook.SymbolOrderBook.LastOrderBookUpdate">
|
||||
@ -2025,12 +2031,13 @@
|
||||
Request object
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Requests.Request.#ctor(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpClient)">
|
||||
<member name="M:CryptoExchange.Net.Requests.Request.#ctor(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpClient,System.Boolean)">
|
||||
<summary>
|
||||
Create request object for web request
|
||||
</summary>
|
||||
<param name="request"></param>
|
||||
<param name="client"></param>
|
||||
<param name="isTracingEnabled">if true, should assign unique id for request</param>
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Requests.Request.Content">
|
||||
<inheritdoc />
|
||||
@ -2044,6 +2051,9 @@
|
||||
<member name="P:CryptoExchange.Net.Requests.Request.Uri">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="P:CryptoExchange.Net.Requests.Request.RequestId">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Requests.Request.SetContent(System.String,System.String)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
@ -2061,7 +2071,7 @@
|
||||
WebRequest factory
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Requests.RequestFactory.Configure(System.TimeSpan,CryptoExchange.Net.Objects.ApiProxy)">
|
||||
<member name="M:CryptoExchange.Net.Requests.RequestFactory.Configure(System.TimeSpan,CryptoExchange.Net.Objects.ApiProxy,System.Boolean)">
|
||||
<inheritdoc />
|
||||
</member>
|
||||
<member name="M:CryptoExchange.Net.Requests.RequestFactory.Create(System.Net.Http.HttpMethod,System.String)">
|
||||
@ -3094,148 +3104,3 @@
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
System.Diagnostics.CodeAnalysis.AllowNullAttribute">
|
||||
<summary>
|
||||
Specifies that <see langword="null"/> is allowed as an input even if the
|
||||
corresponding type disallows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.AllowNullAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute">
|
||||
<summary>
|
||||
Specifies that <see langword="null"/> is disallowed as an input even if the
|
||||
corresponding type allows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.DisallowNullAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute">
|
||||
<summary>
|
||||
Specifies that a method that will never return under any circumstance.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute">
|
||||
<summary>
|
||||
Specifies that the method will not return if the associated <see cref="T:System.Boolean"/>
|
||||
parameter is passed the specified value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.ParameterValue">
|
||||
<summary>
|
||||
Gets the condition parameter value.
|
||||
Code after the method is considered unreachable by diagnostics if the argument
|
||||
to the associated parameter matches this value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.#ctor(System.Boolean)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute"/>
|
||||
class with the specified parameter value.
|
||||
</summary>
|
||||
<param name="parameterValue">
|
||||
The condition parameter value.
|
||||
Code after the method is considered unreachable by diagnostics if the argument
|
||||
to the associated parameter matches this value.
|
||||
</param>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute">
|
||||
<summary>
|
||||
Specifies that an output may be <see langword="null"/> even if the
|
||||
corresponding type disallows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute">
|
||||
<summary>
|
||||
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue"/>,
|
||||
the parameter may be <see langword="null"/> even if the corresponding type disallows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue">
|
||||
<summary>
|
||||
Gets the return value condition.
|
||||
If the method returns this value, the associated parameter may be <see langword="null"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.#ctor(System.Boolean)">
|
||||
<summary>
|
||||
Initializes the attribute with the specified return value condition.
|
||||
</summary>
|
||||
<param name="returnValue">
|
||||
The return value condition.
|
||||
If the method returns this value, the associated parameter may be <see langword="null"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.NotNullAttribute">
|
||||
<summary>
|
||||
Specifies that an output is not <see langword="null"/> even if the
|
||||
corresponding type allows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.NotNullAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.NotNullAttribute"/> class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute">
|
||||
<summary>
|
||||
Specifies that the output will be non-<see langword="null"/> if the
|
||||
named parameter is non-<see langword="null"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.ParameterName">
|
||||
<summary>
|
||||
Gets the associated parameter name.
|
||||
The output will be non-<see langword="null"/> if the argument to the
|
||||
parameter specified is non-<see langword="null"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.#ctor(System.String)">
|
||||
<summary>
|
||||
Initializes the attribute with the associated parameter name.
|
||||
</summary>
|
||||
<param name="parameterName">
|
||||
The associated parameter name.
|
||||
The output will be non-<see langword="null"/> if the argument to the
|
||||
parameter specified is non-<see langword="null"/>.
|
||||
</param>
|
||||
</member>
|
||||
<member name="T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute">
|
||||
<summary>
|
||||
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue"/>,
|
||||
the parameter will not be <see langword="null"/> even if the corresponding type allows it.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue">
|
||||
<summary>
|
||||
Gets the return value condition.
|
||||
If the method returns this value, the associated parameter will not be <see langword="null"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.#ctor(System.Boolean)">
|
||||
<summary>
|
||||
Initializes the attribute with the specified return value condition.
|
||||
</summary>
|
||||
<param name="returnValue">
|
||||
The return value condition.
|
||||
If the method returns this value, the associated parameter will not be <see langword="null"/>.
|
||||
</param>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
@ -27,6 +27,10 @@ namespace CryptoExchange.Net.Interfaces
|
||||
/// </summary>
|
||||
Uri Uri { get; }
|
||||
/// <summary>
|
||||
/// internal request id for tracing
|
||||
/// </summary>
|
||||
string? RequestId { get; }
|
||||
/// <summary>
|
||||
/// Set byte content
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
|
@ -22,6 +22,7 @@ namespace CryptoExchange.Net.Interfaces
|
||||
/// </summary>
|
||||
/// <param name="requestTimeout">Request timeout to use</param>
|
||||
/// <param name="proxy">Proxy settings to use</param>
|
||||
void Configure(TimeSpan requestTimeout, ApiProxy? proxy);
|
||||
/// <param name="isTracingEnabled">Should generate unique id for requests</param>
|
||||
void Configure(TimeSpan requestTimeout, ApiProxy? proxy, bool isTracingEnabled=false);
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// The time the server has to respond to a request before timing out
|
||||
/// </summary>
|
||||
public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(30);
|
||||
|
||||
public bool IsRequestsTracingEnabled { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="client"></param>
|
||||
public Request(HttpRequestMessage request, HttpClient client)
|
||||
/// <param name="isTracingEnabled">if true, should assign unique id for request</param>
|
||||
public Request(HttpRequestMessage request, HttpClient client, bool isTracingEnabled=false)
|
||||
{
|
||||
httpClient = client;
|
||||
this.request = request;
|
||||
if (isTracingEnabled)
|
||||
{
|
||||
RequestId = Path.GetRandomFileName();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -45,6 +51,8 @@ namespace CryptoExchange.Net.Requests
|
||||
|
||||
/// <inheritdoc />
|
||||
public Uri Uri => request.RequestUri;
|
||||
/// <inheritdoc />
|
||||
public string? RequestId { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetContent(string data, string contentType)
|
||||
|
@ -12,10 +12,11 @@ namespace CryptoExchange.Net.Requests
|
||||
public class RequestFactory : IRequestFactory
|
||||
{
|
||||
private HttpClient? httpClient;
|
||||
|
||||
private bool isTracingEnabled;
|
||||
/// <inheritdoc />
|
||||
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 };
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<IRateLimiter>();
|
||||
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<T>(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<T>(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<T>(null, null, default, new CancellationRequestedError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Request timed out
|
||||
log.Write(LogVerbosity.Warning, "Request timed out");
|
||||
return new WebCallResult<T>(null, null, default, new WebError("Request timed out"));
|
||||
log.Write(LogVerbosity.Warning, $"Request {request.RequestId} timed out");
|
||||
return new WebCallResult<T>(null, null, default, new WebError($"Request {request.RequestId} timed out"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user