From 9deb8e74f43b93dfe665f2e1caa1bec617a70f85 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Thu, 20 Jul 2023 20:28:53 +0800 Subject: [PATCH 01/12] feat: add `logjson` support --- Consul/Agent.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index eb0b78df7..12349195e 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -751,14 +751,26 @@ public string NodeName /// Providing a CancellationToken can be used to close the connection and stop the /// log stream, otherwise the log stream will time out based on the HTTP Client's timeout value. /// - public async Task Monitor(LogLevel level = default(LogLevel), CancellationToken ct = default(CancellationToken)) + public async Task Monitor(LogLevel level = default, bool logJSON = false, CancellationToken ct = default) { var req = _client.Get("/v1/agent/monitor"); req.Params["loglevel"] = level.ToString().ToLowerInvariant(); + + if (logJSON) + { + req.Params["logjson"] = "true"; + } + var res = await req.ExecuteStreaming(ct).ConfigureAwait(false); return new LogStream(res.Response); } + // MonitorJSON is like Monitor except it returns logs in JSON format. + public async Task MonitorJSON(LogLevel level = default, CancellationToken ct = default) + { + return await Monitor(level, true, ct).ConfigureAwait(false); + } + /// /// Log streamer /// From c1029ef0adc79d345b291ba70bb1ab737bc24f29 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 21 Jul 2023 21:21:25 +0800 Subject: [PATCH 02/12] chore: apply lint suggestions --- Consul/Agent.cs | 71 ++++++++++++----------------- Consul/Interfaces/IAgentEndpoint.cs | 50 ++++++++++---------- 2 files changed, 55 insertions(+), 66 deletions(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index 12349195e..d0a52b4f7 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited @@ -45,10 +45,7 @@ public class TTLStatus : IEquatable public static TTLStatus Critical { get; } = new TTLStatus() { Status = "critical", LegacyStatus = "fail" }; [Obsolete("Use TTLStatus.Critical instead. This status will be an error in 0.7.0+", true)] - public static TTLStatus Fail - { - get { return Critical; } - } + public static TTLStatus Fail => Critical; public bool Equals(TTLStatus other) { @@ -443,7 +440,7 @@ internal Agent(ConsulClient c) /// Self is used to query the agent we are speaking to for information about itself /// /// A somewhat dynamic object representing the various data elements in Self - public Task>>> Self(CancellationToken ct = default(CancellationToken)) + public Task>>> Self(CancellationToken ct = default) { return _client.Get>>("/v1/agent/self").Execute(ct); } @@ -452,18 +449,12 @@ internal Agent(ConsulClient c) /// NodeName is used to get the node name of the agent /// [Obsolete("This property will be removed in a future version. Replace uses of it with a call to 'await GetNodeName()'")] - public string NodeName - { - get - { - return GetNodeName().ConfigureAwait(false).GetAwaiter().GetResult(); - } - } + public string NodeName => GetNodeName().ConfigureAwait(false).GetAwaiter().GetResult(); /// /// GetNodeName is used to get the node name of the agent. The value is cached per instance of ConsulClient after the first use. /// - public async Task GetNodeName(CancellationToken ct = default(CancellationToken)) + public async Task GetNodeName(CancellationToken ct = default) { if (_nodeName == null) { @@ -483,7 +474,7 @@ public string NodeName /// Checks returns the locally registered checks /// /// A map of the registered check names and check data - public Task>> Checks(CancellationToken ct = default(CancellationToken)) + public Task>> Checks(CancellationToken ct = default) { return Checks(null, ct); } @@ -493,7 +484,7 @@ public string NodeName /// /// Specifies the expression used to filter the queries results prior to returning the data /// A map of the registered check names and check data - public Task>> Checks(Filter filter, CancellationToken ct = default(CancellationToken)) + public Task>> Checks(Filter filter, CancellationToken ct = default) { return _client.Get>("/v1/agent/checks", filter: filter).Execute(ct); } @@ -502,7 +493,7 @@ public string NodeName /// Services returns the locally registered services /// /// A map of the registered services and service data - public async Task>> Services(CancellationToken ct = default(CancellationToken)) + public async Task>> Services(CancellationToken ct = default) { return await Services(null, ct).ConfigureAwait(false); } @@ -512,7 +503,7 @@ public string NodeName /// /// Specifies the expression used to filter the queries results prior to returning the data /// A map of the registered services and service data - public async Task>> Services(Filter filter, CancellationToken ct = default(CancellationToken)) + public async Task>> Services(Filter filter, CancellationToken ct = default) { return await _client.Get>("/v1/agent/services", null, filter).Execute(ct).ConfigureAwait(false); } @@ -521,7 +512,7 @@ public string NodeName /// Members returns the known gossip members. The WAN flag can be used to query a server for WAN members. /// /// An array of gossip peers - public Task> Members(bool wan, CancellationToken ct = default(CancellationToken)) + public Task> Members(bool wan, CancellationToken ct = default) { var req = _client.Get("/v1/agent/members"); if (wan) @@ -536,7 +527,7 @@ public string NodeName /// /// A service registration object /// An empty write result - public Task ServiceRegister(AgentServiceRegistration service, CancellationToken ct = default(CancellationToken)) + public Task ServiceRegister(AgentServiceRegistration service, CancellationToken ct = default) { return ServiceRegister(service, replaceExistingChecks: false, ct); } @@ -547,7 +538,7 @@ public string NodeName /// A service registration object /// Missing health checks from the request will be deleted from the agent. /// An empty write result - public Task ServiceRegister(AgentServiceRegistration service, bool replaceExistingChecks, CancellationToken ct = default(CancellationToken)) + public Task ServiceRegister(AgentServiceRegistration service, bool replaceExistingChecks, CancellationToken ct = default) { var req = _client.Put("/v1/agent/service/register", service, null); if (replaceExistingChecks) @@ -562,7 +553,7 @@ public string NodeName /// /// The service ID /// An empty write result - public Task ServiceDeregister(string serviceID, CancellationToken ct = default(CancellationToken)) + public Task ServiceDeregister(string serviceID, CancellationToken ct = default) { return _client.PutNothing(string.Format("/v1/agent/service/deregister/{0}", serviceID)).Execute(ct); } @@ -572,7 +563,7 @@ public string NodeName /// /// The check ID /// An optional, arbitrary string to write to the check status - public Task PassTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)) + public Task PassTTL(string checkID, string note, CancellationToken ct = default) { return LegacyUpdateTTL(checkID, note, TTLStatus.Pass, ct); } @@ -582,7 +573,7 @@ public string NodeName /// /// The check ID /// An optional, arbitrary string to write to the check status - public Task WarnTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)) + public Task WarnTTL(string checkID, string note, CancellationToken ct = default) { return LegacyUpdateTTL(checkID, note, TTLStatus.Warn, ct); } @@ -592,7 +583,7 @@ public string NodeName /// /// The check ID /// An optional, arbitrary string to write to the check status - public Task FailTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)) + public Task FailTTL(string checkID, string note, CancellationToken ct = default) { return LegacyUpdateTTL(checkID, note, TTLStatus.Critical, ct); } @@ -604,7 +595,7 @@ public string NodeName /// An optional, arbitrary string to write to the check status /// The state to set the check to /// An empty write result - public Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default(CancellationToken)) + public Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default) { var u = new CheckUpdate { @@ -621,7 +612,7 @@ public string NodeName /// An optional, arbitrary string to note on the check status /// The state to set the check to /// An empty write result - private Task LegacyUpdateTTL(string checkID, string note, TTLStatus status, CancellationToken ct = default(CancellationToken)) + private Task LegacyUpdateTTL(string checkID, string note, TTLStatus status, CancellationToken ct = default) { var request = _client.PutNothing(string.Format("/v1/agent/check/{0}/{1}", status.LegacyStatus, checkID)); if (!string.IsNullOrEmpty(note)) @@ -636,7 +627,7 @@ public string NodeName /// /// A check registration object /// An empty write result - public Task CheckRegister(AgentCheckRegistration check, CancellationToken ct = default(CancellationToken)) + public Task CheckRegister(AgentCheckRegistration check, CancellationToken ct = default) { return _client.Put("/v1/agent/check/register", check, null).Execute(ct); } @@ -646,7 +637,7 @@ public string NodeName /// /// The check ID to deregister /// An empty write result - public Task CheckDeregister(string checkID, CancellationToken ct = default(CancellationToken)) + public Task CheckDeregister(string checkID, CancellationToken ct = default) { return _client.PutNothing(string.Format("/v1/agent/check/deregister/{0}", checkID)).Execute(ct); } @@ -657,7 +648,7 @@ public string NodeName /// The address to join to /// Join the WAN pool /// An empty write result - public Task Join(string addr, bool wan, CancellationToken ct = default(CancellationToken)) + public Task Join(string addr, bool wan, CancellationToken ct = default) { var req = _client.PutNothing(string.Format("/v1/agent/join/{0}", addr)); if (wan) @@ -672,7 +663,7 @@ public string NodeName /// /// The node name to remove /// An empty write result - public Task ForceLeave(string node, CancellationToken ct = default(CancellationToken)) + public Task ForceLeave(string node, CancellationToken ct = default) { return _client.PutNothing(string.Format("/v1/agent/force-leave/{0}", node)).Execute(ct); } @@ -682,7 +673,7 @@ public string NodeName /// Leave is used to have the agent gracefully leave the cluster and shutdown /// /// An empty write result - public Task Leave(string node, CancellationToken ct = default(CancellationToken)) + public Task Leave(string node, CancellationToken ct = default) { return _client.PutNothing("/v1/agent/leave").Execute(ct); } @@ -691,7 +682,7 @@ public string NodeName /// Reload triggers a configuration reload for the agent we are connected to. /// /// An empty write result - public Task Reload(string node, CancellationToken ct = default(CancellationToken)) + public Task Reload(string node, CancellationToken ct = default) { return _client.PutNothing("/v1/agent/reload").Execute(ct); } @@ -702,7 +693,7 @@ public string NodeName /// The service ID /// An optional reason /// An empty write result - public Task EnableServiceMaintenance(string serviceID, string reason, CancellationToken ct = default(CancellationToken)) + public Task EnableServiceMaintenance(string serviceID, string reason, CancellationToken ct = default) { var req = _client.PutNothing(string.Format("/v1/agent/service/maintenance/{0}", serviceID)); req.Params["enable"] = "true"; @@ -715,7 +706,7 @@ public string NodeName /// /// The service ID /// An empty write result - public Task DisableServiceMaintenance(string serviceID, CancellationToken ct = default(CancellationToken)) + public Task DisableServiceMaintenance(string serviceID, CancellationToken ct = default) { var req = _client.PutNothing(string.Format("/v1/agent/service/maintenance/{0}", serviceID)); req.Params["enable"] = "false"; @@ -727,7 +718,7 @@ public string NodeName /// /// An optional reason /// An empty write result - public Task EnableNodeMaintenance(string reason, CancellationToken ct = default(CancellationToken)) + public Task EnableNodeMaintenance(string reason, CancellationToken ct = default) { var req = _client.PutNothing("/v1/agent/maintenance"); req.Params["enable"] = "true"; @@ -739,7 +730,7 @@ public string NodeName /// DisableNodeMaintenance toggles node maintenance mode off for the agent we are connected to /// /// An empty write result - public Task DisableNodeMaintenance(CancellationToken ct = default(CancellationToken)) + public Task DisableNodeMaintenance(CancellationToken ct = default) { var req = _client.PutNothing("/v1/agent/maintenance"); req.Params["enable"] = "false"; @@ -788,6 +779,7 @@ public void Dispose() { _streamreader.Dispose(); _stream.Dispose(); + GC.SuppressFinalize(this); } public IEnumerator> GetEnumerator() @@ -813,9 +805,6 @@ public partial class ConsulClient : IConsulClient /// /// Agent returns a handle to the agent endpoints /// - public IAgentEndpoint Agent - { - get { return _agent.Value; } - } + public IAgentEndpoint Agent => _agent.Value; } } diff --git a/Consul/Interfaces/IAgentEndpoint.cs b/Consul/Interfaces/IAgentEndpoint.cs index 1012d6ddc..c1a855514 100644 --- a/Consul/Interfaces/IAgentEndpoint.cs +++ b/Consul/Interfaces/IAgentEndpoint.cs @@ -30,32 +30,32 @@ namespace Consul /// public interface IAgentEndpoint { - Task CheckDeregister(string checkID, CancellationToken ct = default(CancellationToken)); - Task CheckRegister(AgentCheckRegistration check, CancellationToken ct = default(CancellationToken)); - Task>> Checks(CancellationToken ct = default(CancellationToken)); - Task>> Checks(Filter filter, CancellationToken ct = default(CancellationToken)); - Task DisableNodeMaintenance(CancellationToken ct = default(CancellationToken)); - Task DisableServiceMaintenance(string serviceID, CancellationToken ct = default(CancellationToken)); - Task EnableNodeMaintenance(string reason, CancellationToken ct = default(CancellationToken)); - Task EnableServiceMaintenance(string serviceID, string reason, CancellationToken ct = default(CancellationToken)); - Task FailTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)); - Task ForceLeave(string node, CancellationToken ct = default(CancellationToken)); - Task Join(string addr, bool wan, CancellationToken ct = default(CancellationToken)); - Task> Members(bool wan, CancellationToken ct = default(CancellationToken)); + Task CheckDeregister(string checkID, CancellationToken ct = default); + Task CheckRegister(AgentCheckRegistration check, CancellationToken ct = default); + Task>> Checks(CancellationToken ct = default); + Task>> Checks(Filter filter, CancellationToken ct = default); + Task DisableNodeMaintenance(CancellationToken ct = default); + Task DisableServiceMaintenance(string serviceID, CancellationToken ct = default); + Task EnableNodeMaintenance(string reason, CancellationToken ct = default); + Task EnableServiceMaintenance(string serviceID, string reason, CancellationToken ct = default); + Task FailTTL(string checkID, string note, CancellationToken ct = default); + Task ForceLeave(string node, CancellationToken ct = default); + Task Join(string addr, bool wan, CancellationToken ct = default); + Task> Members(bool wan, CancellationToken ct = default); [Obsolete("This property will be removed in a future release. Replace uses of it with a call to GetNodeName()")] string NodeName { get; } - Task GetNodeName(CancellationToken ct = default(CancellationToken)); - Task PassTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)); - Task>>> Self(CancellationToken ct = default(CancellationToken)); - Task ServiceDeregister(string serviceID, CancellationToken ct = default(CancellationToken)); - Task ServiceRegister(AgentServiceRegistration service, CancellationToken ct = default(CancellationToken)); - Task ServiceRegister(AgentServiceRegistration service, bool replaceExistingChecks, CancellationToken ct = default(CancellationToken)); - Task>> Services(CancellationToken ct = default(CancellationToken)); - Task>> Services(Filter filter, CancellationToken ct = default(CancellationToken)); - Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default(CancellationToken)); - Task WarnTTL(string checkID, string note, CancellationToken ct = default(CancellationToken)); - Task Monitor(LogLevel level = default(LogLevel), CancellationToken ct = default(CancellationToken)); - Task Leave(string node, CancellationToken ct = default(CancellationToken)); - Task Reload(string node, CancellationToken ct = default(CancellationToken)); + Task GetNodeName(CancellationToken ct = default); + Task PassTTL(string checkID, string note, CancellationToken ct = default); + Task>>> Self(CancellationToken ct = default); + Task ServiceDeregister(string serviceID, CancellationToken ct = default); + Task ServiceRegister(AgentServiceRegistration service, CancellationToken ct = default); + Task ServiceRegister(AgentServiceRegistration service, bool replaceExistingChecks, CancellationToken ct = default); + Task>> Services(CancellationToken ct = default); + Task>> Services(Filter filter, CancellationToken ct = default); + Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default); + Task WarnTTL(string checkID, string note, CancellationToken ct = default); + Task Monitor(LogLevel level = default, CancellationToken ct = default); + Task Leave(string node, CancellationToken ct = default); + Task Reload(string node, CancellationToken ct = default); } } From 500e3c28d1daf5b311d303be03bed62aba9f75e6 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 21 Jul 2023 21:34:21 +0800 Subject: [PATCH 03/12] fix: update interface with support for `logjson` --- Consul/Interfaces/IAgentEndpoint.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Consul/Interfaces/IAgentEndpoint.cs b/Consul/Interfaces/IAgentEndpoint.cs index c1a855514..70ab93311 100644 --- a/Consul/Interfaces/IAgentEndpoint.cs +++ b/Consul/Interfaces/IAgentEndpoint.cs @@ -54,7 +54,9 @@ public interface IAgentEndpoint Task>> Services(Filter filter, CancellationToken ct = default); Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default); Task WarnTTL(string checkID, string note, CancellationToken ct = default); - Task Monitor(LogLevel level = default, CancellationToken ct = default); + Task Monitor(LogLevel level = default, bool logJSON = false, CancellationToken ct = default); + Task MonitorJSON(LogLevel level = default, CancellationToken ct = default); + Task Leave(string node, CancellationToken ct = default); Task Reload(string node, CancellationToken ct = default); } From 89804ace6b5330d986bdbe9e23c32d7c8c28e2ab Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Wed, 26 Jul 2023 21:44:20 +0800 Subject: [PATCH 04/12] refactor(Monitor): maintain backwards compatibility --- Consul/Agent.cs | 18 ++++++++++-------- Consul/Interfaces/IAgentEndpoint.cs | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index d0a52b4f7..bdad2dd62 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -742,24 +742,26 @@ public Task DisableNodeMaintenance(CancellationToken ct = default) /// Providing a CancellationToken can be used to close the connection and stop the /// log stream, otherwise the log stream will time out based on the HTTP Client's timeout value. /// - public async Task Monitor(LogLevel level = default, bool logJSON = false, CancellationToken ct = default) + public async Task Monitor(LogLevel level = default, CancellationToken ct = default) { var req = _client.Get("/v1/agent/monitor"); req.Params["loglevel"] = level.ToString().ToLowerInvariant(); - if (logJSON) - { - req.Params["logjson"] = "true"; - } - var res = await req.ExecuteStreaming(ct).ConfigureAwait(false); return new LogStream(res.Response); } - // MonitorJSON is like Monitor except it returns logs in JSON format. + /// + /// MonitorJSON is like Monitor except it returns logs in JSON format. + /// public async Task MonitorJSON(LogLevel level = default, CancellationToken ct = default) { - return await Monitor(level, true, ct).ConfigureAwait(false); + var req = _client.Get("/v1/agent/monitor"); + req.Params["loglevel"] = level.ToString().ToLowerInvariant(); + req.Params["logjson"] = "true"; + + var res = await req.ExecuteStreaming(ct).ConfigureAwait(false); + return new LogStream(res.Response); } /// diff --git a/Consul/Interfaces/IAgentEndpoint.cs b/Consul/Interfaces/IAgentEndpoint.cs index 70ab93311..395743ad1 100644 --- a/Consul/Interfaces/IAgentEndpoint.cs +++ b/Consul/Interfaces/IAgentEndpoint.cs @@ -54,7 +54,7 @@ public interface IAgentEndpoint Task>> Services(Filter filter, CancellationToken ct = default); Task UpdateTTL(string checkID, string output, TTLStatus status, CancellationToken ct = default); Task WarnTTL(string checkID, string note, CancellationToken ct = default); - Task Monitor(LogLevel level = default, bool logJSON = false, CancellationToken ct = default); + Task Monitor(LogLevel level = default, CancellationToken ct = default); Task MonitorJSON(LogLevel level = default, CancellationToken ct = default); Task Leave(string node, CancellationToken ct = default); From 23bb3e2b68fcf1dc32af4f40f194f164582507ac Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 28 Jul 2023 17:24:32 +0800 Subject: [PATCH 05/12] feat: add test to validate JSON logs --- Consul.Test/AgentTest.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Consul.Test/AgentTest.cs b/Consul.Test/AgentTest.cs index 6f561c40d..5a6c61f49 100644 --- a/Consul.Test/AgentTest.cs +++ b/Consul.Test/AgentTest.cs @@ -515,6 +515,33 @@ public async Task Agent_Monitor() } } + [Fact] + public async Task Agent_MonitorJSON() + { + using (var logs = await _client.Agent.MonitorJSON(LogLevel.Trace)) + { + var counter = 0; + var logsTask = Task.Run(async () => + { + foreach (var line in logs) + { + // Make a request each time so we get more logs + await _client.Agent.Self(); + Assert.StartsWith("{", await line); + Assert.EndsWith("}", await line); + + counter++; + if (counter > 5) + { + break; + } + } + }); + + await TimeoutUtils.WithTimeout(logsTask); + } + } + [Fact] public async Task Agent_FilterServices() { From 76c5aa4aaa27ae8d2d7d8d0b2c5687e53d8bd1e5 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 28 Jul 2023 18:26:07 +0800 Subject: [PATCH 06/12] refactor: use `System.Text.Json` to test valid JSON --- Consul.Test/AgentTest.cs | 4 ++-- Consul.Test/Consul.Test.csproj | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Consul.Test/AgentTest.cs b/Consul.Test/AgentTest.cs index 0399ea980..e4076786e 100644 --- a/Consul.Test/AgentTest.cs +++ b/Consul.Test/AgentTest.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using Consul.Filtering; using Xunit; @@ -551,8 +552,7 @@ public async Task Agent_MonitorJSON() { // Make a request each time so we get more logs await _client.Agent.Self(); - Assert.StartsWith("{", await line); - Assert.EndsWith("}", await line); + Assert.NotNull(JsonSerializer.Deserialize(await line)); counter++; if (counter > 5) diff --git a/Consul.Test/Consul.Test.csproj b/Consul.Test/Consul.Test.csproj index 3fc9e843c..1e0af803d 100644 --- a/Consul.Test/Consul.Test.csproj +++ b/Consul.Test/Consul.Test.csproj @@ -3,7 +3,7 @@ net461;net5.0;net6.0;net7.0 false - true + true @@ -13,6 +13,7 @@ + From 97dfdfd394b42e252262cd0bf090c063de17ecea Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 28 Jul 2023 19:32:31 +0800 Subject: [PATCH 07/12] fix: skip test if agent version is below v1.7 --- Consul.Test/AgentTest.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Consul.Test/AgentTest.cs b/Consul.Test/AgentTest.cs index e4076786e..6efb145a1 100644 --- a/Consul.Test/AgentTest.cs +++ b/Consul.Test/AgentTest.cs @@ -23,8 +23,8 @@ using System.Text.Json; using System.Threading.Tasks; using Consul.Filtering; +using NuGet.Versioning; using Xunit; -using Xunit.Abstractions; namespace Consul.Test { @@ -540,9 +540,12 @@ public async Task Agent_Monitor() } } - [Fact] + [SkippableFact] public async Task Agent_MonitorJSON() { + var cutOffVersion = SemanticVersion.Parse("1.7.0"); + Skip.If(AgentVersion < cutOffVersion, $"Current version is {AgentVersion}, but `logjson` is only supported from Consul {cutOffVersion}"); + using (var logs = await _client.Agent.MonitorJSON(LogLevel.Trace)) { var counter = 0; From f9c13b1ca2aeabfd0db5fd5247371a3c541ee4d3 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Fri, 28 Jul 2023 19:37:48 +0800 Subject: [PATCH 08/12] chore: fix formatting --- Consul/Agent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index bdad2dd62..3ebf1125d 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited From 3f01b52d5f03669db18e8b957b06f374cde22e98 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Mon, 31 Jul 2023 16:42:09 +0800 Subject: [PATCH 09/12] refactor: use basic dispose pattern for unsealed class --- Consul/Agent.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index 3ebf1125d..3f7fc998d 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited @@ -778,10 +778,15 @@ internal LogStream(Stream s) } public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public virtual void Dispose(bool disposing) { _streamreader.Dispose(); _stream.Dispose(); - GC.SuppressFinalize(this); } public IEnumerator> GetEnumerator() From 9b1638999491050eb846bdba09201fa3754e298c Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Mon, 31 Jul 2023 18:01:29 +0800 Subject: [PATCH 10/12] chore: fix file encoding --- Consul/Agent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index 3f7fc998d..419306f8b 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited From bec8d3de5ca5b17c66c10d14f2708676dfcc382a Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Mon, 31 Jul 2023 21:36:04 +0800 Subject: [PATCH 11/12] fix: add if guard to `Dispose` --- Consul/Agent.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index 419306f8b..85a650bbe 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited @@ -785,6 +785,7 @@ public void Dispose() public virtual void Dispose(bool disposing) { + if (!disposing) return; _streamreader.Dispose(); _stream.Dispose(); } From 7e59bb7da9be9376e756c0dbaad34bd8e9a78f17 Mon Sep 17 00:00:00 2001 From: winstxnhdw Date: Wed, 2 Aug 2023 15:10:14 +0800 Subject: [PATCH 12/12] chore: fix encoding --- Consul/Agent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Consul/Agent.cs b/Consul/Agent.cs index 85a650bbe..e87c24971 100644 --- a/Consul/Agent.cs +++ b/Consul/Agent.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright 2015 PlayFab Inc. // Copyright 2020 G-Research Limited