Мой Logging настроен на использование разных TraceSource для каждого Class.

Можно ли настроить подстановочный знак, который записывает события для всех источников?

<system.diagnostics>
  <sources>
    <source name ="wildcard" switchValue="Warning">
      <listeners>
        <add name="textlog" />
      </listeners>
    </source>
    <source name="MySpecificClass" switchValue="All">
      <listeners>
        <add name="textlog" />
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="textlog"
         type="System.Diagnostics.TextWriterTraceListener"
         initializeData="Log.log">
    </add>
  </sharedListeners> 
  <trace autoflush="true"/>
</system.diagnostics>
6
Jos Vinke 21 Мар 2013 в 21:25

1 ответ

Лучший ответ

Я не знаю встроенного способа сделать это автоматически. Однако, если вы посмотрите на TraceLogger в репозитории Castle Git, вы увидите, что они, по сути, обернули и расширили TraceSource для поддержки «иерархического» именования.

https://github.com/castleproject/Core/blob/master/src/Castle.Core/Core/Logging/TraceLogger.cs

Я бы скопировал код здесь, но было бы неправильно просто вырезать и вставить этот код в SO.

Я могу объяснить, как идеи, представленные в классе, могут сработать для вас (без использования Castle)

По сути, в вашем клиентском коде (который хочет регистрировать данные) вы должны создать экземпляр своего «регистратора» (а не TraceSource). В качестве входных данных для регистратора вы должны указать, например, полное имя класса. Внутри конструктора используйте имя входа, чтобы попытаться разрешить TraceSource. Если существует TraceSource, настроенный с этим именем, используйте этот TraceSource для выполнения работы. Если нет, обрежьте крайнюю правую часть полного имени. Попробуйте разрешить TraceSource с этим именем. Если существует TraceSource, настроенный с этим именем, используйте его. И так далее. Если вы не найдете никаких источников трассировки, не регистрируйте ничего из своего "регистратора". Вы можете добавить возможность распознавания TraceSource, который был настроен с использованием подстановочного имени («»). Если вы никогда не найдете TraceSource, используя технику обрезки имен, и если есть «» TraceSource, используйте «*» TraceSource в качестве запасного варианта.

Итак, у вас может быть что-то вроде этого:

class MyTraceSource
{
  private TraceSource ts;

  public MyTraceSource(string name)
  {
    ResolveTraceSource(name);
  }

  private void ResolveTraceSource(string name)
  {
    //Check for a configured TraceSource from most qualified name (as input) to least qualified ("").
    //Assume name like this:  Namespace1:Namespace2:Class
    //Try to resolve:
    // TraceSource("Namespace1.Namespace2.Class");
    // TraceSource("Namespace1.Namespace2");
    // TraceSource("Namespace1");
    //If you still haven't found one, try to resolve
    // TraceSource("*");
  }

  //Implement either TraceSource API, or whatever API you prefer for logging.

}

Я сам делал что-то подобное как часть прототипа (который мы в итоге не использовали), и это сработало очень хорошо, имитируя способ указания регистраторов в log4net и NLog.

Удачи!

4
wageoghe 29 Мар 2013 в 23:50
Спасибо, этот ответ потрясающий. Я уже сделал почти то же самое, что вы предложили. Я дал регистратору полное имя класса и попытался разрешить сборку. Затем я использовал имя сборки в качестве источника журнала. (Так что у меня были разные исходники для всех моих сборок). Но я никогда не думал о создании собственного исходного кода с подстановочными знаками. Также я думаю, что ваш способ решения более гибок и, вероятно, быстрее. Спасибо, мне не составит труда реализовать это, очень полезно!
 – 
Jos Vinke
30 Мар 2013 в 15:14