2016-01-17 6 views
1

Доступ к API для API для разных типов пользователей. Существуют внешние приложения и пользователи через веб-интерфейс.Serilog: протоколирование различных типов событий журнала

Я попытаюсь объяснить с помощью примера: Итак, в вызове метода я хотел бы указать, кто или что обратился к нему.

В случае внешнего приложения я хотел бы зарегистрировать что-то вроде этого (используя шаблон): «[{Caller}] {Метка времени: HH: mm: ss} [{Level}] (RequestId: {RequestId } | Ключ: {Key} | AppVersion: {Version}) {Message} {NewLine} {Exception} "

, а в случае действия с пользователем, я хотел бы зарегистрировать что-то вроде: " [{Caller }] {Метка времени: HH: mm: ss} [{Level}] FullName: {FullName} | Организация: {Организация} | AppVersion: {Версия}) {Сообщение} {NewLine} {Исключение} "

Оба типа вызывающих вызов метода доступны из Thread.CurrentPrincipal.Identity, но каждый из них реализует различный тип идентификации, h различные пользовательские свойства.

Мой код будет выглядеть следующим образом:

public void DoSomething() 
{ 
    Log.Information("DoSomething called"); 
} 

Если я регистратор настроен что-то вроде:

var logger = new LoggerConfiguration() 
        .Enrich.WithProperty("Version", appVersion) 
        .Enrich.WithProperty("Caller", caller) 
        .Enrich.With(new MyEnricher()) 
        .WriteTo.ColoredConsole(outputTemplate: "[{Caller}] {Timestamp:HH:mm:ss} [{Level}] FullName:{FullName} | Organization:{Organization} | AppVersion:{Version}) {Message}{NewLine}{Exception}") 
        .CreateLogger(); 

она никогда не будет отображаться ключ и RequestID, при вызове вызвано внешним приложением (тождественное нить).

Я добавил MyEnricher к регистратору, и это что-то вроде:

public class MyEnricher : ILogEventEnricher 
{ 
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 
    { 
     var identity = Thread.CurrentPrincipal.Identity; 
     if (identity is ExternalIdentity) 
     { 
      var externalIdentity = Thread.CurrentPrincipal.Identity as ExternalIdentity; 
      logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Key", externalIdentity.Key)); 
      logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("RequestId", externalIdentity.RequestId)); 
     } 
     else 
     { 
      var userIdentity = Thread.CurrentPrincipal.Identity as UserIdentity; 

      logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("FullName", userIdentity.FullName)); 
      logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("Organization", userIdentity.OrganizationName)); 
     } 
} 

Насколько я смог понять из документации и примеров в Интернете, регистрация шаблон устанавливается только в момент настраиваемой регистраторе , до его фактического создания. Я не смог получить доступ к шаблону и модифицировать его, используя LogEvent, поскольку он доступен только для чтения (только для getter).

Я знаю о возможном форматировании сообщений, но это не то, что я ищу в этом конкретном случае.

Конечный результат я хотел бы видеть в журналах, для внешнего доступа приложение является что-то вроде:

17 Jan +2016 10: 11: 42.524 [API] 10:11:40 [Информация] (RequestID: 123 | Key: XXX-1 | AppVersion: 1.2.1) DoSomething называется

и при входе для пользователя:

17 января 2016 11: 12: 42,524 [WEB] 11: 12:40 [Информация] (FullName: Anonymous | Организация: MyOrg | AppV : 1.2.1) DoSomething под названием

Мой вопрос: как (если возможно) могу ли я регистрировать (и просматривать его в журналах) различные типы событий с различными свойствами для входа в шаблон? Можно ли манипулировать шаблоном во время выполнения на лету? Я бы не хотел иметь шаблон со всеми возможными токенами из обоих или многих других возможных типов событий, а их свойства определялись в одном месте (многие из них были пустыми в одном случае или в другом).

ответ

2

Если вы можете принять немного другое форматирование из вашего примера, вы можете использовать уничтожение того, здесь:

"[{Caller}] {Timestamp:HH:mm:ss} [{Level}] ({Principal}) {Message}{NewLine}{Exception}"

Затем в обогатителя:

public class MyEnricher : ILogEventEnricher 
{ 
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 
    { 
     var identity = Thread.CurrentPrincipal.Identity; 
     if (identity is ExternalIdentity) 
     { 
      var externalIdentity = Thread.CurrentPrincipal.Identity as ExternalIdentity; 
      logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Principal", new { 
       externalIdentity.Key, 
       externalIdentity.RequestId 
      }, true)); 
     } 
     else 
     { 
      var userIdentity = Thread.CurrentPrincipal.Identity as UserIdentity; 
      logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Principal", new { 
       userIdentity.FullName, 
       userIdentity.OrganizationName 
      }, true)); 
     } 
    } 
} 

(Обратите внимание на true, чтобы вызвать сериализации анонимные объекты.)

Это выдаст различные свойства p rincipal в синтаксисе пары ключевых значений.

В противном случае, используя пользовательский способ ITextFormatter (при использовании кода на Serilog's DisplayFormatter), это путь. ColoredConsole не будет принимать пользовательские форматирования текста, но:

WriteTo.Sink(new RollingFileSink(@"Logs\app-{Date}.txt", formatter)) 

позволит один должен проходить через.

 Смежные вопросы

  • Нет связанных вопросов^_^