Лучший способ обогащения, когда исходный контекст не является указанным значением c - PullRequest
2 голосов
/ 26 апреля 2020

При программном создании LoggerConfiguration для последующего использования я хотел и смог ограничить использование обогащателя для всех значений контекста источника , кроме one (Global.asax со старого веб-сайта веб-форм) .

Но мне кажется, что это уходит (мне не нравится этот Invoke вызов) от того, что я считаю библиотекой Serilog, предназначенной для практики, через довольно приятный и элегантный свободный API:

private static LoggerConfiguration GetBasicLoggerConfig()
{
    return new LoggerConfiguration()
        .MinimumLevel.Debug()
        .Enrich.When(
            logEvent => !Matching.FromSource("ASP.global_asax").Invoke(logEvent),
            enrichmentConfig => enrichmentConfig.WithAnyKindOfEnricher());
}

Я использую эту логику c, чтобы исключить запуск списка обогащателей вне контекста, и хочу, чтобы они выполнялись только в течение жизненного цикла страницы. Но независимо от этого случая, поскольку я собираюсь применить этот подход в других местах, я хочу сохранить его чистым и кратким, и Меня больше всего интересует само понятие - «обогатить, исключив конкретный контекст».

Я искал способы типа WhenNot или NotMatching до express "отрицание" / "исключение" и не смог найти их в библиотеке. Пробовал с другими методами, предложенными stati c class Matching, но безрезультатно. Проект большой, и я хотел бы персонализировать всю регистрацию в зависимости от различных контекстов (поэтому в итоге мы использовали серию Enrich.When() s - и с большим списком обогащений, получая полное дерево конфигурации с несколькими ", исключая только одну части контекста кажутся уродливыми / грязными).

Конечно, централизованное объявление значения по умолчанию для контекста, как в примере ниже, не обрезает его, потому что будут различные контексты, объявленные через .ForContext<T>(), и все они, кроме нужно быть «пойманным» в состоянии для обогащения.

// this does not cut it
return new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.WithProperty(Serilog.Core.Constants.SourceContextPropertyName, "default")
    .Enrich.When(Matching.FromSource("default"),
        enrichmentConfig => enrichmentConfig.WithAnyKindOfEnricher());

Надеюсь, что мне удалось объяснить, чего я пытаюсь достичь. (Имена лямбда-параметров длинные для ясности)

Итак, я что-то упустил или есть другой подход? Как лучше всего достичь этого «обогащения путем исключения»?

более поздние правки: - Забыл упомянуть, что я вхожу только в файлы (используя приемник файлов). - Не желаю интегрировать Seq (я знаю о его преимуществах), по крайней мере, не в ближайшее время.

Ответы [ 3 ]

2 голосов
/ 27 апреля 2020

Serilog.Filters.Expressions лучше для этого:

        // dotnet add package serilog.filters.expressions
        .Enrich.When(
            "SourceContext <> 'ASP.global_asax'"),
            enrichmentConfig => enrichmentConfig.WithAnyKindOfEnricher());
1 голос
/ 28 апреля 2020

Другой подход, который требует немного меньше пользовательского кода, чем мой предыдущий ответ, заключается в использовании функций, предлагаемых Serilog.Filters.Matching.

// snip... probably need some usings for `Serilog.Filters`
// ...

private static bool ShouldEnrichForThisSourceContext(string sourceContext)
{
  // ⚠️ sourceContext is possibly null
  return sourceContext.StartsWith("whatever") || sourceContext.Contains("xxx");
}

private static LoggerConfiguration GetBasicLoggerConfig()
{
    return new LoggerConfiguration()
        .MinimumLevel.Debug()
        .Enrich.When(
            Matching.WithProperty<string>(
              Constants.SourceContextPropertyName, 
              ShouldEnrichForThisSourceContext), 
            enrichmentConfig => enrichmentConfig.WithAnyKindOfEnricher());
}

У меня нет доступа к рабочая. NET IDE прямо сейчас, так что она может не совсем скомпилироваться, но это было бы идеей.

1 голос
/ 27 апреля 2020

⚠️ код ниже упрощен и неверен . на основании комментария Николаса Блюмхардта может потребоваться дополнительная проверка / приведение к нулю если бы мы хотели)


Если вы определяете свою конфигурацию ведения журнала как код (а не из файла JSON или AppSettings), то я бы предложил вам просто написать простой код C#, и сделайте что-то вроде:

private static LoggerConfiguration GetBasicLoggerConfig()
{
    return new LoggerConfiguration()
        .MinimumLevel.Debug()
        .Enrich.When(
            logEvent => logEvent.Properties["SourceContext"].StartsWith("blah")
              //add all the complexity you want in here
              || logEvent.Properties["SourceContext"].EndsWith("foo"), 
            enrichmentConfig => enrichmentConfig.WithAnyKindOfEnricher());
}

Возможно, будет проще express сложных условий, которые вы хотите использовать.

Если вас не устраивает строка magi c "SourceContext", она также доступна в виде константы от Serilog.Core.Constants.SourceContextPropertyName.

Если logEvent.Properties["SourceContext"] кажется немного многословным, вы можете сделать его более читабельным, определив метод расширения , например:

public static string GetSourceContext(this LogEvent logEvent){
 return logEvent.Properties["SourceContext"];
}
...