Фильтрация log4net по имени метода - не совсем понятно - PullRequest
7 голосов
/ 14 апреля 2010

Я использую log4net для регистрации прогресса моего веб-приложения, используя Log4PostSharp для AOP-injectify всех методов. Это дает желаемый эффект регистрации (почти) всего и хорошо.

Теперь у меня есть требование записать методы JUST Page_Load в файл / консоль. Я, очевидно, могу сделать это для класса log4postsharp, но тогда я потеряю все остальные записи.

Я просматривал фильтры в log4net, начиная с фильтра StringMatch, но он просматривает только регистрируемое сообщение, а я нахожусь после имени метода. Это поместило меня в PropertyFilter, но все еще без радости. Мой фрагмент log4net.config выглядит так:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <filter type="log4net.Filter.PropertyFilter">
    <key value="LocationInfo.MethodName"/>
    <stringToMatch value="Page_Load"/>
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <file value="d:\\xxxx\\yyyyy\\zzzzLog"/>

Как видите, я пытаюсь ввести MethodName события регистрации через LocationInfo, но я все еще регистрирую все. РЕДАКТИРОВАТЬ: Как уже упоминалось в комментариях, я теперь включил DenyAllFilter, который я добавил после RTFM; -)

Кто-нибудь может помочь?

Спасибо,

Майк К.

1 Ответ

4 голосов
/ 02 мая 2010

Насколько я могу судить, log4net не знает свойства LocationInfo.MethodName . Я не использую Log4PostSharp, поэтому я не могу точно сказать, будет ли Log4PostSharp создавать это свойство.

Я бы написал свой собственный фильтр для фильтрации по именам методов (регулярное выражение пропущено):

public class MethodNameFilter : StringMatchFilter
{       
     override public FilterDecision Decide(LoggingEvent loggingEvent) 
     {
         if (loggingEvent == null)
         {
              throw new ArgumentNullException("loggingEvent");
         }

         var locationInfo = loggingEvent.LocationInformation;

         // Check if we have been setup to filter
         if (locationInfo == null || (m_stringToMatch == null && m_regexToMatch == null))
         {
             // We cannot filter so allow the filter chain
             // to continue processing
              return FilterDecision.Neutral;
         }

         if (m_stringToMatch != null)
         {
             // Check substring match
             if (locationInfo.MethodName.IndexOf(m_stringToMatch) == -1) 
             {
                  // No match, continue processing
                  return FilterDecision.Neutral;
             }

             // we've got a match
             if (m_acceptOnMatch) 
             {
                  return FilterDecision.Accept;
             } 
             return FilterDecision.Deny;
         }
         return FilterDecision.Neutral;
    }
} 

Примечание. Доступ к LocationInfo стоит дорого и может заметно повлиять на производительность. Вы можете изменить Log4PostSharp, чтобы извлечь имя метода во время плетения и сохранить его в каком-либо свойстве. В этом случае вы можете использовать фильтр свойств по своему усмотрению, и это не повлияет на производительность. Не уверен, что это действительно работает, но я ожидаю, что это возможно.

Конфигурация будет выглядеть примерно так:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
     <filter type="YourNameSpace.MethodNameFilter">
         <stringToMatch value="Page_Load"/>
     </filter>
     <filter type="log4net.Filter.DenyAllFilter" />
     <file value="d:\\xxxx\\yyyyy\\zzzzLog"/>
...