На моем веб-сайте я интегрирую Serilog, чтобы регистрировать мои ошибки в специальном приемнике. Ведение журнала обогащено LogContext, где необходимо передать некоторые пользовательские свойства. Если я использую Log.Information (), он попадает в мой приемник со свойствами в LogEvent. Так что это прекрасно работает.
Основная цель - объединить систему ведения журнала с промежуточным программным обеспечением обработчика исключений. Таким образом, в обработчике исключений обнаруживается ошибка, которая генерируется из метода контроллера. Где бы я ни разместил _logger.Log () в обработчике исключений, в Sink нет пользовательских свойств. Во время отладки он проходит LogContextFilter до того, как он попадает в Sink, но свойства фильтра не обнаружены.
У кого-нибудь есть идеи?
Запуск
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;
}
}
}