ASP.Net Core API self hosted logging to file

Using ASP.Net Core 5.0 to roll out a Web API service which is running as it's own Windows Service. I'm trying to figure out how to use the Microsoft.Extensions.Logging to write logs to a file.

I would like to be able to specify the location of the logfile in the appsettings.json file that is rolled out with the application. I feel like I'm missing something.

Do I have to use another library with Microsoft.Extensions.Logging, like Serilog, in order to accomplish this? I've read through the link below and don't see anything about file logging.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0

I'm coming from a background where we used log4Net, but can't wrap my head around how to get Microsofot.Extensions.Logging to work.

I tried Serilog, but I run into an issue where when I'm debugging, it seems like the project always runs under IIS Express, even when I set the profile to the name of the project, and "Launch" to "Project".

What am I missing here?


Solution 1:

From the Microsoft documentation:

ASP.NET Core doesn't include a logging provider for writing logs to files. To write logs to files from an ASP.NET Core app, consider using a third-party logging provider.

Using Serilog works perfectly fine for me.

Program.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;

namespace WebApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var config = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: false)
                .Build();

            var path = config.GetValue<string>("Logging:FilePath");
            
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                .Enrich.FromLogContext()
                .WriteTo.File(path)
                .CreateLogger();
            
            CreateHostBuilder(args).Build().Run();
        }

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

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "FilePath" : "logs/AppLog.txt"
  },
  "AllowedHosts": "*"
}

Controller (or Service, whatever you need):

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace WebApplication
{
    [ApiController]
    public class MyController : ControllerBase
    {
        private readonly ILogger<MyController> _logger;
        
        public MyController(ILogger<MyController> logger)
        {
            _logger = logger;
        }
        
        
        [HttpGet("/test")]
        public ActionResult<string> Test()
        {
            _logger.LogInformation("Hello World.");

            return "Success";
        }
    }
}

Packages I installed:

<ItemGroup>
    <PackageReference Include="Serilog" Version="2.10.0" />
    <PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
    <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
</ItemGroup>

As for running on IISExpress, this depends on the launchSettings.json you have, not exactly sure what your issue is there. Generally you use "commandName": "Project" for Kestrel and "commandName": "IISExpress" for IISExpress in your profiles. Your IDE then lets you select you which run configuration you want to have.