2011-12-22 28 views
11

मैं log4net में एक और सशर्त फ़िल्टर लिखने के लिए संघर्ष कर रहा हूं।log4net फ़िल्टर - लॉग संदेशों को अनदेखा करने के लिए कैसे लिखें और फ़िल्टर करें

<logger name="*" minlevel="Info" xsi:type="NLogLoggerRule" writeTo="FooLogger" > 
    <filters> 
    <when condition="equals('${event-context:item=UserID}', 'TESTUSER') 
       and equals('${event-context:item=URL}','/foo/foobar.aspx')" 
      action="Ignore" /> 
    </filters> 
</logger> 

मुझे यकीन है कि कैसे log4net में एक ही फिल्टर लिखने के लिए नहीं कर रहा हूँ: यह nLog किया गया था, मैं इसे इस तरह से लिखा जा सकता था। मैं अब तक सफल रहे हैं, एक भी शर्त लिखित रूप में:

<appender> 
    .... 
    <filter type="log4net.Filter.PropertyFilter"> 
     <key value="URL" /> 
     <stringToMatch value="/foo/foobar.aspx" /> 
     <acceptOnMatch value="false" /> 
    </filter> 
</appender> 

मैं कैसे लिख सकता हूँ और शर्तों log4net फ़िल्टर का उपयोग कर सकते हैं? कृपया मदद करे।

उत्तर

21

एक कस्टम फ़िल्टर समर्थन और शर्तों। यह वर्ग फ़िल्टर प्रॉपर्टी का खुलासा करता है, इसलिए मौजूदा लॉग 4नेट फ़िल्टर का उपयोग यहां किया जा सकता है और यदि आवश्यक हो तो कोई भी घोंसला और स्थितियां रख सकता है।

public class AndFilter : FilterSkeleton 
{ 
    private bool acceptOnMatch; 
    private readonly IList<IFilter> filters = new List<IFilter>(); 

    public override FilterDecision Decide(LoggingEvent loggingEvent) 
    { 
     if (loggingEvent == null) 
      throw new ArgumentNullException("loggingEvent"); 

     foreach(IFilter filter in filters) 
     { 
      if (filter.Decide(loggingEvent) != FilterDecision.Accept) 
       return FilterDecision.Neutral; // one of the filter has failed 
     } 

     // All conditions are true 
     if(acceptOnMatch) 
      return FilterDecision.Accept; 
     else 
      return FilterDecision.Deny; 
    } 

    public IFilter Filter 
    { 
     set { filters.Add(value); } 
    } 

    public bool AcceptOnMatch 
    { 
     get { return acceptOnMatch;} 
     set { acceptOnMatch = value;} 
    } 
} 

कॉन्फ़िग:

<filter type="Namespace.AndFilter, Assembly"> 
    <filter type="log4net.Filter.PropertyFilter"> 
    <key value="URL" /> 
    <stringToMatch value="/foo/foobar.aspx" /> 
    </filter> 
    <filter type="log4net.Filter.PropertyFilter"> 
    <key value="UserID" /> 
    <stringToMatch value="TESTUSER" /> 
    </filter> 
    <acceptOnMatch value="false" /> 
</filter> 
+1

हाँ, मैं कंपाउंड फ़िल्टर (जैसे आपके एडफिल्टर) के साथ आया था, लेकिन यह नहीं लगा कि कॉन्फ़िगरेशन के माध्यम से आंतरिक फ़िल्टर कैसे जोड़ना है। यह वास्तव में अच्छी चाल है :) सार्वजनिक IFilter फ़िल्टर {सेट {filter.Add (मान); }} –

+2

धन्यवाद, मदद की। यह दयालु है कि यह मानक लॉग 4नेट सुविधा नहीं है। –

7

आप के लिए अपने व्यापार की जरूरत है कस्टम फ़िल्टर बना सकते हैं:

public class UserRequestFilter : FilterSkeleton 
{ 
    public override FilterDecision Decide(LoggingEvent loggingEvent) 
    { 
     if (loggingEvent == null) 
      throw new ArgumentNullException("loggingEvent"); 

     string userId = (string)loggingEvent.Properties["UserId"]; 
     string url = (string)loggingEvent.Properties["Url"]; 

     if (String.IsNullOrEmpty(UserId) || String.IsNullOrEmpty(Url)) 
      return FilterDecision.Neutral; 

     if (UserId.Equals(userId) && Url.Equals(url, StringComparison.CurrentCultureIgnoreCase)) 
      return AcceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny; 

     return FilterDecision.Neutral; 
    } 

    public bool AcceptOnMatch { get; set; } 
    public string UserId { get; set; } 
    public string Url { get; set; } 
} 

विन्यास इस तरह दिखेगा:

<filter type="Namespace.UserRequestFilter, Assembly"> 
    <userId value="TESTUSER"/> 
    <url value="/foo/foobar.aspx"/> 
    <acceptOnMatch value="true"/> 
</filter> 

इसके अलावा, आप यौगिक फ़िल्टर बना सकते हैं, लेकिन मैं उपयोग करने के लिए जिस तरह से नहीं मिला यह विन्यास में है। ऐसा लगता है कि यह केवल प्रोग्राम के रूप में (जो^_^बेकार है) संलग्न किया जा सकता है:

IAppenderAttachable logger = (IAppenderAttachable)_log.Logger; 
AppenderSkeleton appender = (AppenderSkeleton)logger.GetAppender("appenderName"); 
CompoundFilter compoundFilter = new CompoundFilter(); 
compoundFilter.AddFilter(new PropertyFilter() { Key = "UserId", StringToMatch = "TEST" }); 
compoundFilter.AddFilter(new PropertyFilter() { Key = "Url", StringToMatch = @"/foo/foobar.aspx" }); 
appender.AddFilter(compoundFilter); 
logger.AddAppender(appender); 

[अद्यतन]

यहाँ चाल है कि आप उपयोग कर सकते हैं - फिल्टर बनाने के लिए, जो फिल्टर नीचे सभी फिल्टर की जाँच करेगा श्रृंखला:

public class DenyAllSubsequentFilter : FilterSkeleton 
{ 
    public override FilterDecision Decide(LoggingEvent loggingEvent) 
    { 
     IFilter nextFilter = Next; 
     if (nextFilter == null) 
      return FilterDecision.Accept; 

     while (nextFilter != null) 
     { 
      if (nextFilter.Decide(loggingEvent) != FilterDecision.Deny) 
       return FilterDecision.Accept; 

      nextFilter = nextFilter.Next; 
     } 

     return FilterDecision.Deny; 
    } 
} 

उपयोग:

<filter type="Namespace.DenyAllSubsequentFilter, Assembly"/> 
<filter type="log4net.Filter.PropertyFilter"> 
    <key value="UserId" /> 
    <stringToMatch value="TEST" /> 
    <acceptOnMatch value="false" /> 
</filter> 
<filter type="log4net.Filter.PropertyFilter"> 
    <key value="Url" /> 
    <stringToMatch value="/foo/foobar.aspx" /> 
    <acceptOnMatch value="false" /> 
</filter> 

इस फिल्टर लॉगिंग संदेश अगर सब सु इनकार करेगा बाद के फिल्टर इसे अस्वीकार कर देंगे।

+0

धन्यवाद @lazyberezovsky! असल में, मैं अंतर्निर्मित फ़िल्टर की तलाश में था जो समर्थन और शर्तों का समर्थन करता है। लेकिन, यह समझने के बाद कि log4net एक का समर्थन नहीं करता है, मैंने एक कस्टम एंडफिल्टर लिखा जो हमारे लिए काम करता था। मैं दूसरों के लाभ के लिए कोड साझा करूंगा: –