So I've recently started to build a asp.net core application and for the logging i'm using SeriLog. This was working fine until recently I found out that most of the time the stacktrace of an exception is not being transferred to my logs. I'm using the .WriteTo.RollingFile() method to write to a .txt file in my LoggerConfiguration in Startup.cs like so
public void ConfigureServices(IServiceCollection services)
{
//add a bunch of services
services.AddLogging(builder =>
{
builder.AddConsole();
builder.AddDebug();
var logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.WithExceptionDetails()
.WriteTo.RollingFile(Configuration.GetValue<string>("LogFilePath") + "-{Date}.txt", LogEventLevel.Information,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}) {Message}{NewLine}{Exception}")
.CreateLogger();
builder.AddSerilog(logger);
});
services.AddMvc();
}
And in my loggerFactory I added the Serilog with this line of code
loggerFactory.AddSerilog();
My BuildWebHost method does not have the .UserSerilog() and looks like this:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
This method gets called as the last step in my Main
method in Program.cs
Reading Serilog's documentation the {Exception} in the outputTemplate of the RollingFile should also log the stacktrace of the exception. However when for example I log an error like so (using the Microsoft.Extensions.Logging.ILogger
)
_log.LogError("Exception thrown when trying to convert customer viewmodel to model or getting data from the database with id: " + id, ex);
This logs:
2017-12-12 10:59:46.871 +01:00 [Error] (ProjectName.Controllers.CustomersController) Exception thrown when trying to convert customer viewmodel to model or getting data from the database with id: 137dfdc1-6a96-4621-106c-08d538a26c5b
It does not have a stacktrace. But when for example I forget to inject a class into the constructor of a class through constructor injection from my .addServices it does log the stacktrace. For example:
2017-12-12 11:03:23.968 +01:00 [Error] (Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware) An unhandled exception has occurred while executing the request
System.InvalidOperationException: Unable to resolve service for type 'TypeName' while attempting to activate 'ProjectName.Controllers.CustomersController'.
at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
How do I get the stacktrace to show up in my logging .txt file?
Debug(exception, "This is an {Exception} text", exception); logger. Debug(exception, "This is an {@Exception} structure", exception); The first line causes the logger to log an exception as plain text (by calling ToString()), and the second line causes the logger to write exception properties as separate fields.
Create a Console Application project in Visual Studio. Install Serilog and its dependencies. Create and configure the Serilog global logger. Integrate the logger into the C# Console Application.
Serilog is a third-party, open-source library that integrates nicely with ASP.NET Core and allows developers to easily log-structured event data to the console, to files, and various kinds of log targets.
In ASP.NET Core, logging providers store the logs. You can configure multiple logging providers for your application. The default ASP.NET Core configures the following logging providers: Console, Debug, EventSource, and EventLog (on Windows).
LogError
extension method has following overrides:
public static void LogError(this ILogger logger, Exception exception, string message, params object[] args);
public static void LogError(this ILogger logger, string message, params object[] args);
When you call
_log.LogError("Exception thrown when trying to convert customer viewmodel to model or getting data from the database with id: " + id, ex);
you actually use the second one and ex
object is passed just as parameter for formatting. As far as your message does not have formatting items, passed exception is just ignored.
To fix the problem just switch arguments in your call, exception should be the first:
_log.LogError(ex, "Exception thrown when trying to convert customer viewmodel to model or getting data from the database with id: " + id);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With