Question3r
Question3r

Reputation: 3812

How to prevent Serilog from logging every little step as information automatically?

I want to use Serilog for my .Net 5 Web Api project. I installed the packages

and changed the Program.cs file to

public sealed class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();
        
        CreateHostBuilder(args)
            .Build()
            .Run();
    }

    private static IHostBuilder CreateHostBuilder(string[] args) 
        => Host
            .CreateDefaultBuilder(args)
            .UseSerilog()
            .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}

I created a single controller for testing purposes

[ApiController]
[Route("[controller]")]
public sealed class TodosController : ControllerBase
{
    [HttpGet("{todoId:Guid}")]
    public IActionResult GetTodoById(Guid todoId) => Ok(todoId);
}

After consuming this endpoint I can see the following in the console

[22:30:11 INF] Now listening on: https://localhost:5001
[22:30:11 INF] Now listening on: http://localhost:5000
[22:30:11 INF] Application started. Press Ctrl+C to shut down.
[22:30:11 INF] Hosting environment: Development
[22:30:11 INF] Content root path: /home/.../Server
[22:30:12 INF] Request starting HTTP/2 GET https://localhost:5001/swagger - -
[22:30:12 INF] Request finished HTTP/2 GET https://localhost:5001/swagger - - - 301 0 - 78.0119ms
[22:30:12 INF] Request starting HTTP/2 GET https://localhost:5001/swagger/index.html - -
[22:30:12 INF] Request finished HTTP/2 GET https://localhost:5001/swagger/index.html - - - 200 - text/html;charset=utf-8 64.9042ms
[22:30:12 INF] Request starting HTTP/2 GET https://localhost:5001/swagger/swagger-ui.css - -
[22:30:12 INF] Request starting HTTP/2 GET https://localhost:5001/swagger/swagger-ui-bundle.js - -
[22:30:12 INF] Request starting HTTP/2 GET https://localhost:5001/swagger/swagger-ui-standalone-preset.js - -
[22:30:12 INF] Sending file. Request path: '/swagger-ui-standalone-preset.js'. Physical path: 'N/A'
[22:30:12 INF] Sending file. Request path: '/swagger-ui.css'. Physical path: 'N/A'
[22:30:12 INF] Sending file. Request path: '/swagger-ui-bundle.js'. Physical path: 'N/A'
[22:30:12 INF] Request finished HTTP/2 GET https://localhost:5001/swagger/swagger-ui-bundle.js - - - 200 986342 application/javascript 191.4506ms
[22:30:12 INF] Request finished HTTP/2 GET https://localhost:5001/swagger/swagger-ui-standalone-preset.js - - - 200 311804 application/javascript 191.4478ms
[22:30:12 INF] Request finished HTTP/2 GET https://localhost:5001/swagger/swagger-ui.css - - - 200 142933 text/css 192.6142ms
[22:30:13 INF] Request starting HTTP/2 GET https://localhost:5001/swagger/v1/swagger.json - -
[22:30:13 INF] Request finished HTTP/2 GET https://localhost:5001/swagger/v1/swagger.json - - - 200 - application/json;charset=utf-8 83.3874ms
[22:30:41 INF] Request starting HTTP/2 GET https://localhost:5001/Todos/00119201-3fed-4741-8295-48d697790729 - -
[22:30:41 INF] Executing endpoint 'Server.Controllers.TodosController.GetTodoById (Server)'
[22:30:41 INF] Route matched with {action = "GetTodoById", controller = "Todos"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] GetTodoById(System.Guid) on controller Server.Controllers.TodosController (Server).
[22:30:41 INF] Executing OkObjectResult, writing value of type 'System.Guid'.
[22:30:41 INF] Executed action Server.Controllers.TodosController.GetTodoById (Server) in 34.6663ms
[22:30:41 INF] Executed endpoint 'Server.Controllers.TodosController.GetTodoById (Server)'
[22:30:41 INF] Request finished HTTP/2 GET https://localhost:5001/Todos/00119201-3fed-4741-8295-48d697790729 - - - 200 - application/json;+charset=utf-8 121.1434ms

I don't think this is a desired behaviour (if the log level is information instead of trace). Did I miss something? How to prevent Serilog from logging without being asked for it?

I already checked this question Serilog - MinimumLoggingLevel Information shows every request in log - is that normal? but that didn't help. The Serilog.Web.Classic package is not installed.

Upvotes: 13

Views: 12929

Answers (3)

Ivan  Silkin
Ivan Silkin

Reputation: 485

I ended up configuring the Serilog like this to hide the irrelevant information:

"Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Information",
        "Microsoft.Hosting.Lifetime": "Information",
        "Microsoft.AspNetCore.Hosting.Diagnostics": "Warning",
        "Microsoft.AspNetCore.Mvc.RazorPages": "Warning",
        "Microsoft.AspNetCore.Mvc.ViewFeatures": "Warning",
        "Microsoft.AspNetCore.StaticFiles": "Warning",
        // The migration is not applied, so what?
        "Microsoft.EntityFrameworkCore.Migrations": "Warning",
        // DbCommand executed, so what?
        "Microsoft.EntityFrameworkCore.Database": "Warning",
        "Microsoft.AspNetCore.Mvc.Infrastructure": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:/Logs/DEBUG-{Date}.txt",
          "rollingInterval": "Day"
        },
        "When": "Environment = 'Development'"
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:/Logs/RELEASE-{Date}.txt",
          "rollingInterval": "Day"
        },
        "When": "Environment = 'Production'"
      }
    ]
  }

And the Program.cs:

using Serilog;
        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    if (IsDevelopment())
                    {
                        webBuilder.UseUrls("http://0.0.0.0:5000", "https://0.0.0.0:5001");
                    }
                }).UseSerilog((hostingContext, loggerConfiguration) =>
                {
                    loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);
                });
        }

Output on executing "Home/Index":

[16:03:19 INF] Now listening on: http://0.0.0.0:5000
[16:03:19 INF] Now listening on: https://0.0.0.0:5001
[16:03:19 INF] Application started. Press Ctrl+C to shut down.
[16:03:19 INF] Hosting environment: Development
[16:03:19 INF] Content root path: O:\VCSharp\MVCSolution\MVCApplication
[16:03:22 INF] Executing endpoint 'MVCApplication.Controllers.HomeController.Index (MVCApplication)'
[16:03:26 INF] Executed endpoint 'MVCApplication.Controllers.HomeController.Index (MVCApplication)'

Upvotes: 6

Guru Stron
Guru Stron

Reputation: 142963

You need to set up log level for "Microsoft.Hosting.Lifetime" and "Microsoft". Personally I use Serilog.Settings.Configuration package, adding .ReadFrom.Configuration(configuration) to the set up and copying values provided by default template to Serilog.MinimumLevel.Override json property in config:

  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    }
  },

Upvotes: 5

C. Augusto Proiete
C. Augusto Proiete

Reputation: 27878

These logs are being written by the ASP .NET host with the level Information and thus Serilog receives them as Information as well.

What you can do, is override the MinimumLevel for different sources, so that you can continue to receive Information-level logs written by some sources, whilst ignoring Information-level logs written by the host.

Here's an example that:

  • Sets the overall MinimumLevel to Information
  • Overrides the MinimumLevel to Warning only for logs coming from the Microsoft source
  • Overrides the MinimumLevel to Information only for logs coming from the Microsoft.Hosting.Lifetime source

e.g.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
    .WriteTo.Console()
    .CreateLogger();

You can also configure these source overrides via appSettings.json:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    }
  },
  "AllowedHosts": "*"
}

Upvotes: 31

Related Questions