From c356e92f060810e72031f164203b557b8bcb1f4e Mon Sep 17 00:00:00 2001 From: Morgan Leroi Date: Tue, 30 Jan 2024 12:31:12 +0100 Subject: [PATCH 1/3] add logs --- .../algoliasearch/Clients/AlgoliaConfig.cs | 2 +- .../Http/AlgoliaHttpRequester.cs | 51 ++++++++------ .../algoliasearch/Http/ClientUtils.cs | 4 -- .../algoliasearch/Http/EchoHttpRequester.cs | 4 +- .../Serializer/DefaultSerializer.cs | 16 +++-- .../algoliasearch/Serializer/ISerializer.cs | 8 +-- .../algoliasearch/Transport/HttpTransport.cs | 67 ++++++++++++++++--- .../csharp/Playground/Playgrounds/Search.cs | 35 +++++++--- templates/csharp/Configuration.mustache | 2 + templates/csharp/api.mustache | 23 +++++-- templates/csharp/netcore_project.mustache | 21 +----- tests/output/csharp/src/HelpersTests.cs | 1 + tests/output/csharp/src/RetryStrategyTests.cs | 2 + 13 files changed, 157 insertions(+), 79 deletions(-) diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs b/clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs index b6650641e6..254d923063 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using Algolia.Search.Http; -using Algolia.Search.Models; using Algolia.Search.Models.Common; using Algolia.Search.Serializer; using Algolia.Search.Transport; using Algolia.Search.Utils; +using Microsoft.Extensions.Logging; namespace Algolia.Search.Clients { diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs b/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs index 14d4d22beb..3e5fe601e2 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Algolia.Search.Http { @@ -17,10 +18,17 @@ internal class AlgoliaHttpRequester : IHttpRequester /// https://docs.microsoft.com/en-gb/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client /// private readonly HttpClient _httpClient = new( - new TimeoutHandler - { - InnerHandler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip } - }); + new TimeoutHandler + { + InnerHandler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip } + }); + + private readonly ILogger _logger; + + public AlgoliaHttpRequester(ILoggerFactory loggerFactory) + { + _logger = loggerFactory.CreateLogger(); + } /// /// Don't use it directly @@ -31,8 +39,8 @@ internal class AlgoliaHttpRequester : IHttpRequester /// Connect timeout /// Optional cancellation token /// - public async Task SendRequestAsync(Request request, TimeSpan requestTimeout, TimeSpan connectTimeout, - CancellationToken ct = default) + public async Task SendRequestAsync(Request request, TimeSpan requestTimeout, + TimeSpan connectTimeout, CancellationToken ct = default) { if (request.Method == null) { @@ -63,14 +71,13 @@ public async Task SendRequestAsync(Request request, TimeSpa try { using (httpRequestMessage) - using (HttpResponseMessage response = - await _httpClient.SendAsync(httpRequestMessage, ct).ConfigureAwait(false)) + using (var response = await _httpClient.SendAsync(httpRequestMessage, ct).ConfigureAwait(false)) { using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { if (response.IsSuccessStatusCode) { - MemoryStream outputStream = new MemoryStream(); + var outputStream = new MemoryStream(); await stream.CopyToAsync(outputStream).ConfigureAwait(false); outputStream.Seek(0, SeekOrigin.Begin); @@ -89,29 +96,35 @@ await _httpClient.SendAsync(httpRequestMessage, ct).ConfigureAwait(false)) } } } - catch (TimeoutException e) + catch (TimeoutException ex) { - return new AlgoliaHttpResponse { IsTimedOut = true, Error = e.ToString() }; + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug(ex, "Timeout while sending request"); + } + + return new AlgoliaHttpResponse { IsTimedOut = true, Error = ex.ToString() }; } - catch (HttpRequestException e) + catch (HttpRequestException ex) { // HttpRequestException is thrown when an underlying issue happened such as // network connectivity, DNS failure, server certificate validation. - return new AlgoliaHttpResponse { IsNetworkError = true, Error = e.Message }; + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug(ex, "Error while sending request"); + } + + return new AlgoliaHttpResponse { IsNetworkError = true, Error = ex.Message }; } } private async Task StreamToStringAsync(Stream stream) { - string content; - if (stream == null) return null; - using (var sr = new StreamReader(stream)) - { - content = await sr.ReadToEndAsync().ConfigureAwait(false); - } + using var sr = new StreamReader(stream); + var content = await sr.ReadToEndAsync().ConfigureAwait(false); return content; } diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Http/ClientUtils.cs b/clients/algoliasearch-client-csharp/algoliasearch/Http/ClientUtils.cs index e8aaf32327..095461538e 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Http/ClientUtils.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Http/ClientUtils.cs @@ -1,7 +1,3 @@ -// -// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT. -// - using System; using System.Collections; using System.Collections.Generic; diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Http/EchoHttpRequester.cs b/clients/algoliasearch-client-csharp/algoliasearch/Http/EchoHttpRequester.cs index 4b13418841..f64ef760af 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Http/EchoHttpRequester.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Http/EchoHttpRequester.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using System.Web; +using Microsoft.Extensions.Logging; namespace Algolia.Search.Http { @@ -44,8 +45,7 @@ private static Dictionary SplitQuery(string query) /// /// public Task SendRequestAsync(Request request, TimeSpan requestTimeout, - TimeSpan connectTimeout, - CancellationToken ct = default) + TimeSpan connectTimeout, CancellationToken ct = default) { string body = null; if (!_bodyAsStream && request.Body != null) diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Serializer/DefaultSerializer.cs b/clients/algoliasearch-client-csharp/algoliasearch/Serializer/DefaultSerializer.cs index a62994e7fc..3fd471a107 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Serializer/DefaultSerializer.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Serializer/DefaultSerializer.cs @@ -4,17 +4,20 @@ using System.Threading.Tasks; using Algolia.Search.Exceptions; using Algolia.Search.Models.Common; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace Algolia.Search.Serializer; -internal class DefaultJsonSerializer +internal class DefaultJsonSerializer : ISerializer { private readonly JsonSerializerSettings _serializerSettings; + private readonly ILogger _logger; - public DefaultJsonSerializer(JsonSerializerSettings serializerSettings) + public DefaultJsonSerializer(JsonSerializerSettings serializerSettings, ILoggerFactory logger) { _serializerSettings = serializerSettings; + _logger = logger.CreateLogger(); } /// @@ -79,9 +82,14 @@ private async Task Deserialize(Stream response, Type type) var text = await reader.ReadToEndAsync().ConfigureAwait(false); return JsonConvert.DeserializeObject(text, type, _serializerSettings); } - catch (Exception e) + catch (Exception ex) { - throw new AlgoliaException(e.Message); + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.Log(LogLevel.Debug, ex, "Error while deserializing response"); + } + + throw new AlgoliaException(ex.Message); } } } diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Serializer/ISerializer.cs b/clients/algoliasearch-client-csharp/algoliasearch/Serializer/ISerializer.cs index 40a8e89d6d..248ccbd511 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Serializer/ISerializer.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Serializer/ISerializer.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Threading.Tasks; using Algolia.Search.Models.Common; namespace Algolia.Search.Serializer @@ -12,10 +13,7 @@ internal interface ISerializer /// Converts the value of a specified type into a JSON string. /// /// The value to convert and write. - /// The Stream containing the data to read. - /// How the stream should be compressed - /// The type of the value to convert. - void Serialize(T data, Stream stream, CompressionType compressionType); + string Serialize(object data); /// /// Parses the stream into an instance of a specified type. @@ -23,6 +21,6 @@ internal interface ISerializer /// The Stream containing the data to read. /// The type of the value to convert. /// - T Deserialize(Stream stream); + Task Deserialize(Stream stream); } } diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Transport/HttpTransport.cs b/clients/algoliasearch-client-csharp/algoliasearch/Transport/HttpTransport.cs index 81c24b8ac7..106c793e5b 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Transport/HttpTransport.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Transport/HttpTransport.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Text; @@ -10,9 +9,9 @@ using Algolia.Search.Clients; using Algolia.Search.Exceptions; using Algolia.Search.Http; -using Algolia.Search.Models.Common; using Algolia.Search.Serializer; using Algolia.Search.Utils; +using Microsoft.Extensions.Logging; namespace Algolia.Search.Transport; @@ -23,10 +22,11 @@ namespace Algolia.Search.Transport; internal class HttpTransport { private readonly IHttpRequester _httpClient; - private readonly DefaultJsonSerializer _serializer = new(JsonConfig.AlgoliaJsonSerializerSettings); + private readonly ISerializer _serializer; private readonly RetryStrategy _retryStrategy; private readonly AlgoliaConfig _algoliaConfig; private string _errorMessage; + private readonly ILogger _logger; private class VoidResult { @@ -37,11 +37,14 @@ private class VoidResult /// /// Algolia Config /// An implementation of http requester - public HttpTransport(AlgoliaConfig config, IHttpRequester httpClient) + /// Logger factory + public HttpTransport(AlgoliaConfig config, IHttpRequester httpClient, ILoggerFactory loggerFactory) { _algoliaConfig = config ?? throw new ArgumentNullException(nameof(config)); _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); _retryStrategy = new RetryStrategy(config); + _serializer = new DefaultJsonSerializer(JsonConfig.AlgoliaJsonSerializerSettings, loggerFactory); + _logger = loggerFactory.CreateLogger(); } /// @@ -112,7 +115,7 @@ private async Task ExecuteRequestAsync(HttpMethod metho foreach (var host in _retryStrategy.GetTryableHost(callType)) { - request.Body = CreateRequestContent(requestOptions?.Data, request.CanCompress); + request.Body = CreateRequestContent(requestOptions?.Data, request.CanCompress, _logger); request.Uri = BuildUri(host.Url, uri, requestOptions?.CustomPathParameters, requestOptions?.PathParameters, requestOptions?.QueryParameters); var requestTimeout = @@ -123,6 +126,11 @@ private async Task ExecuteRequestAsync(HttpMethod metho request.Body = new MemoryStream(Encoding.UTF8.GetBytes("{}")); } + if (_logger.IsEnabled(LogLevel.Trace)) + { + _logger.LogTrace("Sending request to {Method} {Uri}", request.Method, request.Uri); + } + var response = await _httpClient .SendRequestAsync(request, requestTimeout, _algoliaConfig.ConnectTimeout ?? Defaults.ConnectTimeout, ct) .ConfigureAwait(false); @@ -137,16 +145,51 @@ private async Task ExecuteRequestAsync(HttpMethod metho return new VoidResult() as TResult; } - return await _serializer.Deserialize(response.Body); + if (_logger.IsEnabled(LogLevel.Trace)) + { + var reader = new StreamReader(response.Body); + var json = await reader.ReadToEndAsync().ConfigureAwait(false); + _logger.LogTrace( + "Response HTTP {HttpCode}: {Json}", response.HttpStatusCode, json); + response.Body.Seek(0, SeekOrigin.Begin); + } + + var deserialized = await _serializer.Deserialize(response.Body); + + if (_logger.IsEnabled(LogLevel.Trace)) + { + _logger.LogTrace("Object created: {objectCreated}", deserialized); + } + + return deserialized; case RetryOutcomeType.Retry: + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug( + "Retrying ... Retryable error for response HTTP {HttpCode} : {Error}", response.HttpStatusCode, + response.Error); + } + continue; case RetryOutcomeType.Failure: + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug( + "Retry strategy with failure outcome. Response HTTP{HttpCode} : {Error}", response.HttpStatusCode, + response.Error); + } + throw new AlgoliaApiException(response.Error, response.HttpStatusCode); default: throw new ArgumentOutOfRangeException(); } } + if (_logger.IsEnabled(LogLevel.Debug)) + { + _logger.LogDebug("Retry strategy failed: {ErrorMessage}", _errorMessage); + } + throw new AlgoliaUnreachableHostException("RetryStrategy failed to connect to Algolia. Reason: " + _errorMessage); } @@ -155,11 +198,19 @@ private async Task ExecuteRequestAsync(HttpMethod metho /// /// Data to send /// Whether the stream should be compressed or not + /// Logger /// Type of the data to send/retrieve /// - private MemoryStream CreateRequestContent(T data, bool compress) + private MemoryStream CreateRequestContent(T data, bool compress, ILogger logger) { - return data == null ? null : Compression.CreateStream(_serializer.Serialize(data), compress); + var serializedData = _serializer.Serialize(data); + + if (_logger.IsEnabled(LogLevel.Trace)) + { + logger.LogTrace("Serialized request data: {Json}", serializedData); + } + + return data == null ? null : Compression.CreateStream(serializedData, compress); } /// diff --git a/playground/csharp/Playground/Playgrounds/Search.cs b/playground/csharp/Playground/Playgrounds/Search.cs index 068c78c3bd..190debab3f 100644 --- a/playground/csharp/Playground/Playgrounds/Search.cs +++ b/playground/csharp/Playground/Playgrounds/Search.cs @@ -5,6 +5,7 @@ using Algolia.Search.Models.Search; using Algolia.Search.Utils; using Algolia.Utils; +using Microsoft.Extensions.Logging; using Action = Algolia.Search.Models.Search.Action; namespace Algolia.Playgrounds; @@ -19,10 +20,17 @@ public static async Task Run(Configuration configuration) Console.WriteLine("Starting Search API playground"); Console.WriteLine("------------------------------------"); - var client = new SearchClient(new SearchConfig(configuration.AppId, configuration.AdminApiKey) + + var searchConfig = new SearchConfig(configuration.AppId, configuration.AdminApiKey) { Compression = CompressionType.NONE - }); + }; + + + var loggerFactory = LoggerFactory.Create(i => i.AddFilter("Algolia", LogLevel.Information) + .AddConsole()); + + var client = new SearchClient(searchConfig, loggerFactory); var metisClient = new SearchClient(new SearchConfig(configuration.MetisAppId, configuration.MetisApiKey) { @@ -93,7 +101,8 @@ await PlaygroundHelper.Start( }; var getObjResults = await client.GetObjectsAsync(new GetObjectsParams(getObjRequests)); - getObjResults.Results.ForEach(t => Console.WriteLine($" - Record ObjectID: {t.ObjectID} - Property `otherValue`: {t.otherValue}")); + getObjResults.Results.ForEach(t => + Console.WriteLine($" - Record ObjectID: {t.ObjectID} - Property `otherValue`: {t.otherValue}")); // Search single index Console.WriteLine("--- Search single index `SearchSingleIndexAsync` ---"); @@ -117,7 +126,8 @@ await PlaygroundHelper.Start( } else if (result.IsSearchForFacetValuesResponse()) { - Console.WriteLine("Record with Facet. Facet value = " + result.AsSearchForFacetValuesResponse().FacetHits.First().Value); + Console.WriteLine("Record with Facet. Facet value = " + + result.AsSearchForFacetValuesResponse().FacetHits.First().Value); } else { @@ -130,7 +140,8 @@ await PlaygroundHelper.Start( var tMetis = await metisClient.SearchSingleIndexAsync("008_jobs_v2_nosplit__contents__default"); foreach (var tMetisAdditionalProperty in tMetis.AdditionalProperties) { - Console.WriteLine($" - Additional property found {tMetisAdditionalProperty.Key} : {tMetisAdditionalProperty.Value}"); + Console.WriteLine( + $" - Additional property found {tMetisAdditionalProperty.Key} : {tMetisAdditionalProperty.Value}"); } // API Key @@ -140,7 +151,7 @@ await PlaygroundHelper.Start( Acl = new List { Acl.Browse, Acl.Search }, Description = "A test key", Indexes = new List { defaultIndex } }); - var createdApiKey = await PlaygroundHelper.Start($"Saving new API Key",async () => + var createdApiKey = await PlaygroundHelper.Start($"Saving new API Key", async () => await client.WaitForApiKeyAsync(ApiKeyOperation.Add, addApiKeyResponse.Key), "New key has been created !"); Console.WriteLine("--- Update api key `UpdateApiKeyAsync` ---"); @@ -148,12 +159,12 @@ await PlaygroundHelper.Start( modifiedApiKey.Description = "Updated description"; var updateApiKey = await client.UpdateApiKeyAsync(addApiKeyResponse.Key, modifiedApiKey); - await PlaygroundHelper.Start("Updating API Key`",async () => + await PlaygroundHelper.Start("Updating API Key`", async () => await client.WaitForApiKeyAsync(ApiKeyOperation.Update, updateApiKey.Key, modifiedApiKey), "Key updated !"); Console.WriteLine("--- Delete api key `UpdateApiKeyAsync` ---"); await client.DeleteApiKeyAsync(addApiKeyResponse.Key); - await PlaygroundHelper.Start("Deleting API Key",async () => + await PlaygroundHelper.Start("Deleting API Key", async () => await client.WaitForApiKeyAsync(ApiKeyOperation.Delete, updateApiKey.Key), "Key deleted !"); // Add Synonyms @@ -178,13 +189,14 @@ await PlaygroundHelper.Start("Deleting API Key",async () => }, }).ConfigureAwait(false); - await PlaygroundHelper.Start("Creating new Synonyms - Async TaskID: `{synonymsResponse.TaskID}`",async () => + await PlaygroundHelper.Start("Creating new Synonyms - Async TaskID: `{synonymsResponse.TaskID}`", async () => await client.WaitForTaskAsync(defaultIndex, synonymsResponse.TaskID), "New Synonyms has been created !"); // Search Synonyms Console.WriteLine("--- Search Synonyms `SearchSynonymsAsync` ---"); var searchSynonymsAsync = await client - .SearchSynonymsAsync(defaultIndex, new SearchSynonymsParams { Query = "", Type = SynonymType.Onewaysynonym, HitsPerPage = 1}) + .SearchSynonymsAsync(defaultIndex, + new SearchSynonymsParams { Query = "", Type = SynonymType.Onewaysynonym, HitsPerPage = 1 }) .ConfigureAwait(false); Console.WriteLine(searchSynonymsAsync.Hits.Count); @@ -225,7 +237,8 @@ await PlaygroundHelper.Start("Deleting API Key",async () => } }).ConfigureAwait(false); - await PlaygroundHelper.Start($"Saving new Rule - Async TaskID: `{saveRulesAsync.TaskID}`", async () => await client.WaitForTaskAsync(defaultIndex, saveRulesAsync.TaskID), "New Rule has been created !"); + await PlaygroundHelper.Start($"Saving new Rule - Async TaskID: `{saveRulesAsync.TaskID}`", + async () => await client.WaitForTaskAsync(defaultIndex, saveRulesAsync.TaskID), "New Rule has been created !"); Console.WriteLine("--- Error Handling ---"); try diff --git a/templates/csharp/Configuration.mustache b/templates/csharp/Configuration.mustache index cd79a8cf47..9d56b370b3 100644 --- a/templates/csharp/Configuration.mustache +++ b/templates/csharp/Configuration.mustache @@ -6,6 +6,8 @@ using Algolia.Search.Models; using Algolia.Search.Models.Common; using Algolia.Search.Transport; using Algolia.Search.Utils; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Algolia.Search.Clients; diff --git a/templates/csharp/api.mustache b/templates/csharp/api.mustache index 0cdafedd6f..8b3951270c 100644 --- a/templates/csharp/api.mustache +++ b/templates/csharp/api.mustache @@ -6,12 +6,12 @@ using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using Algolia.Search.Clients; -using Algolia.Search.Models; {{#hasImport}}using Algolia.Search.Models.{{apiPackageName}}; {{/hasImport}} using Algolia.Search.Transport; using Algolia.Search.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Algolia.Search.Clients; @@ -53,14 +53,16 @@ namespace Algolia.Search.Clients; {{>visibility}} partial class {{classname}} : {{interfacePrefix}}{{classname}} { private readonly HttpTransport _transport; + private readonly ILogger<{{apiPackageName}}Client> _logger; /// /// Create a new {{apiPackageName}} client for the given appID and apiKey. /// /// Your application /// Your API key + /// Logger factory {{#hasRegionalHost}}/// The targeted region{{/hasRegionalHost}} - public {{classname}}(string applicationId, string apiKey{{#hasRegionalHost}}, string region{{/hasRegionalHost}}{{#fallbackToAliasHost}} = null{{/fallbackToAliasHost}}) : this(new {{apiPackageName}}Config(applicationId, apiKey{{#hasRegionalHost}}, region{{/hasRegionalHost}}), new AlgoliaHttpRequester()) + public {{classname}}(string applicationId, string apiKey{{#hasRegionalHost}}, string region{{/hasRegionalHost}}{{#fallbackToAliasHost}} = null{{/fallbackToAliasHost}}, ILoggerFactory loggerFactory = null) : this(new {{apiPackageName}}Config(applicationId, apiKey{{#hasRegionalHost}}, region{{/hasRegionalHost}}), new AlgoliaHttpRequester(loggerFactory), loggerFactory) { } @@ -68,7 +70,8 @@ namespace Algolia.Search.Clients; /// Initialize a client with custom config /// /// Algolia configuration - public {{classname}}({{apiPackageName}}Config config) : this(config, new AlgoliaHttpRequester()) + /// Logger factory + public {{classname}}({{apiPackageName}}Config config, ILoggerFactory loggerFactory = null) : this(config, new AlgoliaHttpRequester(loggerFactory), loggerFactory) { } @@ -77,7 +80,8 @@ namespace Algolia.Search.Clients; /// /// Algolia Config /// Your Http requester implementation of - public {{classname}}({{apiPackageName}}Config config, IHttpRequester httpRequester) + /// Logger factory + public {{classname}}({{apiPackageName}}Config config, IHttpRequester httpRequester, ILoggerFactory loggerFactory = null) { if (httpRequester == null) { @@ -96,7 +100,14 @@ namespace Algolia.Search.Clients; throw new ArgumentException("`ApiKey` is missing."); } - _transport = new HttpTransport(config, httpRequester); + var factory = loggerFactory ?? NullLoggerFactory.Instance; + _transport = new HttpTransport(config, httpRequester, factory); + _logger = factory.CreateLogger<{{apiPackageName}}Client>(); + + if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information)) + { + _logger.LogInformation("Algolia {{apiPackageName}} client is initialized."); + } } {{#operation}} diff --git a/templates/csharp/netcore_project.mustache b/templates/csharp/netcore_project.mustache index 47fd8c9b07..7e0a2e2ef2 100644 --- a/templates/csharp/netcore_project.mustache +++ b/templates/csharp/netcore_project.mustache @@ -38,26 +38,9 @@ - {{#useCompareNetObjects}} - - {{/useCompareNetObjects}} - {{^useGenericHost}} + + - {{/useGenericHost}} - {{#useRestSharp}} - - {{/useRestSharp}} - {{#useGenericHost}} - - - {{/useGenericHost}} - {{^useGenericHost}} - {{/useGenericHost}} - {{#validatable}} - {{^net60OrLater}} - - {{/net60OrLater}} - {{/validatable}} {{>netcore_project.additions}} diff --git a/tests/output/csharp/src/HelpersTests.cs b/tests/output/csharp/src/HelpersTests.cs index 2fa3912841..892b6882da 100644 --- a/tests/output/csharp/src/HelpersTests.cs +++ b/tests/output/csharp/src/HelpersTests.cs @@ -4,6 +4,7 @@ using Algolia.Search.Http; using Algolia.Search.Models.Search; using Algolia.Search.Utils; +using Microsoft.Extensions.Logging; using Moq; using Newtonsoft.Json; using Xunit; diff --git a/tests/output/csharp/src/RetryStrategyTests.cs b/tests/output/csharp/src/RetryStrategyTests.cs index 06acd0678b..4db19233a9 100644 --- a/tests/output/csharp/src/RetryStrategyTests.cs +++ b/tests/output/csharp/src/RetryStrategyTests.cs @@ -1,9 +1,11 @@ +using System.Security.Cryptography; using System.Text; using Algolia.Search.Clients; using Algolia.Search.Exceptions; using Algolia.Search.Http; using Algolia.Search.Models.Search; using Algolia.Search.Transport; +using Microsoft.Extensions.Logging; using Moq; using Newtonsoft.Json; using Xunit; From 01180d910166508839201f9a9b7b3f674678d356 Mon Sep 17 00:00:00 2001 From: Morgan Leroi Date: Tue, 30 Jan 2024 13:10:33 +0100 Subject: [PATCH 2/3] add logs --- .../algoliasearch/Http/AlgoliaHttpRequester.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs b/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs index 3e5fe601e2..6711ac7629 100644 --- a/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs +++ b/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Algolia.Search.Http { @@ -27,7 +28,8 @@ internal class AlgoliaHttpRequester : IHttpRequester public AlgoliaHttpRequester(ILoggerFactory loggerFactory) { - _logger = loggerFactory.CreateLogger(); + var logger = loggerFactory ?? NullLoggerFactory.Instance; + _logger = logger.CreateLogger(); } /// From 66ca78d628da2921e7e645b9eb2245d6c5224686 Mon Sep 17 00:00:00 2001 From: Morgan Leroi Date: Wed, 31 Jan 2024 13:51:18 +0100 Subject: [PATCH 3/3] review --- templates/csharp/netcore_project.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/csharp/netcore_project.mustache b/templates/csharp/netcore_project.mustache index 7e0a2e2ef2..6efc0cb468 100644 --- a/templates/csharp/netcore_project.mustache +++ b/templates/csharp/netcore_project.mustache @@ -38,8 +38,8 @@ - - + +