4

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://learn.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?

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

Comments

2

I based my solution on Jakob's, with some minor changes

In appSettings.json I added the file path:

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

In Program.cs I added the following code:

using Serilog;

var config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json", optional: false)
    .Build();

var builder = WebApplication.CreateBuilder(args);

// Apply logging 
builder.Logging.ClearProviders();
var path = config.GetValue<string>("Logging:FilePath");
var logger = new LoggerConfiguration()
    .WriteTo.File(path)
    .CreateLogger();
builder.Logging.AddSerilog(logger);

I also installed the Nuget Packages: Serilog, Serilog.AspNetCore and Serilog.Sinks.File

In my Controller's constructor I provide the logger, this way I can use the logger throughout the Controller:

private readonly ILogger<ExampleController> _logger;

public ExampleController(ILogger<ExampleController> logger)
{
    _logger = logger;
}

Now whenever I log an exception I call _logger.LogError(ex.Message); and this error will be written in the logger file, which is defined in appSettings.json

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.