2009-08-28 19 views
9

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

  • StackTrace/StackFrame

  • MethodInfo.GetCurrentMethod() (अब भी:

    यहाँ कुछ मैं था कर रहे हैं, लेकिन मैं प्रतिबिंब की वजह से प्रदर्शन के बारे में चिंता (बहुत ज्यादा भूमि के ऊपर?)? के रूप में प्रतिनिधि (सी # और बहुत साफ नहीं)

  • पास विधि है कि परोक्ष कर सकते हैं और मैं MethodInfo के लिए उपयोग किया है, लेकिन बहुत साफ नहीं)

मैं किसी की टिप्पणियों की सराहना करता हूं।

अद्यतन:

मैं इसे पसंद किया StackFrame की cleanless तो मैं StackFrame के प्रदर्शन के संबंध में एक अधिक विशिष्ट प्रश्न here पूछा और मैं प्रदर्शन परीक्षणों सहित कुछ वास्तव में अच्छी प्रतिक्रिया मिल गया। यह पता चला है कि MethodInfo.GetCurrentMethod() सबसे तेज़ है (मेरे कंप्यूटर पर लगभग 1 माइक्रोसॉन्ड लेता है) और new StackFrame(1) मांग पर अनुरोध किया जा सकता है (मेरे कंप्यूटर पर लगभग 15-20 माइक्रोसॉन्ड लेता है)। मैंने विधि को विकल्प के रूप में फेंक दिया क्योंकि विधि में कई पैरामीटर हैं जब यह बहुत गन्दा है।

निष्कर्ष:

मैं सभी विकल्पों को देखा है और सबसे अच्छा PostSharp के लिए एक कस्टम प्लग में जो संकलन के दौरान MSIL में स्ट्रिंग के रूप में विधि नाम injects जब की तरह एक कस्टम विशेषता को लागू करने के बारे में करने के लिए है [Trace] इसे। यह मेरी राय में सबसे तेज़ और सबसे रखरखाव विकल्प है। यह पैरामीटर नामों और तर्कों को बिना किसी प्रकार के प्रतिबिंब और पकड़ने और अपवादों को स्वचालित रूप से लॉगिंग करने जैसी कई और चीजों को सक्षम बनाता है। अधिक जानकारी के लिए यह my related question

+0

मैं पूछ सकते हैं, आप log4net उपयोग करने के लिए क्यों चाहते है? – nWorx

+0

मुझे अन्य घटकों पर भी भरोसा नहीं है। और log4net के मामले में, यह बहुत जटिल है। –

+2

हरमन, इसे आम तौर पर हमारे उद्योग में "यहां सिंड्रोम का आविष्कार नहीं किया गया" के रूप में जाना जाता है और इससे बचा जाना सर्वोत्तम होता है। इस दुःख के बारे में अधिक जानकारी के साथ यहां एक विकिपीडिया लिंक है: http://en.wikipedia.org/wiki/Not_Invented_Here –

उत्तर

3

सीधे शब्दों में कहें, सबसे तेज़ तरीका संकलन समय पर स्थिर यह करने के लिए है:

public void DoSomething() 
{ 
    TraceCall("DoSomething"); 
} 

public void TraceCall(string methodName) 
{ 
    if (!tracingEnabled) { return; } 
    // Log the call 
} 

सवाल तो अनिवार्य रूप से अपने पिछले प्रश्न के रूप में ही है, एक रखरखाव और सटीक fastion में ऐसा करने का सबसे अच्छा तरीका क्या है? रन-टाइम विकल्प जिन्हें हमने पहले चर्चा की थी, अपेक्षाकृत गंभीर प्रदर्शन हिट लेते हैं, लेकिन व्यापार-बंद यह है कि उन्हें आसानी से कार्यान्वित किया जा सकता है।

के रूप में वह पिछले धागा पूर्णांक उल्लेख किया गया था, इस पहलू उन्मुख-प्रोग्रामिंग की ओर झुक लगा है; PostSharp ऐसी एक पुस्तकालय है जो सरल रखरखाव के साथ स्थिर रूप से संकलित प्रदर्शन के संतुलन को खोजने में मदद कर सकती है।

+0

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

+0

@ हरमन: जब तक कि आप कुछ लिख रहे हैं जिसे Google के थ्रूपुट को संभालना है, 20ms पूरी तरह से लापरवाह है। अन्य प्रश्नों में हमने किए गए परीक्षण दिखा रहे थे कि यदि आपको 100,000 तरीकों के लिए लॉगिंग कॉल शुरू करने की आवश्यकता है तो यह अधिकतम - 1.5 सेकंड में जोड़ देगा। इस तथ्य के बावजूद कि कुछ विधियां दूसरों की तुलना में काफी तेजी से हैं, सभी विधियां दिन के अंत में मामूली हैं। – STW

2

जब आप पहले से ही विधि के अंदर हैं (या यदि आप विधि को रोक रहे हैं), मुझे नहीं लगता कि आप MethodInfo.GetCurrentMethod से बहुत बेहतर कर सकते हैं - जो बहुत तेज़ नहीं है - अगर आप प्रकार रहना चाहते हैं -सुरक्षित।

चूंकि आप इसे लॉगिंग के लिए करना चाहते हैं, तो क्या आपने इसे एसिंक्रोनस ऑपरेशन में ऐसा करने पर विचार किया है ताकि आप मुख्य धागे को धीमा न करें?

आपके आवेदन पर पहले से लोड के आधार पर, यह मदद कर सकता है या नहीं भी हो सकता है।

+0

हाँ, मैं भी इसके बारे में सोच रहा था। लेकिन क्या होता है जब आवेदन व्यस्त है? क्या यह लॉगिंग स्थगित नहीं करेगा और जब एप्लिकेशन क्रैश हो जाए तो यह खो जाएगा नहीं? –

+0

इस पर निर्भर करता है कि आप एसिंक ऑपरेशन को कैसे कार्यान्वित करते हैं। यदि आप इसे थ्रेडपूल पर फेंक देते हैं, तो हाँ, आप सही हैं, और ऑर्डरिंग की गारंटी नहीं है। हालांकि, आप इसे एमएसएमक्यू को भी लिख सकते हैं, जो आपको ऑर्डर-ऑर्डर, टिकाऊ लॉगिंग दे सकता है। –

+1

एसिंक विकल्प केवल वास्तविक लेखन को लॉग में कम करेगा (जो अभी भी फायदेमंद हो सकता है)। वास्तविक "GetCurrentMethod" कॉल अभी भी मुख्य धागे पर प्रदर्शन दंड लगाएगा। – STW

0

ऐसा करने का सबसे अच्छा तरीका संकलन समय पर है: C++ परंपरागत रूप से ____FILE____ और ____LINE____ ऐसा करने के लिए मैक्रोज़ में प्रीप्रोसेसर प्रतीकों का उपयोग किया जाता है। दुर्भाग्य से सी # कंपाइलर इस समय मैक्रोज़ या ____FILE____ के बराबर और ____LINE____ की पेशकश नहीं करता है।

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

0

मुझे लगता है कि Log4PostSharp नौकरी बहुत अच्छी तरह से करेगी।

+0

मैं एक और लॉगर का उपयोग नहीं करना चाहता, खासकर log4net पर आधारित कुछ नहीं, लेकिन मैं वास्तव में) के विचार की तरह एमएसआईएल कोड इंजेक्शन। अगर मैं किसी भी तरह इसका उपयोग कर सकता हूं तो मुझे शोध करना होगा। –

+0

स्टू का जवाब पढ़ना - इसमें लगभग लेना होगा। PostSharp (या __TYPE__ और __METHOD__) का उपयोग करके __FILE__ के बराबर विकसित करने के लिए एक घंटे और __LINE__। खैर, मेरे लिए 1 घंटे। –

+0

मुझे पोस्टशर्प पर एक नज़र डालेंगी। धन्यवाद गेल! –

0

आप Event Tracing for Windows का उपयोग कर बनाया जाना चाहिए वास्तविक लॉग संदेश से गति के कारण चिंतित हैं। ईटीडब्ल्यू एक उच्च स्पीड लॉगिंग लाइब्रेरी है जो एक ड्राइवर के रूप में लागू होती है जो कर्नेल मोड और उपयोगकर्ता मोड दोनों से सुलभ है। ट्रेसिंग गतिशील रूप से चालू और बंद किया जा सकता है। लॉगिंग आवेदन के लिए बहुत कम ओवरहेड जोड़ता है। मैंने उच्च थ्रूपुट सर्वर ऐप्स में ट्रेसिंग लागू करने के लिए ईटीडब्ल्यू का उपयोग किया है। NTrace देखें।

4

सबसे तेज़ तरीका है कि संकलन समय पर, यह सच है क्या करना है, लेकिन ऐसा करने के लिए जो .NET में सबसे सुविधाजनक तरीका है CallerMemberName, CallerFilePath और अन्य कंपाइलर सेवा विशेषताओं .NET 4.5 में incroduced का उपयोग कर के माध्यम से है:

public void TraceMethodCall([CallerMemberName]string methodName) 
{ 
} 
संबंधित मुद्दे

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