2010-03-09 16 views
16

मैंने एक सी # ऐप लिखा है जो लगातार लूप में चलता है और कई धागे लॉग 4नेट फ़ाइल को लिखते हैं।लॉग 4नेट प्रदर्शन

मुद्दा यह है कि ऐप चल रहा है, लूप को पूरा करने में जितना अधिक समय लगता है। मैंने एक एएनटीएस प्रदर्शन प्रोफाइलर चलाया है, और देखा है कि इनमें से अधिकतर CPU समय लॉग 4.net के साथ लॉगिंग करने में व्यतीत होता है।

अधिक वर्बोज़ लॉग जितना अधिक CPU उपयोग करता है और 30 मिनट के बाद यह 100% CPU का उपयोग कर रहा है। अगर मैं लूप के लिए लिया गया समय लॉगिंग अक्षम करता हूं तो समय के साथ स्थिर रहता है। मैंने विंडोज परफॉर्मेंस मॉनीटर पर एक नज़र डाली और भौतिक डिस्क ज्यादातर समय आईडीईई है।

मैंने अपनी लॉगिंग को न्यूनतम रखने की कोशिश की है, लेकिन यहां तक ​​कि अपेक्षाकृत कम मात्रा में लॉगिंग के साथ भी मुझे समस्या का सामना करना पड़ रहा है।

<log4net> 
    <root> 
    <!-- Levels: OFF, DEBUG, INFO, WARN, ERROR, FATAL--> 
    <level value="INFO" /> 
    <appender-ref ref="RollingLogFileAppender" /> 
    </root> 

    <!--Logs to a file--> 
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> 
    <file value="c:\\logs\\log-file.txt" /> 
    <appendToFile value="true" /> 
    <lockingModel type="log4net.Appender.FileAppender+ExclusiveLock" /> 
    <rollingStyle value="Composite" /> 
    <datePattern value="yyyyMMdd" /> 
    <maxSizeRollBackups value="20" /> 
    <maximumFileSize value="1MB" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date [%thread] %-5level %logger %L %M Schdl:[%property{scheduleContext}] Job:[%property{jobContext}] - %message%newline" /> 
    </layout> 
    </appender> 
</log4net> 

मैं हर वस्तु है कि लॉग से एक ही लकड़हारा उपयोग कर रहा हूँ:

यहाँ मेरी Log4net.xml विन्यास फाइल का एक नमूना है।

log4net.ILog logger; 
    log4net.Config.BasicConfigurator.Configure(); 
    logger = log4net.LogManager.GetLogger(typeof(myProject)); 

यह अधिक से अधिक CPU का उपयोग क्यों लंबे समय तक चलता है?

इस पर सुधार करने के तरीके पर कोई सलाह की सराहना की जाएगी।

+0

इसके बजाए एडीओनेट एपेंडर का उपयोग करने का प्रयास करें? – ram

+0

एडीओनेट एक ही समस्या पैदा कर रहा था –

उत्तर

29

क्या आप लॉग इन करने वाले प्रत्येक ऑब्जेक्ट में log4net को कॉन्फ़िगर कर रहे हैं? ऐसा लगता है कि आपके कोड से। प्रति प्रक्रिया एक बार कॉन्फ़िगरेशन किया जाना चाहिए, उदा। स्टार्टअप पर और फिर आपकी ऑब्जेक्ट्स को केवल लॉगर प्राप्त करना होगा।

प्रत्येक वर्ग के प्रवेश करने के लिए मैं आमतौर पर निम्नलिखित पैटर्न की जरूरत है कि के लिए:

class SomeClass 
{ 
    private static readonly ILog log = LogManager.GetLogger(typeof(SomeClass)); 
    ... 
} 

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

+0

दाएं, और लॉग इन करने वाली प्रत्येक वस्तु लॉगजर तक पहुंच सकती है: 'निजी स्थैतिक रीडोनली ILog लॉग = LogManager.GetLogger (typeof (MyProject));' –

+0

आप सही हैं, मैं कॉन्फ़िगर() में चल रहा था प्रत्येक ऑब्जेक्ट जो लॉग करता है। मैंने प्रत्येक लॉगर ऑब्जेक्ट में स्थिर सदस्य जोड़ा है। अब तक सब ठीक है। मैं इसके बाद अधिक परीक्षण और अद्यतन करूँगा। –

+0

धन्यवाद @ जैमी, इस तरह मैं इसे तब भी करता हूं जब तक कि मैं निर्भरता इंजेक्शन का उपयोग नहीं कर रहा हूं। –

-3

(मैं log4net इस्तेमाल नहीं किया है पहले तो ले कि मैं क्या सावधानी के साथ सलाह देते हैं)

आप घटक log4net और एक समर्पित धागा पर लॉग ऑन करने के लिए एक async प्रॉक्सी लिख सकते हैं। लॉगफाइल पर लिखने के प्रयासों के साथ अब आप अपने मुख्य धागे को अवरुद्ध नहीं करेंगे।

लॉग 4नेट में पहले से ही एसिंक प्रॉक्सी होने पर यह बेकार है।

+1

यदि आपने log4Net का उपयोग किया था तो एक बेहतर उत्तर संभवतः प्रदान किया जा सकता था :) – HansLindgren

4

आप उन संदर्भ गुणों के साथ क्या कर रहे हैं? Schdl:[%property{scheduleContext}] Job:[%property{jobContext}] यदि आप यहां केवल एक मान से अधिक कुछ असाइन करते हैं (या एक साधारण ToString() विधि वाला ऑब्जेक्ट), तो यह प्रदर्शन को कम कर सकता है। मैं किस बारे में बात कर रहा हूं उसके विचार के लिए Active Property Values के तहत लॉग 4नेट मैनुअल देखें।

पीटर लिलवॉल्ड के पास केवल एक बार लॉग 4नेट को कॉन्फ़िगर करने के बारे में एक अच्छा सुझाव है। आप अपनी असेंबली इन्फ्लो में निम्न पंक्ति भी डाल सकते हैं।सीएस फ़ाइल:

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

तुम भी क्या देखने के लिए log4net आंतरिक लॉगिंग चालू की कोशिश कर सकते हो रहा है:

[assembly: log4net.Config.XmlConfigurator()] 

निम्न पंक्ति में कटौती करने और किसी भी वर्ग करता है लॉगिंग में पेस्ट करने के लिए आसान है

<appSettings> 
    <add key="log4net.Internal.Debug" value="true"/> 
</appSettings> 
+0

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

+0

मैं समस्याओं के बिना काफी व्यस्त एएसपी.NET साइटों (एकाधिक थ्रेड लॉगिंग एक फ़ाइल ऐपेंडर) से गुणों का उपयोग करता हूं। सरल मान समस्या नहीं होनी चाहिए। – intoOrbit

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