Reputation: 175
In my .NET Core 3.1 project, I have installed Serilog and tried to follow all of the implementing details but for some reason it is not logging into a SQL Server table.
Here is the code - Web API program:
public class Program
{
public static void Main(string[] args)
{
try
{
var iWebHost = CreateHostBuilder(args).Build();
var path = Directory.GetCurrentDirectory();
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
var configuration = new ConfigurationBuilder()
.SetBasePath(path)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{environmentName}.json", optional: true)
.Build();
var logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.ReadFrom.Configuration(configuration)
.CreateLogger();
Log.Logger = logger;
iWebHost.Run();
}
catch (Exception exception)
{
Log.Fatal(exception, "Error starting");
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog();
}
appsetting.json and appsettings.development.json
{
"Serilog": {
"Using": [ "Serilog.Sinks.MSSqlServer" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning"
},
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Server=localhost; Initial Catalog=GP; User ID=lc; Password=lc",
"tableName": "Log"
}
}
]
}
}
}
Here is my main controller
public class MainController : ControllerBase
{
private readonly ILogger<MainController> _logger;
public MainController(ILogger<MainController> logger)
{
_logger = logger;
}
}
And here is the controller that I want to write logs from:
public async Task<ResponseBase> GetAsync(RequestBase request)
{
_logger.LogInformation("in controller");
// other code
// return;
}
Here is my log entity
public class Log
{
public int Id { get; set; }
public string Message { get; set; }
public string MessageTemplate { get; set; }
public string Level { get; set; }
public DateTimeOffset TimeStamp { get; set; }
public string Exception { get; set; }
public string Properties { get; set; }
public string LogEvent { get; set; }
}
Upvotes: 2
Views: 6015
Reputation: 131374
Your code calls UseSerilog()
before Serilog's configuration. This means the application ends up with a default, unconfigured logger. You can avoid this by configuring Serilog using inline initialization with the UseSerilog
overload that provides access to the HostingContext. From the linked docs:
.UseSerilog((hostingContext, services, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console())
This reads Serilog's settings from configuration and adds a Console logger, ensuring you'll get log messages even if the configuration is incorrect.
There's no reason to create the configuration separately. CreateDefaultBuilder()
sets the current directory as the root and adds the appsettings
files. To extend this, use ConfigureHostConfiguration
or ConfigureAppConfiguration
after CreateDefaultBuilder()
.
CreateHostBuilder
should change to :
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog((hostingContext, services, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console());
and Main
to just :
public static void Main(string[] args)
{
CreateHostBuilder(args).Run();
}
If you want to use the logger before building the host, you should create it before calling UseSerilog()
:
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.ReadFrom.Configuration(configuration)
.WriteTo.Console()
.CreateLogger();
try
{
CreateHostBuilder(args).Run();
}
catch (Exception exception)
{
Log.Fatal(exception, "Error starting");
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog()
Upvotes: 2