Как исключить определенные типы исключений из Serilog? - PullRequest
0 голосов
/ 29 августа 2018

Я использую Serilog для регистрации информации о приложении asp.net core 2.1, размещенном в IIS. Когда происходят исключения, мне сообщают по электронной почте. Дело в том, что некоторые исключения случаются, не причиняя вреда приложению вообще, и я не хочу, чтобы меня замечали каждый раз, когда это происходит.

Есть ли способ в Serilog исключить определенный тип исключения из журнала?

РЕДАКТИРОВАТЬ:

Вот как я настроил Serilog в моем Program.cs:

using System;
using System.Data;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Sinks.MSSqlServer;

namespace WindZone_Warehouse_Mobile_App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile(Environment.CurrentDirectory + "/appsettings.json")
                .Build();

            var columnOptions = new ColumnOptions {
                AdditionalDataColumns = new System.Collections.ObjectModel.Collection<DataColumn>
                {
                    new DataColumn {DataType = typeof (string), ColumnName = "email", DefaultValue = "myemail@myemail.com", MaxLength = 4000},
                    new DataColumn {DataType = typeof (string), ColumnName = "subject", DefaultValue = "Application error", MaxLength = 4000},
                }
            };
            columnOptions.Store.Remove(StandardColumn.Level);
            columnOptions.Store.Remove(StandardColumn.LogEvent);
            columnOptions.Store.Remove(StandardColumn.Message);
            columnOptions.Store.Remove(StandardColumn.MessageTemplate);
            columnOptions.Store.Remove(StandardColumn.Properties);
            columnOptions.Store.Remove(StandardColumn.TimeStamp);
            columnOptions.Exception.ColumnName = "message";
            columnOptions.Id.ColumnName = "id";
            columnOptions.DisableTriggers = true;

            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Information)
                .Enrich.FromLogContext()
                .Filter.ByExcluding(ObjectDisposedException) //What is the right way to tell Serilog to ignore this type of exception?
                .WriteTo.RollingFile("logs\\log-{Hour}.txt", retainedFileCountLimit: 168)
                .WriteTo.MSSqlServer(
                connectionString: configuration.GetConnectionString("DefaultConnection"),
                tableName: "emailtosend",
                columnOptions: columnOptions,
                restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error
                )
                .CreateLogger();

            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseSerilog();
    }
}

РЕДАКТИРОВАТЬ 2:

@ reza baiat, @GoldenAge & @Alessandro Di Cicco: Конечно, ваши ответы позволят мне обработать исключения, но только те, которые возникают за пределами регистратора Serilog. Serilog - это библиотека журналов, которая заменяет библиотеку Microsoft по умолчанию и позволяет мне пропустить все Try / Catch внутри остальной части моего кода, поскольку она будет регистрировать их все в (в моем случае) файле журнала и таблице SQL. Я пытаюсь заставить Serilog не регистрировать, например, ObjectDisposedException исключений, которые происходят внутри критического кода. Я думаю, что Try / Catch в моем коде сбивал с толку, поэтому я исключу его из моего примера, так как он не имеет отношения к делу. Serilog будет перехватывать любое исключение, которое выдается после сборки и запуска приложения. Я думал, что это может быть дополнительная строка конфигурации Serilog, как это: .Filter.ByExcluding(ObjectDisposedException) или что-то в этом роде. Возможно ли это?

Спасибо

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Есть ли способ в Serilog исключить определенный тип исключения из быть зарегистрированым?

Я бы просто создал пустой улов для этого конкретного типа исключения и ничего не делал внутри тела, например.

try
{
    // invoke some function/s
}
catch (BlahException)
{
    // do nothing
}
catch (Exception e)
{
    Log.Fatal(ex, "Host terminated unexpectedly");
    // do something
}
finally
{
    Log.CloseAndFlush();
}

Если вы хотите игнорировать больше исключений, я бы создал дополнительную функцию, которая проверяет, хотите ли вы регистрировать этот тип ошибки или нет.

// list of error codes:
// https://docs.microsoft.com/en-gb/windows/desktop/Debug/system-error-codes
public static bool IgnoreError(int errorCode)
{
    switch (errorCode)
    {
        case 16389:
            return true;
        case 16387:
            return true;
        default:
            return false;
    }
}

затем внутри блока catch вы можете передать код исключения этому методу. например,

try
{
    throw new ArgumentNullException("value");
}
catch (Exception e) 
{
    // Using an AND operation will retrieve the error code from the HRESULT:
    if (IgnoreError(e.HResult & 0xFFFF))
    {
        return;
    }
    Log.Fatal(e, "message");
}

Я думаю каждое необработанное исключение должно регистрироваться регистратором, потому что это его главная ответственность . Я не вижу никакого преимущества, чтобы игнорировать запись необработанного исключения, и такой настройки не должно быть, это слишком страшно! Если вы знаете, что исключение может возникнуть в данном месте, вам следует создать блоки try и catch, чтобы перехватить как можно больше ожидаемых исключений. Затем вы можете принять решение, хотите ли вы игнорировать какое-то конкретное исключение или нет в блоке catch.

0 голосов
/ 29 августа 2018

Вы можете использовать HashSet<TypeInfo>, который вы заполняете всеми типами исключений, которые хотите исключить, и затем проверять, содержится ли в нем ваше текущее исключение:

HashSet<TypeInfo> ignore = new HashSet<TypeInfo>();
ignore.Add(typeof(SomeExceptionType).GetTypeInfo());

//Add all the exceptions you want to exclude

Теперь вы можете проверить тип исключения следующим образом:

try {
   //Critical code
}
catch (Exception e) {
    if (!ignore.Contains(e.GetType().GetTypeInfo())) //Do stuff
}

Вам необходимо добавить using System.Reflection, чтобы использовать тип TypeInfo

0 голосов
/ 29 августа 2018

код ниже может помочь вам

catch (Exception ex)
{
    if (ex.GetType() != typeof(ExceptionTypeToExclude) ) {
         Log.Fatal(ex, "Host terminated unexpectedly");
    }
    return;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...