-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HttpClientFactory] Remove dependency on ILoggerFactory #89531
Conversation
Tagging subscribers to this area: @dotnet/ncl Issue Details
cc @CodeBlanch Fixes #89032
|
Test failures are unrelated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just one question.
src/libraries/Microsoft.Extensions.Http/src/Logging/NetEventSource.cs
Outdated
Show resolved
Hide resolved
Would you mind verifying that this test passes with the change? This will verify #89032. It seems like it should, but just want to make sure. [Fact]
public void LoggerFactoryWithHttpClientFactoryTest()
{
var services = new ServiceCollection();
services.AddHttpClient();
services.AddLogging(builder => builder.Services.AddSingleton<ILoggerProvider, TestLoggerProvider>());
using var serviceProvider = services.BuildServiceProvider();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
}
private sealed class TestLoggerProvider : ILoggerProvider
{
private readonly HttpClient _httpClient;
public TestLoggerProvider(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient("TestLoggerProvider");
}
public ILogger CreateLogger(string categoryName)
{
return NullLogger.Instance;
}
public void Dispose()
{
_httpClient.Dispose();
}
} |
@CodeBlanch you need to remove the default HttpClient logging (that uses ILoggerFactory, and I cannot change that without breaking the end users) -- so in your suggestion I've changed services.AddHttpClient("TestLoggerProvider").RemoveAllLoggers(); Default logging can also be removed for all HttpClients by services.ConfigureHttpClientDefaults(b => b.RemoveAllLoggers()); (it is still possible to add the default logging back per-name with |
Wait, this is a breaking change for anyone who is using these logs. Also, Could this be fixed by not resolving ILoggerFactory in the private ILogger Logger
{
get { return _logger ??= _serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<DefaultHttpClientFactory>(); }
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean debugging DefaultHttpClientFactory logs that say that the cleanup cycle has started? This really looked like an internal diagnostics stuff, not a thing anyone could depend on? Because the "default" per-client logs stay the same as they were (using ILogger). I've thought on an ability to bring the debugging back to ILogger via an app-context switch, if it's reeeally needed.... And the user setting this would guarantee that they haven't registered any logging provider that internally uses HttpClientFactory.
I don't think there's any other way to fix the bug. Even if the factory would be created by making the resolution to be lazy, the whole thing would still enter an endless cycle trying to log that it logs that it logs etc |
Are you sure? Logging isn't async. Some more log messages will get written when, for example, Btw I don't have an objection to requiring people to remove default HTTP client logging. That's just a configuration change required by someone who wants to do this. Alternatively, you could suggest to them that they disable that logging with Microsoft.Extensions.Logging filters. They could do the same thing to filter out logging from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the added tests simulate the reported problem and with the lazy initialization it's solved. If so, still LGTM.
_optionsMonitor = optionsMonitor; | ||
|
||
_loggerFactory = new Lazy<ILoggerFactory>(serviceProvider.GetRequiredService<ILoggerFactory>, LazyThreadSafetyMode.PublicationOnly); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment explaining why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why PublicationOnly in this lazy and ExecutionAndPublication in DefaultHttpClientFactory lazy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we don't need to guard this one at all, given that DI should already guard creation of a singleton.
DefaultHttpClientFactory lazy is creating ILogger, which is most possibly a new instance every time CreateLogger is invoked, so I want to avoid unnecessary allocations.
...rosoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/Logging/HttpClientLoggerTest.cs
Outdated
Show resolved
Hide resolved
@JamesNK PTAL |
Internal diagnostics logging in
DefaultHttpClientFactory
now uses a newEventSource
("Private.InternalDiagnostics.Microsoft.Extensions.Http") instead ofILogger
LoggingHttpMessageHandlerBuilderFilter
only resolvesILoggerFactory
if default logging is oncc @CodeBlanch
Fixes #89032