From 6eb7d3009bbb36a5c710a18b34cb52818a1ba98f Mon Sep 17 00:00:00 2001 From: kgrudzien Date: Wed, 27 Mar 2024 10:46:19 +0100 Subject: [PATCH] latency_type param --- .../CoinAPI.WebSocket.Stats.Console.csproj | 4 +-- .../Program.cs | 33 +++++++++++++++++-- .../Properties/launchSettings.json | 2 +- .../CoinAPI.WebSocket.Stats.Console/README.md | 31 ++++++++++++++++- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/CoinAPI.WebSocket.Stats.Console.csproj b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/CoinAPI.WebSocket.Stats.Console.csproj index a512348f8a..4f4bfbbf87 100644 --- a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/CoinAPI.WebSocket.Stats.Console.csproj +++ b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/CoinAPI.WebSocket.Stats.Console.csproj @@ -1,8 +1,8 @@ - + Exe - net6.0 + net8.0 enable enable diff --git a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Program.cs b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Program.cs index 058911b500..a1258d0520 100644 --- a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Program.cs +++ b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Program.cs @@ -30,6 +30,13 @@ internal enum Endpoints ncsa } +internal enum LatencyType +{ + nc, //Now-CoinAPI + ne, //Now-Exchange + ce, //CoinAPI-Exchange +} + internal class Program { public static IConfiguration Configuration { get; private set; } @@ -75,7 +82,7 @@ static async Task Main(string[] args) public async Task MakeRequest([FromService] IConfiguration configuration, string endpoint_name = null, string subscribe_data_type = null, string asset = null, string symbol = null, - string exchange = null, string apikey = null, string type = "hello", bool supress_hb = false) + string exchange = null, string apikey = null, string type = "hello", bool supress_hb = false, string latency_type = "ce") { var typeNames = Enum.GetNames().ToList(); if (!typeNames.Any(x => x == subscribe_data_type)) @@ -90,12 +97,19 @@ public async Task MakeRequest([FromService] IConfiguration configuration, string Serilog.Log.Error($"Invalid endpoint_name, valid values: {string.Join(",", endpointNames)}"); return; } + var latencyTypes = Enum.GetNames().ToList(); + if (!string.IsNullOrWhiteSpace(latency_type) && !latencyTypes.Any(x => x == latency_type)) + { + Serilog.Log.Error($"Invalid latency_type, valid values: {string.Join(",", latencyTypes)}"); + return; + } using (var wsClient = string.IsNullOrWhiteSpace(endpoint_name) ? new CoinApiWsClient() : new CoinApiWsClient(Endpoints[endpoint_name])) { wsClient.SupressHeartbeat(supress_hb); int msgCount = 0; int errorCount = 0; + LatencyType latencyType = Enum.GetValues().FirstOrDefault(x => x.ToString() == latency_type); void WsClient_Error(object? sender, Exception e) { @@ -112,7 +126,18 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi) msgCount++; if (time_coinapi.HasValue && time_exchange.HasValue) { - latencyList.Add((time_exchange.Value, time_coinapi.Value)); + switch(latencyType) + { + case LatencyType.nc: + latencyList.Add((DateTime.UtcNow, time_coinapi.Value)); + break; + case LatencyType.ne: + latencyList.Add((DateTime.UtcNow, time_exchange.Value)); + break; + case LatencyType.ce: + latencyList.Add((time_coinapi.Value, time_exchange.Value)); + break; + } } } @@ -180,6 +205,8 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi) { strbld.Append($", symbol = {symbol}"); } + strbld.Append($", supress_hb = {supress_hb}"); + strbld.Append($", latency_type = {latency_type}"); Serilog.Log.Information(strbld.ToString()); @@ -222,7 +249,7 @@ void ProcessMsg(DateTime? time_exchange, DateTime? time_coinapi) var msgCountOnInterval = msgCount - msgCountPrev; var bytesCountOnInterval = wsClient.TotalBytesReceived - totalBytesReceivedPrev; - var latencies = latencyList.Select(x => x.Item2 - x.Item1).ToList(); + var latencies = latencyList.Select(x => x.Item1 - x.Item2).ToList(); latencyList.Clear(); diff --git a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Properties/launchSettings.json b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Properties/launchSettings.json index 36053d8f3a..da852efd1f 100644 --- a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Properties/launchSettings.json +++ b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "CoinAPI.WebSocket.Stats.Console": { "commandName": "Project", - "commandLineArgs": "--subscribe_data_type book --symbol COINBASE_SPOT_BTC_USD$" + "commandLineArgs": "" } } } \ No newline at end of file diff --git a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/README.md b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/README.md index 25a7c94dc2..8b9a8184e1 100644 --- a/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/README.md +++ b/data-api/csharp-ws/CoinAPI.WebSocket.Stats.Console/README.md @@ -62,15 +62,44 @@ dotnet run -- [options] - `--apikey `: Your CoinAPI API key. Optional if specified in `appsettings.json`. - `--type `: The type of message to send. Default is "hello". - `--supress_hb `: Whether to suppress heartbeat messages. Default is false. +- `--latency_type `: Type of measured latency, valid types are: + - `nc` client UTC to CoinApi time, + - `ne` client UTC to exchange time + - `ce` CoinApi time to exchange time. + + Default value is `ce`. ### Example ```bash dotnet run -- --endpoint_name emea --subscribe_data_type quote --symbol COINBASE_SPOT_BTC_USD$ ``` - +which is equivalent to: +```bash +dotnet run -- --endpoint_name emea --subscribe_data_type quote --symbol COINBASE_SPOT_BTC_USD$ --supress_hb false --latency_type ce +``` This command subscribes to quote data for the BTC_USD spot symbol in Coinbase exchange from the EMEA endpoint. +### Output +```terminal +[10:32:35 DBG] Hosting starting +[10:32:35 DBG] Hosting started +[10:32:35 INF] Time: 03/27/2024 09:32:35 +[10:32:35 INF] Subscribed to: subscribe_data_type = quote, symbol = COINBASE_SPOT_BTC_USD$, supress_hb = False, latency_type = ce +[10:32:35 INF] Endpoint ws://api-emea.coinapi.net, 0 iterations, 0 messages received, 0 bytes received, Error count 0 +[10:32:36 INF] Messages: 138 | Recv bytes: 34351 | CPU: wait: 97.58% | parse: 2.32% | process: 0.10% | Latency min: 51.9639 ms | max: 249.1233ms +[10:32:37 INF] Messages: 109 | Recv bytes: 27166 | CPU: wait: 99.66% | parse: 0.33% | process: 0.01% | Latency min: 51.9898 ms | max: 70.521 ms +[10:32:38 INF] Messages: 94 | Recv bytes: 23411 | CPU: wait: 99.78% | parse: 0.21% | process: 0.01% | Latency min: 51.8882 ms | max: 85.2687 ms +[10:32:39 INF] Messages: 236 | Recv bytes: 58615 | CPU: wait: 99.66% | parse: 0.32% | process: 0.02% | Latency min: 51.8318 ms | max: 170.4874ms +[10:32:40 INF] Messages: 89 | Recv bytes: 22200 | CPU: wait: 99.81% | parse: 0.18% | process: 0.01% | Latency min: 51.8809 ms | max: 61.0727 ms +[10:32:41 INF] Messages: 24 | Recv bytes: 5900 | CPU: wait: 99.94% | parse: 0.06% | process: 0.00% | Latency min: 52.0308 ms | max: 58.7746 ms +[10:32:42 INF] Messages: 136 | Recv bytes: 33908 | CPU: wait: 99.72% | parse: 0.26% | process: 0.01% | Latency min: 51.8673 ms | max: 88.1614 ms +[10:32:43 INF] Messages: 241 | Recv bytes: 60031 | CPU: wait: 99.61% | parse: 0.38% | process: 0.02% | Latency min: 51.8677 ms | max: 57.4617 ms +[10:32:44 INF] Messages: 176 | Recv bytes: 43977 | CPU: wait: 99.66% | parse: 0.32% | process: 0.02% | Latency min: 51.6744 ms | max: 64.6544 ms +[10:32:45 INF] Messages: 292 | Recv bytes: 72844 | CPU: wait: 99.54% | parse: 0.43% | process: 0.03% | Latency min: 51.9092 ms | max: 60.2158 ms +[10:32:45 INF] Endpoint ws://api-emea.coinapi.net, 10 iterations, 1555 messages received, 387420 bytes received, Error count 0 +[10:32:46 INF] Messages: 116 | Recv bytes: 28854 | CPU: wait: 99.77% | parse: 0.22% | process: 0.01% | Latency min: 51.786 +``` ## Logging The application logs detailed information to the console, including subscribed data types, message counts, CPU usage, and latencies.