2009-01-13 21 views
5

मैं आम तौर पर हर वर्ग में निम्नलिखित की घोषणा:log4net रणनीति?

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
      System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

और प्रत्येक वर्ग के भीतर स्थिर सदस्य का उपयोग विभिन्न स्तरों (जानकारी, डिबग, आदि)

पर लॉग इन करने के मुझे लगता है कि कहीं न कहीं देखा था और किया गया है इसे कुछ हद तक दिमागी तरीके से उपयोग करते हुए, यह तर्क है कि सेटअप नामस्थान द्वारा फ़िल्टर करने में मदद करने के लिए पर्याप्त लचीला है और व्यक्तिगत प्रकार लॉग इन करता है यदि मैं उत्पादन समस्याओं का निवारण करना चाहता हूं और क्या नहीं।

लेकिन मुझे शायद ही कभी ठीक लॉगिंग के "स्तर" का उपयोग करना पड़ा। तो, मैं देखना चाहता हूं कि दूसरे क्या उपयोग कर रहे हैं। क्या आप उपर्युक्त का उपयोग करते हैं, क्योंकि मुझे लगता है कि बहुत से लोग इसका उपयोग कर रहे हैं, या आप नामांकित लॉगर्स जैसे "डीबग", "ट्रेस", "एरर", "मॉड्यूलए" इत्यादि बनाते हैं और लॉगर को विभिन्न प्रकारों में साझा करते हैं विधानसभाएं?

उत्तर

-1

हाल ही में, मैं कुछ इस तरह बनाया:

public static class Logger 
{ 
    private static bool isLoaded = false;  

    public static ILog Log 
    { 
     get 
     { 
      System.Reflection.MethodBase method; 
      method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod(); 
      StringBuilder loggerName = new StringBuilder(); 
      loggerName.AppendFormat("{0}.{1}(", method.ReflectedType.FullName, method.Name); 

      ParameterInfo[] parameters = method.GetParameters(); 
      string[] parametersStr = new string[parameters.Length]; 

      if (parameters.Length > 0) 
      { 
       for (int i = 0; i < parameters.Length; i++) 
       { 
        parametersStr[i] = parameters[i].ToString(); 
       } 
       loggerName.Append(String.Join(", ", parametersStr)); 
      } 

      loggerName.Append(")"); 

      return GetLogger(loggerName.ToString()); 
     } 
    } 


    private static ILog GetLogger(string loggerName) 
    { 
     if (!isLoaded) 
     { 
      log4net.Config.XmlConfigurator.Configure(); 
     } 
     return LogManager.GetLogger(loggerName); 
    } 
} 

यह मुझे हर वर्ग में अपनी उदाहरण बनाकर मैं इसे उपयोग करने की आवश्यकता के बिना log4net का उपयोग करने देता है, और मैं अभी भी वर्ग के नाम और विधि मैं कहाँ कार्रवाई लॉग इन ।

नमूना उपयोग:

Logger.Log.DebugFormat("Response [{0}]", xmlResponse); 
+0

उत्कृष्ट। धन्यवाद। – Chasler

+2

क्या आपने इस पर एक प्रोफाइलर चलाया है? इस जानवर की निष्पादन गति बहुत बड़ी है। और यहां तक ​​कि यदि आप उत्पादन में DEBUG लॉगिंग स्तर को चालू करना चाहते हैं तो भी आपको एक ही लागत लगेगी। अगर आप वास्तव में लॉगर में विधि नाम की आवश्यकता है तो मैं कुछ बिंदु देख सकता हूं लेकिन फिर, जब उदा। अपवाद होते हैं आप अपवाद में उस नाम स्टैकट्रेस वैसे भी ... –

+1

सुंदर यकीन है कि यह काफ़ी नया CallerName विशेषता ने ले जाता है मिलेगा - http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices देखते हैं। callermembernameattribute% 28v = vs.110% 29.aspx – keithl8041

2

यह अपने मूल तरीका कर की लागत Ilog कार्यान्वयन और समय इसे चलाने के लिए "। System.Reflection.MethodBase.GetCurrentMethod() DeclaringType" लेता है पर का एक उदाहरण है चालू होना।

मुझे कुछ साल पहले इसे याद रखना याद है, और हमारी स्टार्टअप लागत प्रति 10000 कक्षाओं के 1 सेकंड के क्रम में थी, और प्रति 10k कक्षाओं में मेगाबाइट से कम थी।

इतनी कम लागत को देखते हुए, मैंने कभी अविश्वसनीय लचीलापन log4net प्रदान नहीं किया है।

नोट: मैं अन्य समाधान पर यहाँ टिप्पणी कर सकते हैं नहीं के रूप में मैं नया हूँ .. लेकिन इस लाइन:।

विधि = नए System.Diagnostics.StackTrace() GetFrame (1) .GetMethod ();

महंगा, खासकर अगर प्रत्येक लॉग संदेश के लिए बुलाया जाता है।

0

एक उपकरण जिसे आप लॉगिंग के साथ उपयोग कर सकते हैं PostSharp (http://www.postsharp.org/) है। एक भुगतान और एक मुक्त (एक्सप्रेस) संस्करण है। मैंने केवल विधि सीमाओं को लॉग करने के लिए इसका उपयोग किया है, लेकिन मुझे पता है कि आप इसे त्रुटि-हैंडलिंग के लिए भी उपयोग कर सकते हैं। दोनों के बीच, यह प्रत्येक वर्ग में कोड लिखने के बिना आपकी अधिकांश लॉगिंग आवश्यकताओं का ख्याल रखेगा।

11

मैं मूल रूप से

public class MyClass 
{ 
    private static readonly ILog log = Log.Get<MyClass>(); 
} 

जहां Log.Get एक वर्ग मूल रूप से इस आंतरिक रूप से

return LogManager.GetLogger(typeof(T)); 

स्टार्टअप लागत क्लीनर imo के रूप में जिस तरह से साथ ही प्रतिबिंब से भी छोटा होता है करता है वह यह है कि का उपयोग करें।

अद्यतन: निर्भरता इंजेक्शन, इकाई परीक्षण और नकली के साथ बाद के वर्षों में मेरे अनुभव को देखते हुए, मैं अब कह सकता कि मैं दृष्टिकोण ऊपर उल्लिखित नज़रअंदाज़।दृष्टिकोण (मेरी और ओपी दोनों की) के साथ समस्या यह है कि कोड के पास के बारे में स्पष्ट ज्ञान है कि लॉग इंस्टेंस बनाया गया है। वहाँ एक नकली एक के साथ ILog उदाहरण की जगह का कोई आसान तरीका है:

एक एक तरफ, इस युग्मन यह मुश्किल बना देता है परीक्षण करने के लिए वृद्धि हुई है। दूसरी तरफ, मेरे Log वर्ग में किए गए परिवर्तन से इसका उपयोग करने वाले सभी वर्गों में परिवर्तनों का कारण बन जाएगा।

इसलिए मैं इंजेक्शन लगानेILog उदाहरण है, आमतौर पर निर्माता इंजेक्शन के जरिए का तरीका अपनाते हैं, और आउटसोर्स कैसे my DI framework of choice करने के लिए एक लकड़हारा निर्माण करने के लिए:

public class MyClass 
{ 
    readonly ILog _log; 

    public class MyClass(ILog log) 
    { 
     _log = log; 
    } 
} 

यह उचित decoupling के लिए अनुमति देता है। कोड को अब यह जानने की आवश्यकता नहीं है कि लॉगर्स कैसे बनाए जाते हैं। अधिकांश निर्भरता इंजेक्शन ढांचे का मतलब इंजेक्शन वाले प्रकार को देखने और उसके बाद लॉग इंस्टेंस बनाने के लिए उपयोग करना है। यहां एक approach for log4net and Autofac है।

+0

क्या लाभ इस 'LogManager.GetLogger (typeof (MyClass))' 'ILog' उदाहरण है जब हो रही का उपयोग करने पर देता है? – MarioVW

+1

छोटा, क्लीनर कोड। लेकिन मुझे इस जवाब को संशोधित करना चाहिए क्योंकि आजकल, मैं निर्भरता इंजेक्शन का उपयोग करता हूं और डी ढांचे को लॉगर का निर्माण करने देता हूं। –