diff --git a/.editorconfig b/.editorconfig
index c93d988..e3e6e54 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -16,7 +16,6 @@ indent_style = space
tab_width = 4
# New line preferences
-insert_final_newline = true
trim_trailing_whitespace = true
@@ -67,9 +66,9 @@ dotnet_code_quality_unused_parameters = all:suggestion
#### C# Coding Conventions ####
# var preferences
-csharp_style_var_elsewhere = false:silent
-csharp_style_var_for_built_in_types = false:silent
-csharp_style_var_when_type_is_apparent = false:silent
+csharp_style_var_elsewhere = true
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
@@ -89,7 +88,7 @@ csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
+csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async
# Code-block preferences
csharp_prefer_braces = true:silent
@@ -103,7 +102,10 @@ csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# C# 10
-csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_namespace_declarations = file_scoped:error
+csharp_style_prefer_primary_constructors = true
+dotnet_diagnostic.IDE0290.severity = error
+
#### C# Formatting Rules ####
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 6b32f82..4a51353 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -7,14 +7,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - name: Setup .NET
- uses: actions/setup-dotnet@v3
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.x
- - name: Restore dependencies
- run: dotnet restore source
- - name: Build
- run: dotnet build --no-restore source
- - name: Test
- run: dotnet test source /p:CollectCoverage=true /p:CoverletOutputFormat=opencover --logger "GitHubActions;report-warnings=false"
+ dotnet-version: 9.0.x
+ - run: dotnet restore source
+ - run: dotnet build --no-restore source
+ - run: dotnet test source /p:CollectCoverage=true /p:CoverletOutputFormat=opencover --logger "GitHubActions;report-warnings=false"
diff --git a/.github/workflows/PreRelease.yml b/.github/workflows/PreRelease.yml
index 1bb8545..f725d48 100644
--- a/.github/workflows/PreRelease.yml
+++ b/.github/workflows/PreRelease.yml
@@ -8,24 +8,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
- run: echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV
- - name: Install GitVersion
- uses: gittools/actions/gitversion/setup@v0
+ - uses: gittools/actions/gitversion/setup@v0
with:
versionSpec: "5.x"
- - name: Determine Version
+ - uses: gittools/actions/gitversion/execute@v0
id: gitversion
- uses: gittools/actions/gitversion/execute@v0
with:
useConfigFile: true
- - name: Setup .NET
- uses: actions/setup-dotnet@v3
+ - uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.x
- - name: Pack
- run: dotnet pack source /p:Version=${{ steps.gitversion.outputs.NuGetVersionV2 }}-${{ steps.gitversion.outputs.ShortSha }} /p:InformationalVersion=${{ steps.gitversion.outputs.informationalVersion }} /p:PackageReleaseNotes="https://github.com/$GITHUB_REPOSITORY/releases/tag/${{ steps.gitversion.outputs.NuGetVersionV2 }}" -o ./releases
- - name: Publish
- run: dotnet nuget push ./releases/**/*.nupkg -k=${{ secrets.NUGETORGAPIKEY }} -s=nuget.org
+ dotnet-version: 9.0.x
+ - run: dotnet pack source /p:Version=${{ steps.gitversion.outputs.NuGetVersionV2 }}-${{ steps.gitversion.outputs.ShortSha }} /p:InformationalVersion=${{ steps.gitversion.outputs.informationalVersion }} /p:PackageReleaseNotes="https://github.com/$GITHUB_REPOSITORY/releases/tag/${{ steps.gitversion.outputs.NuGetVersionV2 }}" -o ./releases
+ - run: dotnet nuget push ./releases/**/*.nupkg -k=${{ secrets.NUGETORGAPIKEY }} -s=nuget.org
diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml
index 6e5badb..26c0bad 100644
--- a/.github/workflows/Release.yml
+++ b/.github/workflows/Release.yml
@@ -8,12 +8,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
fetch-depth: 0
- run: echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV
- - name: Install GitVersion
- uses: gittools/actions/gitversion/setup@v0
+ - uses: gittools/actions/gitversion/setup@v0
with:
versionSpec: "5.x"
- name: Determine Version
@@ -22,9 +21,9 @@ jobs:
with:
useConfigFile: true
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.x
+ dotnet-version: 9.0.x
- name: Pack
run: dotnet pack source /p:Version=${{ steps.gitversion.outputs.majorMinorPatch }} /p:InformationalVersion=${{ steps.gitversion.outputs.informationalVersion }} /p:PackageReleaseNotes="https://github.com/$GITHUB_REPOSITORY/releases/tag/${{ steps.gitversion.outputs.majorMinorPatch }}" -o ./releases
- name: Publish
diff --git a/README.md b/README.md
index 1896038..1de33bb 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,28 @@
# MinimalHttpLogger
[](https://github.com/johnkors/MinimalHttpLogger/actions)
- [](https://www.nuget.org/packages/MinimalHttpLogger/)
+[](https://www.nuget.org/packages/MinimalHttpLogger/)
[](https://www.nuget.org/packages/MinimalHttpLogger/)
-
## Why?
-My logs were
-* hard to read
-* filling up space(*)
+
+My logs were
+
+* hard to read
+* filling up space(*)
## What is this?
-It's not possible to configure the log pattern of the Microsoft.Extensions.Http based HttpClient loggers. To modify, one has to replace them. This package replaces the default loggers with a logger that:
+It's not possible to configure the log pattern of the Microsoft.Extensions.Http based HttpClient loggers. To modify, one
+has to replace them. This package replaces the default loggers with a logger that:
-1. Reduces the number of log statements on httpclient requests from 4 to 1
+1. Reduces the number of log statements on httpclient requests from 4 to 1
2. Logs 1 aggregated log statement: `{Method} {Uri} - {StatusCode} {StatusCodeLiteral} in {Time}ms`
-
### Change in output
Before:
+
```log
info: Start processing HTTP request GET https://www.google.com/
info: Sending HTTP request GET https://www.google.com/
@@ -29,11 +31,11 @@ info: End processing HTTP request after 188.8026ms - 200
```
After:
+
```log
info: GET https://www.google.com/ - 200 OK in 186.4883ms
```
-
## Install
```sh
diff --git a/samples/With/Program.cs b/samples/With/Program.cs
index b919309..50839ec 100644
--- a/samples/With/Program.cs
+++ b/samples/With/Program.cs
@@ -1,6 +1,6 @@
using With;
-IHost host = Host.CreateDefaultBuilder(args)
+var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging((c, b) =>
{
b.AddSimpleConsole(o => { o.SingleLine = true; });
@@ -18,6 +18,3 @@
.Build();
await host.RunAsync();
-
-
-
diff --git a/samples/With/Properties/launchSettings.json b/samples/With/Properties/launchSettings.json
index bc15687..3a46e50 100644
--- a/samples/With/Properties/launchSettings.json
+++ b/samples/With/Properties/launchSettings.json
@@ -1,6 +1,6 @@
{
"profiles": {
- "Without": {
+ "With": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
diff --git a/samples/With/With.csproj b/samples/With/With.csproj
index 249348e..02fa076 100644
--- a/samples/With/With.csproj
+++ b/samples/With/With.csproj
@@ -1,17 +1,17 @@
- net8.0
+ net9.0
enable
-
-
-
+
+
+
-
+
diff --git a/samples/With/Worker.cs b/samples/With/Worker.cs
index 8a83971..8ef7c48 100644
--- a/samples/With/Worker.cs
+++ b/samples/With/Worker.cs
@@ -24,7 +24,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timeout!");
}
- catch(Exception e)
+ catch (Exception e)
{
_logger.LogError(e.Message);
}
diff --git a/samples/Without/Program.cs b/samples/Without/Program.cs
index b364bfd..9903d08 100644
--- a/samples/Without/Program.cs
+++ b/samples/Without/Program.cs
@@ -1,7 +1,9 @@
using Without;
-IHost host = Host.CreateDefaultBuilder(args)
- .ConfigureLogging((c, b) =>
+AppContext.SetSwitch("System.Net.Http.DisableUriRedaction", true);
+
+var host = Host.CreateDefaultBuilder(args)
+ .ConfigureLogging((_, b) =>
{
b.AddSimpleConsole(o => { o.SingleLine = true; });
})
@@ -12,11 +14,9 @@
hostOptions.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore;
});
services.AddHttpClient();
+
services.AddHostedService();
})
.Build();
await host.RunAsync();
-
-
-
diff --git a/samples/Without/Without.csproj b/samples/Without/Without.csproj
index 3a33a36..85cf14a 100644
--- a/samples/Without/Without.csproj
+++ b/samples/Without/Without.csproj
@@ -1,13 +1,13 @@
- net6.0
+ net9.0
enable
-
-
-
+
+
+
diff --git a/samples/Without/Worker.cs b/samples/Without/Worker.cs
index 470942e..ffe1f0e 100644
--- a/samples/Without/Worker.cs
+++ b/samples/Without/Worker.cs
@@ -24,7 +24,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timeout!");
}
- catch(Exception e)
+ catch (Exception e)
{
_logger.LogError(e.Message);
}
diff --git a/source/MinimalHttpLogger/MinimalHttpLogger.cs b/source/MinimalHttpLogger/MinimalHttpLogger.cs
index b2cf07e..ef9e9f3 100644
--- a/source/MinimalHttpLogger/MinimalHttpLogger.cs
+++ b/source/MinimalHttpLogger/MinimalHttpLogger.cs
@@ -11,20 +11,15 @@ public static class ServiceCollectionExtensions
{
public static IServiceCollection UseMinimalHttpLogger(this IServiceCollection services)
{
- services.Replace(ServiceDescriptor.Singleton());
+ services.Replace(ServiceDescriptor
+ .Singleton());
return services;
}
}
-internal class ReplaceLoggingHttpMessageHandlerBuilderFilter : IHttpMessageHandlerBuilderFilter
+internal class ReplaceLoggingHttpMessageHandlerBuilderFilter(ILoggerFactory loggerFactory)
+ : IHttpMessageHandlerBuilderFilter
{
- private readonly ILoggerFactory _loggerFactory;
-
- public ReplaceLoggingHttpMessageHandlerBuilderFilter(ILoggerFactory loggerFactory)
- {
- _loggerFactory = loggerFactory;
- }
-
public Action Configure(Action next)
{
return builder =>
@@ -32,52 +27,56 @@ public Action Configure(Action (h is LoggingHttpMessageHandler) || h is LoggingScopeHttpMessageHandler).Select(h => h).ToList();
+ var innerLogger = loggerFactory.CreateLogger($"System.Net.Http.HttpClient.{loggerName}.ClientHandler");
+ var toRemove = builder.AdditionalHandlers
+ .Where(h => h is LoggingHttpMessageHandler or LoggingScopeHttpMessageHandler)
+ .ToList();
foreach (var delegatingHandler in toRemove)
{
builder.AdditionalHandlers.Remove(delegatingHandler);
}
+
builder.AdditionalHandlers.Add(new RequestEndOnlyLogger(innerLogger));
};
}
}
-internal class RequestEndOnlyLogger : DelegatingHandler
+internal class RequestEndOnlyLogger(ILogger logger) : DelegatingHandler
{
- private readonly ILogger _logger;
-
- public RequestEndOnlyLogger(ILogger logger)
- {
- _logger = logger;
- }
-
- protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ protected override async Task SendAsync(HttpRequestMessage request,
+ CancellationToken cancellationToken)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
- var requestUri = request.RequestUri?.ToString(); //SendAsync modifies req uri in case of redirects (?!), so making a local copy
+
+ var
+ requestUri =
+ request.RequestUri
+ ?.ToString(); //SendAsync modifies req uri in case of redirects (?!), so making a local copy
var stopwatch = ValueStopwatch.StartNew();
try
{
var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
- _logger.LogInformation("{Method} {Uri} - {StatusCode} {StatusCodeLiteral} in {Time}ms", request.Method, requestUri, $"{(int)response.StatusCode}", $"{response.StatusCode}", stopwatch.GetElapsedTime().TotalMilliseconds);
+ logger.LogInformation("{Method} {Uri} - {StatusCode} {StatusCodeLiteral} in {Time}ms", request.Method,
+ requestUri, $"{(int)response.StatusCode}", $"{response.StatusCode}",
+ stopwatch.GetElapsedTime().TotalMilliseconds);
return response;
}
- catch(Exception)
+ catch (Exception)
{
- _logger.LogInformation("{Method} {Uri} failed to respond in {Time}ms", request.Method, requestUri, stopwatch.GetElapsedTime().TotalMilliseconds);
+ logger.LogInformation("{Method} {Uri} failed to respond in {Time}ms", request.Method, requestUri,
+ stopwatch.GetElapsedTime().TotalMilliseconds);
throw;
}
}
- internal struct ValueStopwatch
+ internal readonly struct ValueStopwatch
{
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
- private long _startTimestamp;
+ private readonly long _startTimestamp;
public bool IsActive => _startTimestamp != 0;
@@ -86,18 +85,22 @@ private ValueStopwatch(long startTimestamp)
_startTimestamp = startTimestamp;
}
- public static ValueStopwatch StartNew() => new ValueStopwatch(Stopwatch.GetTimestamp());
+ public static ValueStopwatch StartNew()
+ {
+ return new ValueStopwatch(Stopwatch.GetTimestamp());
+ }
public TimeSpan GetElapsedTime()
{
if (!IsActive)
{
- throw new InvalidOperationException("An uninitialized, or 'default', ValueStopwatch cannot be used to get elapsed time.");
+ throw new InvalidOperationException(
+ "An uninitialized, or 'default', ValueStopwatch cannot be used to get elapsed time.");
}
- long end = Stopwatch.GetTimestamp();
- long timestampDelta = end - _startTimestamp;
- long ticks = (long)(TimestampToTicks * timestampDelta);
+ var end = Stopwatch.GetTimestamp();
+ var timestampDelta = end - _startTimestamp;
+ var ticks = (long)(TimestampToTicks * timestampDelta);
return new TimeSpan(ticks);
}
}
diff --git a/source/MinimalHttpLogger/MinimalHttpLogger.csproj b/source/MinimalHttpLogger/MinimalHttpLogger.csproj
index eb0877a..4e67efd 100644
--- a/source/MinimalHttpLogger/MinimalHttpLogger.csproj
+++ b/source/MinimalHttpLogger/MinimalHttpLogger.csproj
@@ -1,7 +1,7 @@
- net7.0;net8.0
+ net9.0
enable
latest
enable
@@ -17,28 +17,21 @@
- 7.0.0
- 8.0.0
+ 9.0.0
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+