簡體   English   中英

如何禁用 Serilog 以記錄一個異常?

[英]How to disable Serilog to log one exception?

(Asp.Net core 3.1/.Net 6)我需要在 Asp.Net 應用程序(由其他人構建)中禁用異常TaskCanceledException的 ERR 日志記錄。 我使用以下中間件來抑制 TaskCanceledException

app.UseMiddleware<TaskCanceledMiddleware>();

public class TaskCanceledMiddleware
{
    private readonly RequestDelegate _next;

    public TaskCanceledMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (TaskCanceledException)
        {
            // Set StatusCode 499 Client Closed Request
            logger.WARN("...")
            context.Response.StatusCode = 499;
        }
    }
}

我可以在日志中看到 WARN 日志。 但是,我仍然可以通過Serilog.AspNetCore.RequestLoggingMiddleware找到以下錯誤消息? (注意錯誤級別是EROR

2022-07-06 07:30:40.6636|116344477|EROR|Serilog.AspNetCore.RequestLoggingMiddleware|HTTP "GET" "/api/v1/myurl" responded 500 in 23213.3233 ms
System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at ....

為什么使用app.UseMiddleware<TaskCanceledMiddleware>()后, TaskCanceledException仍然報錯? (順便說一句,EROR 級別是多少?不應該是 ERR 嗎?)

你知道異常是在哪里拋出的嗎? 也許它不會在 asp.net 核心動作執行管道(中間件工作的地方)內拋出。 您可以注冊一個過濾器來攔截.AddControllers()注冊中的應用程序范圍的異常,如下所示:

 _ = services
        .AddControllers(options =>
        {
            //Global filters
            _ = options.Filters.Add<ApiGlobalExceptionFilterAttribute>();
            ///...omissis...
        })

這里有一個簡單的異常過濾屬性實現:

public sealed class ApiGlobalExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly ILogger<ApiGlobalExceptionFilterAttribute> _logger;

    public ApiGlobalExceptionFilterAttribute(ILogger<ApiGlobalExceptionFilterAttribute> logger)
    {
        _logger = logger;
    }

    public override void OnException(ExceptionContext context)
    {
        var request = context.HttpContext?.Request;

        if (context.Exception is TaskCanceledException tcExc)
        {
            // Set StatusCode 499 Client Closed Request
            _logger.WARN("...");
            context.Result = new ErrorActionResult(499);
        }
        else
        {
            //TODO: manage errors
        }

        context.ExceptionHandled = true;

        base.OnException(context);
    }
}

internal class ErrorActionResult : IActionResult
{
    [JsonIgnore]
    public int StatusCode { get; private set; }

    public ErrorActionResult(int statusCode)
    {
        StatusCode = statusCode;
    }

    public async Task ExecuteResultAsync(ActionContext context)
    {
        var error = new
        {
            Code = StatusCode,
            Message = "Internal server error"
        };

        var objectResult = new ObjectResult(error)
        {
            StatusCode = StatusCode
        };

        await objectResult.ExecuteResultAsync(context);
    }
}

context.ExceptionHandled = true; 停止異常在管道內傳播。

希望能幫助到你!

您可以嘗試排除此類特定異常的日志記錄。

new LoggerConfiguration()
       ....
       .Filter.ByExcluding(logEvent => logEvent.Exception != null && logEvent.Exception.GetType() == typeof(TaskCanceledException))
       ...CreateLogger();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM