2012-12-12 15 views
5

मैं विंडसर लॉगिंग सुविधा और एनएलओजी एकीकरण का उपयोग कर किसी प्रोजेक्ट में लॉगिंग जोड़ने पर काम कर रहा हूं।विंडसर लॉगिंग सुविधा: नियंत्रण लॉग नाम

विंडसर दस्तावेज के Log संपत्ति को प्रत्येक वर्ग में जोड़ने के लिए अनुशंसित अभ्यास करने के बजाय, जिसे मैं लॉगिंग का समर्थन करना चाहता हूं, मैंने इसे करने के लिए गतिशील अवरोध का उपयोग करने का मार्ग तय करने का निर्णय लिया है। अभी तक इंटरसेप्टर काफी बुनियादी है; यह सिर्फ ILogger का एक उदाहरण प्राप्त करने के लिए निर्माता इंजेक्शन का उपयोग करता है:

class LoggingInterceptor : IInterceptor 
{ 
    private readonly ILogger _logger; 
    public LoggingInterceptor(ILogger logger) 
    { 
     if (logger == null) throw new ArgumentNullException("logger"); 
     _logger = logger; 
    } 

    public void Intercept(IInvocation invocation) 
    { 
     // just a placeholder implementation, I'm not actually planning to do this ;) 
     _logger.Info(invocation.Method.Name); 
     invocation.Proceed(); 
    } 
} 

इसके अलावा, सभी मेरे द्वारा की गई इंटरसेप्टर दर्ज की और एक घटक के लिए इसे लागू करने के लिए कम से कम है, और लॉगिंग सुविधा बाकी का ख्याल रखता है ।

container.Register(Component.For<LoggingInterceptor>().LifeStyle.Transient); 

container.Register(
    Component.For<IEmployeeRepository>() 
    .ImplementedBy<EmployeeRepository>() 
    .Interceptors(InterceptorReference.ForType<LoggingInterceptor>()).First); 

अभी तक इतना अच्छा - तरह का। मैं जो लॉगर प्रति कक्षा में एक लॉगर की एनएलओजी की अनुशंसित अभ्यास का पालन करता हूं। मुझे नहीं लगता कि इस मामले में यह बहुत अच्छी पसंद है। इसका मतलब है कि हर एक संदेश "MyAplication.Interceptors.LoggingInterceptor" नामक एक लॉग पर जा रहा है, जो बहुत उपयोगी नहीं है।

मैं लॉगर लागू करने के लिए नामांकन के बाद नाम दर्ज करना पसंद करूंगा। उदाहरण के लिए, यदि IEmployeeRepository के कार्यान्वयन पर लॉगर लागू किया गया है तो लॉग को EmployeeRepository नाम दिया जाना चाहिए। क्या यह करने योग्य है?

संपादित करें: मैं एक कस्टम ILoggerFactory लागू करने और कंटेनर को निर्देश उसका उपयोग करना चाहते कोशिश की है। हालांकि मैंने जल्दी से रोडब्लॉक मारा: जब विंडसर कारखाने में बुलाता है, तो आपूर्ति की गई एकमात्र जानकारी उस वस्तु का प्रकार है जिसके लिए लॉगर अधिग्रहण किया जा रहा है। ऑब्जेक्ट के बारे में कोई अन्य जानकारी प्रदान नहीं की जाती है, इसलिए ILoggerFactory में अवरोधक के बारे में पता लगाने का कोई तरीका नहीं है जिसे इंटरसेप्टर पर लागू किया गया है।

मुझे लगता है कि ILoggerFactory.Create() के दो ओवरलोड हैं जो तारों को तर्क के रूप में स्वीकार करते हैं। ऐसा लगता है कि विंडसर सीधे उनमें से किसी का उपयोग नहीं कर रहा है, लेकिन कोई यह मान लेगा कि उन्हें किसी कारण से वहां रहना है। क्या धाराप्रवाह पंजीकरण API में कुछ भी है जिसका उपयोग यह निर्दिष्ट करने के लिए किया जा सकता है कि एक विशेष स्ट्रिंग का उपयोग किया जाए?

उत्तर

6

यहां एक प्रश्न है जो आपके जैसा ही है और इसका एक स्वीकार्य उत्तर है। लिंक में, उत्तर पोस्ट करने वाला व्यक्ति इलोगगर फैक्ट्री पर और इंटरसेप्ट विधि पर निर्भर इंटरसेप्टर बनाने का सुझाव देता है, उचित लॉगर प्राप्त करने के लिए ILoggerFactory को भेजने के लिए टाइप के रूप में IInvocation.TargetType का उपयोग करें।

नोट, मैं कैसल का उपयोग नहीं करता, इसलिए मैं इस सुझाव पर और अधिक टिप्पणी नहीं कर सकता।

public class LoggingInterceptor : IInterceptor 
{ 
    private readonly ILoggerFactory _loggerFactory; 

    public LoggingInterceptor(ILoggerFactory loggerFactory) 
    { 
     _loggerFactory = loggerFactory; 
    } 

    public void Intercept(IInvocation invocation) 
    { 
     var logger = _loggerFactory.Create(invocation.TargetType); 
     if (logger.IsDebugEnabled) 
     { 
      logger.Debug(CreateInvocationLogString(invocation)); 
     } 
     try 
     { 
      invocation.Proceed(); 
     } 
     catch (Exception e) 
     { 
      logger.Warn(CreateInvocationLogString(invocation)); 
      throw; 
     } 
     logger.Info(CreateInvocationLogString(invocation)); 
    } 

    private static String CreateInvocationLogString(IInvocation invocation) 
    { 
     var sb = new StringBuilder(100); 
     sb.AppendFormat("Called: {0}.{1}(", invocation.TargetType.Name, invocation.Method.Name); 
     foreach (var argument in invocation.Arguments) 
     { 
      var argumentDescription = argument == null ? "null" : argument.ToString(); 
      sb.Append(argumentDescription).Append(","); 
     } 
     if (invocation.Arguments.Any()) 
     { 
      sb.Length--; 
     } 
     sb.Append(")"); 
     return sb.ToString(); 
    } 
} 

Castle: How can i get the correct ILogger in the logging interceptor?

आप शायद पहले से ही इस देखा है, लेकिन यहां एक महल उदाहरण से पता चलता है कि एक प्रवेश इंटरसेप्टर बनाने का तरीका और कैसे, जाहिरा तौर पर, लिपटे प्रकार के लिए एक लकड़हारा बनाने के लिए करने के लिए एक कड़ी है:

http://docs.castleproject.org/Windsor.Introduction-to-AOP-With-Castle.ashx

संपादित करें: nlog के लिए ILoggerFactory के कार्यान्वयन ExtendedNLogFactory है, यह Castle.Core-nLog nuget पैकेज में है (http://www.nuget.org/packages/Castle.Core-NLog)

+1

आपका Google-fu मेरा से स्पष्ट रूप से बेहतर है। यह सही होना चाहिए - केवल अतिरिक्त विवरण ठोस प्रकार के बजाय अमूर्त प्रकार के लिए नामित लॉग प्राप्त कर रहा है।मैं सोच रहा हूं कि मैं उन लोगों के लिए ठोस प्रकार के इंटरफेस खोजकर ऐसा करूंगा जो एक सम्मेलन का पालन करते हैं। –

+0

खुशी मैं मदद करने में सक्षम था! – wageoghe

संबंधित मुद्दे