.NET Core logging questions

I’ve been upgrading several projects and I’ve noticed that the recommended logging solution with .NET core is to use its own logging abstraction rather than the ServiceStack logging.

My projects used to use Serilog through the ServiceStack.Logging but I’d like to tidy up my code and get it up to date since I’ve made the move to NET 6.0 (great job by the way!)

My question is what’s the best way to achieve console logging with a selfhost ServiceStack project, I seem to be getting confused between the NET Core and ServiceStack logging solutions especially with the old code making things confusing.

My Program.cs has the following startup code:

Log.Logger = new LoggerConfiguration()
  .Enrich.FromLogContext()
  .WriteTo.Console()
  .MinimumLevel.Is(LogEventLevel.Debug)
  .CreateLogger();

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
  ApplicationName = typeof(Program).Assembly.FullName,
  ContentRootPath = Directory.GetCurrentDirectory(),
  EnvironmentName = Debugger.IsAttached ? Environments.Development : Environments.Production,
  WebRootPath = "wwwroot"
});
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
builder.Host.UseSerilog();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
  app.UseExceptionHandler("/Error");
  app.UseHsts();
  app.UseHttpsRedirection();
}
else
{
  app.UseDeveloperExceptionPage();
}

app.Run();

When I’m attempting to log in my AppHost startup code I’m using:

var loggerFactory = app.ApplicationServices.GetRequiredService<ILoggerFactory>();
var _logger = loggerFactory.CreateLogger<AppHost>();
_logger.LogInformation("test");

I’m assuming from reading that I’ll need to add the following code in my service class:

private readonly ILogger<ApiService> _logger;
public ApiService(ILogger<ApiService> logger) => _logger = logger;

Does any of that make sense? Thanks for any help.

Following the Serilog recommended way with .NET Core and just using the ILogger and ILoggerFactory is the best way to go. What you’ve got looks fine.

For logging in your ApiService you could just use property based injection and have something like:

public ILoggerFactory LoggerFactory { get; set; }
private ILogger _logger;
public ILogger Logger => 
    _logger ?? (_logger = LoggerFactory.CreateLogger(typeof(ApiService)));

And freely use Logger in the Service class as needed.

1 Like

Glad to hear I’m on the right track, I don’t seem to be seeing any debug information from Ormlite which I did when using the previous logging setup?

Am I able to use Serilog by utilising .UseSerilog() - it’s quite confusing working out the best way to do this.

You can use OrmLite’s BeforeExecFilter to inspect SQL before they’re executed, which is what PrintSql() uses to print SQL Statements to the Console:

OrmLiteUtils.PrintSql();

Implementation:

public static void PrintSql() => OrmLiteConfig.BeforeExecFilter = 
    cmd => Console.WriteLine(cmd.GetDebugString());

Alternatively you can use BeforeExecFilter as done here to use your preferred logging abstraction of choice.