Dans mon site web, j'intègre Serilog pour enregistrer mes erreurs dans un puits personnalisé. La journalisation est enrichie d'un LogContext où certaines propriétés personnalisées doivent être passées. Si j'utilise Log.Information(), il arrive à mon puits avec les propriétés dans le LogEvent. Cela fonctionne donc très bien.
L'objectif principal est de combiner le système de journalisation à un logiciel intermédiaire de gestion des exceptions. Ainsi, dans le gestionnaire d'exception, l'erreur est attrapée, qui est lancée à partir d'une méthode du contrôleur. Partout où je place le _logger.Log() dans le gestionnaire d'exception, aucune propriété personnalisée n'est disponible dans le Sink. Lors du débogage, le filtre LogContextFilter est passé avant d'aller dans le Sink, mais aucune propriété du filtre n'est trouvée.
Quelqu'un a-t-il une idée ?
Démarrage
Log.Logger = new LoggerConfiguration()
.WriteTo.PasSink(new SerLogServiceClient.SerLogServiceClient(new SerLogServiceClientOptions()))
.Enrich.FromLogContext()
.CreateLogger();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddMvcOptions(mo =>
{
mo.Filters.Add(typeof(LogContextFilter));
});
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMiddleware<LogContextMiddleware>();
app.UseErrorHandler(o =>
{
o.ExceptionHandlingPath = "/Home/Error";
o.Context = ExceptionHandler.Context.MVC;
});
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Content")),
RequestPath = "/Content"
});
app.UseAuthentication();
app.UseSession();
//app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
LogContextFilter
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
using (LogContext.Push(
new PropertyEnricher("UserCode", context.HttpContext.User.Claims.FirstOrDefault(s => s.ToString().StartsWith("UserCode"))?.Value),
new PropertyEnricher("Test", "Will this go through?")))
{
await next.Invoke();
}
}
ExceptionHandlerMiddleware
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
}
catch (HttpRequestException hex)
{
//check response naar reynaersexception??
//deserialize naar re
throw new NotSupportedException(); //als test
}
catch (Exception ex)
{
if (context.Response.HasStarted)
{
throw ex;
}
_logger.LogError(ex.Message);
var originalPath = context.Request.Path;
try
{
if (_options.Context == Context.MVC)
{
context.Response.Clear();
context.Response.StatusCode = 500;
context.Response.OnStarting(Callback, context.Response);
//set features
var exceptionHandlerFeature = new ReynaersExceptionHandlerFeature()
{
Error = ex,
Path = context.Request.Path.Value,
};
context.Features.Set<IExceptionHandlerFeature>(exceptionHandlerFeature);
context.Features.Set<IExceptionHandlerPathFeature>(exceptionHandlerFeature);
//continue lifecycle with updated context
if (_options.ExceptionHandlingPath.HasValue)
{
context.Request.Path = _options.ExceptionHandlingPath;
}
await _next.Invoke(context);
}
}
catch (Exception ex2)
{
// Suppress secondary exceptions, re-throw the original.
Log.Error(ex2.Message);
context.Request.Path = originalPath;
throw ex;
}
}
}