Refactoring (LogExtensions): Ersetzen der benutzerdefinierten LogCurlAsync durch eine auf HttpClientToCurl basierende Implementierung

- Manuelle cURL-Zeichenfolgenkonstruktion in `LogExtensions` entfernt.
- Überladungen von `LogCurl` unter Verwendung von `HttpClient.GenerateCurlInString` eingeführt.
- Unterstützung für das Kürzen langer cURL-Ausgaben mit `maxLength` hinzugefügt.
- Parameter vereinfacht und Wartbarkeit verbessert.
This commit is contained in:
2025-08-18 16:48:23 +02:00
parent 0273beb6f8
commit e9a7ef910f
3 changed files with 56 additions and 64 deletions

View File

@@ -108,12 +108,12 @@ public class EConnectClient<TError> : IEConnectClient<TError> where TError : cl
{ {
{ fileContent, "file", fileName } { fileContent, "file", fileName }
}; };
message.Content = form; message.Content = form;
var res = await Http.SendAsync(message, cancel); var res = await Http.SendAsync(message, cancel);
_logger?.LogCurlAsync(Http, requestMessage: message); _logger?.LogCurl(Http, message);
return res.IsSuccessStatusCode return res.IsSuccessStatusCode
? new() ? new()

View File

@@ -7,6 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HttpClientToCurl" Version="2.0.6" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.19" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.19" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />

View File

@@ -1,75 +1,66 @@
using Microsoft.Extensions.Logging; using HttpClientToCurl;
using System.Text; using HttpClientToCurl.Config;
using Microsoft.Extensions.Logging;
using System.Net.Http.Headers;
namespace Leanetec.EConnect.Infrastructure; namespace Leanetec.EConnect.Infrastructure;
public static class LogExtensions public static class LogExtensions
{ {
public static async Task LogCurlAsync<TCategoryName>( public static void LogCurl<TCategoryName>(
this ILogger<TCategoryName> logger, this ILogger<TCategoryName> logger,
HttpClient client, HttpClient client,
HttpMethod? method = null, HttpRequestMessage request,
string? route = null, Action<StringConfig>? config = null,
HttpContent? content = null, int maxLength = 1000,
HttpRequestMessage? requestMessage = null,
LogLevel logLevel = LogLevel.Information) LogLevel logLevel = LogLevel.Information)
{ {
route ??= requestMessage?.RequestUri?.ToString(); var curl = client.GenerateCurlInString(
request,
config
).Substring(0, maxLength) + "...[truncated]";
logger?.Log(logLevel, "{curl}", curl);
}
var sb = new StringBuilder(); public static void LogCurl<TCategoryName>(
sb.Append("curl"); this ILogger<TCategoryName> logger,
HttpClient client,
HttpMethod method,
string uri = "",
HttpRequestHeaders? headers = null,
HttpContent? content = null,
Action<StringConfig>? config = null,
int maxLength = 1000,
LogLevel logLevel = LogLevel.Information)
{
var curl = client.GenerateCurlInString(
method,
uri,
headers,
content,
config
).Substring(0, maxLength) + "...[truncated]";
logger?.Log(logLevel, "{curl}", curl);
}
// Method public static void LogCurl<TCategoryName>(
sb.Append($" -X {method?.Method ?? requestMessage?.Method.ToString()}"); this ILogger<TCategoryName> logger,
HttpClient client,
// URL HttpMethod method,
var fullUrl = string.Empty; Uri uri,
if (client.BaseAddress is not null && route is not null) HttpRequestHeaders? headers = null,
fullUrl = new Uri(client.BaseAddress, route).ToString(); HttpContent? content = null,
else if (route is not null) Action<StringConfig>? config = null,
fullUrl = route; int maxLength = 1000,
else if (client.BaseAddress is not null) LogLevel logLevel = LogLevel.Information)
fullUrl = client.BaseAddress.ToString(); {
var curl = client.GenerateCurlInString(
if (!string.IsNullOrWhiteSpace(fullUrl)) method,
sb.AppendLine($" \"{fullUrl}\""); uri,
headers,
// Headers content,
foreach (var header in client.DefaultRequestHeaders) config
{ ).Substring(0, maxLength) + "...[truncated]";
sb.AppendLine($"\t-H \"{header.Key}: {string.Join(", ", header.Value)}\""); logger?.Log(logLevel, "{curl}", curl);
}
// Headers
if (requestMessage is not null)
foreach (var header in requestMessage.Headers)
{
sb.AppendLine($"\t-H \"{header.Key}: {string.Join(", ", header.Value)}\"");
}
if (content != null)
{
foreach (var header in content.Headers)
{
sb.AppendLine($"\t-H \"{header.Key}: {string.Join(", ", header.Value)}\"");
}
var mediaType = content.Headers.ContentType?.MediaType;
if (mediaType is not null && mediaType.StartsWith("text") || mediaType!.Contains("json"))
{
var body = await content.ReadAsStringAsync();
if (!string.IsNullOrWhiteSpace(body))
{
// Escape double quotes
body = body.Replace("\"", "\\\"");
sb.AppendLine($"\t-d \"{body}\"");
}
}
else
// Binary content, only placeholder in log
sb.AppendLine("\t-d \"<binary data>\"");
}
logger.Log(logLevel, "{message}", sb.ToString());
} }
} }