ASP.NET Core 3.1 HttpClient to log only warnings and errors - asp.net-core

I've noticed that my application(service) that supposed to run in a backgraund creates a log of garbage logging information because of HttpClient, like so:
info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
Start processing HTTP request POST https://localhost:44317/programmatic/getcontent info:
System.Net.Http.HttpClient.Default.ClientHandler[100]
Sending HTTP request POST https://localhost:44317/programmatic/getcontent info:
System.Net.Http.HttpClient.Default.ClientHandler[101]
Received HTTP response after 3027.6345ms - OK info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
End processing HTTP request after 3028.2987ms - OK info: System.Net.Http.HttpClient.Default.ClientHandler[101]
Received HTTP response after 3052.4709ms - OK info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
End processing HTTP request after 3053.467ms - OK
Is there a way to configure it anywhere?
I inject client factory like this:
serviceCollection.AddHttpClient();
And then create a client like this:
HttpClient client = _clientFactory.CreateClient();

You can configure Logging in .NET Core through the Appsettings file. You should find a section in the appsettings.json file along the lines
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information"
}
}
}
}
You can add an additional Log Level filter to specify the minimum log level required to log.
{
"Logging": {
"Debug": {
"LogLevel": {
"Default": "Information",
"System.Net.Http.HttpClient": "Debug"
}
}
}
}
Documentation for Logging with filters in .NET Core can be found here.
Documemtation for Logging with filters in the IHttpClientFactory library can be found here. This documentation also includes examples of log filtering with a named HttpClient.

You can override log level in appsettings.json by adding, for example, a new row to the Logging object:
"Logging": {
"LogLevel": {
"System.Net.Http.HttpClient": "Warning"
}
},
This will log anything from Warning level and above.

Related

Set Log Levels for Microsoft.* , System, and AspNet when using Serilog

I had always imagined that
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
would set my project code's log level to Debug, and make Microsoft.* namespaces log at Information level or higher. It seems not. With this config, AspNetCore infrastructure logs at Debug level.
How do I target Microsoft.* to not use the Default level?
I'm using Serilog, but the injected Loggers are all Microsoft.Extensions.Logging.ILogger so I expected Microsoft.Extensions.Logging config to kick in.
Is this a mistaken assumption?
Yes, the assumption that Serilog will respect the Logging.LogLevel section when used with Extensions.Logging is wrong. It doesn't.
To read serilog levels from config, some options are:
use https://github.com/serilog/serilog-settings-configuration and use the config structure they give, especially the section at MinimumLevel, LevelSwitches, overrides
For those who do Serilog config in code, use something like this:
var defaultLogLevel = configuration.GetLogLevel("Default");
var aspNetCoreLogLevel = configuration.GetLogLevel("Microsoft.AspNetCore");
var microsoftLogLevel = configuration.GetLogLevel("Microsoft");
var logger = new LoggerConfiguration()
.MinimumLevel.Is(defaultLogLevel)
.MinimumLevel.Override("Microsoft.AspNetCore", aspNetCoreLogLevel)
.MinimumLevel.Override("Microsoft", microsoftLogLevel)
// ... etc ...
// ...
static LogEventLevel GetLogLevel(this IConfiguration configuration, string #namespace, string fallbackLevel = "Information")
{
return Enum.Parse<LogEventLevel>(configuration["Logging:LogLevel:" + #namespace] ?? fallbackLevel);
}
but the in-config approach for minimum levels has the advantage that you can make use of reloadOnChange

Serilog doesn't write to text file the log of console log in ASP.NET Core 6 minimal API

For debugging, I would like to write all what happens in the ASP.NET service. How I will install it as service, I need to write it in a text file.
But in debugging, I can see the output in console and in the text file.
First, I configure the json settings:
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": { "path": "Logs/log.txt" }
}
],
And the I use this code in the program.cs of the ASP.NET Core project:
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
.Build();
var miFicheroTextoLogger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
miFicheroTextoLogger.Information("Prueba");
In the console, I can see this:
[17:39:22 INF] Prueba
trce: Grpc.AspNetCore.Server.Model.Internal.ServiceRouteBuilder[2]
Discovering gRPC methods for GestorOrdenadores.Service.Server.Grpc.GestorOrdenadoresService.
trce: Grpc.AspNetCore.Server.Model.Internal.ServiceRouteBuilder[1]
Added gRPC method 'SayHello' to service 'greet.Greeter'. Method type: Unary, HTTP method: POST, route pattern: '/greet.Greeter/SayHello'.
dbug: Microsoft.Extensions.Hosting.Internal.Host[1]
Hosting starting
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://[::]:5001
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[13]
Loaded hosting startup assembly GestorOrdenadores.Service.Server.Host.AspCore
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: D:\desarrollo\proyectos\GestorOrdenadores\GestorOrdenadores.Service.Server.Host.AspCore\bin\Debug\net6.0\
dbug: Microsoft.Extensions.Hosting.Internal.Host[2]
Hosting started
But in my text file I only have:
2022-08-26 17:39:22.057 +02:00 [INF] Prueba
In the text file only writes what I told to write with miFicheroTextoLogger.Information("Prueba"); but I would like to write all what ASP.NET Core tells too.
Thanks.
This code is wrong. First, there's no reason to create another configuration instance. The host generated by the minimal API template already uses these configuration sources.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
As the docs explain the default configuration reads from
appSettings.json and appSettings.{environment}.json
Environment variables
The command line
Logging can be configured through the builder.Logger property. If you add the Serilog.AspNetCore package you can also use the UseSerilog() method through builder.Host :
builder.Host.UseSerilog((ctx, lc) => lc
.WriteTo.Console()
.ReadFrom.Configuration(ctx.Configuration));
In this example the logger is configured using both code and settings.
You can also add request logging by adding this after `Build():
app.UseSerilogRequestLogging();
Putting this together :
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((ctx, lc) => lc
.WriteTo.Console()
.ReadFrom.Configuration(ctx.Configuration));
var app = builder.Build();
app.UseSerilogRequestLogging();
app.MapGet("/", () => "Hello World!");
app.Run();
The Serilog .NET 6 Minimal API example projects shows how to add Serilog to a Minimal API project configure it. It also adds a fallback logger should the startup process fail

Console logger with json formatter does not serialize objects

I try to use default .NET core logging tools without any third party libs. So, question.
Does console logger with Json formatter support json serialization of objects?
I have the following config in appsettings
"Logging": {
"Console": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information",
"Microsoft.Hosting.Lifetime": "Information"
},
"FormatterName": "json",
"FormatterOptions": {
"SingleLine": true,
"JsonWriterOptions": {
"Indented": true
}
}
}
},
The following line
logger.LogDebug("RequestId:{requestId} ResponseInfo: {#response} ", requestName, response);
produces the output with string representation of #response object, internally it still invokes ToString(), but docs in Caution section says that
The logging infrastructure itself already manages the serialization of log messages, so if you're to pass in a log message that is already serialized—it will be double serialized
docs
And this point me that it should serialize object.
I think the build-in ILogger don't support this. That's why we can try the new System.Text.Json source generator.
The new System.Text.Json source generator can improve logging performance.
I think we also can choose third-party package, like Serilog. That should be more easy to do this.

ASP.NET Web API not logging exception in application insights when deployed in Azure

I have enabled application insights logging in my ASP.NET Web API project which is done from a class implementing IExceptionLogger. In debug mode it's logging exceptions to application insights using TrackException().
But when the same code is deployed in an Azure App Service, it's not sending exception to application insights, but it's able to send data using traces.
After trying lot of different ways (flush also), I have added one method which will log exception in SharePoint list, after that Web API is also able to send data to Application Insights. When commenting out the SharePoint code, the Web API stopped sending exception to Application Insights.
I am not sure whether its happening due to some extra time that TelemetryClient is getting due to SharePoint code.
Anyone faced this issue?
Here is the Microsoft doc link which I have followed: LINK
Make sure you have added the Application Insights logging level in appsettings.json
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ApplicationInsights": {
"ConnectionString": "< App insights connection string>"
}
}
After adding the log level of application insights I can able to see the custom logs and exceptions.
Here you can see the security level to verify the logging level
Refer here

Windows Authentication with asp.net core

Please provide guidance on how to implement Windows Authentication on ASP.NET Core RC2+.
I see other SO questions that describe bearer authentication like Bearer Authentication with ASP.NET Core RC2 404 instead of 403
But that is not what I am looking for.
You can do this using WebListener, like so:
Open your project.json and add WebListener to dependencies:
"dependencies" : {
...
"Microsoft.AspNetCore.Server.WebListener": "0.1.0-rc2-final"
...
}
Add WebListener to commands (again in Project.json)
"commands": {
"weblistener": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener"
},
In Startup.cs, specify the WebHostBuilder to use WebListener with NTLM
var host = new WebHostBuilder()
// Some configuration
.UseWebListener(options => options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM)
// Also UseUrls() is mandatory if no configuration is used
.Build();
That's it!
This doesn't appear to work any longer in the .Net Core 1.0.0 (RTM). I do the WebHostBuilder exactly as above in Ivan Prodanov's answer; it runs, don't get an error there, but the HttpContext.User is not marked with a WindowsIdentity. Following code used to work in ASP.Net 5 beta6:
in project.json:
"version": "1.0.0"
"dependencies": {
"Microsoft.AspNetCore.Owin": "1.0.0",
"Microsoft.AspNetCore.Server.WebListener": "0.1.0",
in middleware class:
public async Task Invoke(HttpContext context)
{
try
{
ClaimsPrincipal principal = context.User;
// <-- get invalidcastexception here:
WindowsIdentity winIdentity = (WindowsIdentity)principal.Identity;
....
....
Check your launchSettings.json file - change anonymousAuthentication to false
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
For deployment to iis check this Asp.Net core MVC application Windows Authentication in IIS