【发布时间】:2018-07-26 20:53:06
【问题描述】:
我已设置 Serilog 以使用以下方式登录到 MSSql:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Information)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Async(x => x.MSSqlServer(logConntectionString, tableName, LogEventLevel.Warning, autoCreateSqlTable: false, columnOptions: columnOptions))
.CreateLogger();
此外,我在管道中添加了一个 SerilogMiddleware,它成功地从HttpContext 添加了LogContext。
在测试控制器中,我有以下两种测试方法:
public class TestController : ControllerBase
{
[HttpGet, Route("test")]
public IActionResult Get() {
try
{
string[] sar = new string[0];
var errorgenerator = sar[2]; // Trigger exception
}
catch (Exception ex)
{
Log.Error(ex, "Caught Exception");
return StatusCode(500, "Custom 500 Error");
}
return Ok();
}
[HttpGet, Route("test2")]
public IActionResult Get2() {
string[] sar = new string[0];
var errorgenerator = sar[2];// Trigger exception
return Ok();
}
}
第一种方法不是 DRY,所以我想处理全局/未捕获的异常,例如方法 2。
我所拥有的from here 是:
public class GloablExceptionFilter : ActionFilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext context)
{
var httpContext = context.HttpContext; // This does not appear to have the actual HttpContext
Log.Error(context.Exception, "Unhandled Exception");
}
}
问题是,我原本可以正常工作的中间件不再起作用。它不会编辑响应正文等。此外,当我访问 ExceptionContext 的 context.HttpContext 时,它不包含从内部触发时的实际 HttpContext控制器方法如上。
- 如何使用此过滤器注入或共享 HttpContext 和/或 LogContext?
- 如果那不可能,我如何在 DRY、 和 有上下文可用的情况下完成日志记录异常?
更新 1:当前的中间件
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddSerilog();
app.UseAuthentication();
// Logging Middleware is just after Authentication, to have access to
// user IsAuthorized, claims, etc..
app.UseMiddleware<SerilogMiddleware>();
app.UseCors("CORSPolicy");
app.UseMvc();
}
在中间件本身:
public class SerilogMiddleware
{
readonly RequestDelegate _next;
public SerilogMiddleware(RequestDelegate next)
{
if (next == null) throw new ArgumentNullException(nameof(next));
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
// Do logging stuff with Request..
await _next(httpContext);
// Do logging stuff with Response but..
// This point is never reached, when exception is unhandled.
}
}
【问题讨论】:
-
您可以考虑使用放置在管道早期的实际中间件,该中间件可以直接访问 htttp 上下文,与稍后进入管道的文件管理器相对。
-
在我给stackoverflow.com/a/44791487/5233410的答案中找到了一个示例
-
@Nkosi - 我添加了中间件代码及其注入顺序以进行演示。我不希望这个问题过于宽泛,或者过于狭隘以至于我无法使用。
-
基于代码 sn-p 当您将上下文传递到管道中时,您不会捕获异常。如果你没有捕捉到异常,那么它就不会到达你的代码。
-
你尝试/捕获中间件中的
await _next(httpContext)- 我明白了;谢谢!做一个答案,如果你愿意,我会标记它:)
标签: asp.net-core exception-handling asp.net-core-2.0 error-logging serilog