2012-05-08 10 views
11

मैं अपना आवेदन बंद करना चाहता हूं और लंबित लॉग संदेश लिखना चाहता हूं। तो मैं अपनी शट डाउन प्रक्रिया के दौरान LogManager.Flush() पर कॉल करता हूं। हालांकि, मुझे लिखे गए सभी संदेश नहीं दिखते हैं। इसके बजाय, अगर मैं कुछ सेकंड प्रतीक्षा करता हूं (Thread.Sleep() का उपयोग करके) मैं संदेश देखता हूं।फ्लश() कहलाते समय एनएलओजी AsyncTargetWrapper में सभी कतारबद्ध संदेशों को फ्लश करना चाहिए?

NLog's code on GitHUB की जांच करने के बाद, मुझे लगता है कि AsyncTargetWrapper.FlushAsync() विधि केवल आलसी लेखक थ्रेड को अगले बैच पर सभी लंबित संदेशों को लिखने के लिए शेड्यूल कर रही है। यह लॉग संदेशों को समकालिक रूप से लिख नहीं रहा है।

इस अपेक्षित व्यवहार है? मुझे LogManager.Flush() समकालिक होने की उम्मीद है, यानी: सभी लंबित संदेशों को लिखे जाने तक ब्लॉक करने के लिए (या टाइमआउट पार हो गया है)।


कोड मैं शटडाउन होने पर का उपयोग करें:

LogManager.Flush(ex => { }, TimeSpan.FromSeconds(15)); 

और फिर कोड Nlog आरंभ करने के लिए (यह एक Silverlight अनुप्रयोग है, तो मैं किसी भी config फ़ाइलों का उपयोग नहीं कर रहा हूँ)।

public static void InitialiseNLog(LogLevel forLevel) 
    { 
     var config = new LoggingConfiguration(); 

     // Add targets. 
     // We need an async target wrapping a custom web service call back to the server. 
     var serverTarget = new RemoteServiceTarget(); 
     var asyncWrapper = new AsyncTargetWrapper(serverTarget, 10000, AsyncTargetWrapperOverflowAction.Discard); 
     asyncWrapper.TimeToSleepBetweenBatches = (int)TimeSpan.FromSeconds(2).TotalMilliseconds; 
     asyncWrapper.BatchSize = 200; 

     // Add rules. 
     var rule = new LoggingRule("Company.Application.SilverlightApp.*", forLevel, asyncWrapper); 
     config.LoggingRules.Add(rule); 

     // Activate the configuration. 
     LogManager.Configuration = config; 
     LogManager.GlobalThreshold = forLevel; 
    } 

उत्तर

-1

मैं संपादन वर्तमान NLog स्रोत कोड द्वारा एक फिक्स क्रियान्वित किया है।

protected override void FlushAsync(AsyncContinuation asyncContinuation) 
{ 
    this.flushAllContinuation = asyncContinuation; 
} 

करने के लिए::

AsyncTargetWrapper.cs में, से FlushAsync() पद्धति को बदलने अभी भी सही नहीं

protected override void FlushAsync(AsyncContinuation asyncContinuation) 
{ 
    this.flushAllContinuation = asyncContinuation; 
    this.ProcessPendingEvents(null);  // Added to make this flush synchronous. 
} 
+1

परिणाम FlushAsync समारोह सिंक हो जाते हैं ;-) यह एक ठीक नहीं है। –

+0

यह अब थोड़ा पुराना है, इसलिए मैं पूरे संदर्भ को याद नहीं कर सकता। लेकिन शट डाउन पर 'थ्रेड स्लीप()' को कॉल करना शायद ही बेहतर विकल्प है। वर्तमान एनएलओजी में 'LogManager.Shutdown()' विधि है, जो एक बेहतर विकल्प हो सकता है (हालांकि मैंने इसका परीक्षण नहीं किया है)। – ligos

0

, लेकिन कैसे इस बारे में:

var reset = new ManualResetEventSlim(false); 
LogManager.Flush(ex => reset.Set(), TimeSpan.FromSeconds(15)); 
reset.Wait(TimeSpan.FromSeconds(15)); 
3

टिप्पणी से ligos सही रास्ते पर है। AsyncTargetWrapper.CloseTarget() विधि NLog issue 134 के परिणामस्वरूप संशोधित की गई थी, जहां एक नेस्टेड BufferingTargetWrapper डोमेन अनलोड पर फ़्लश नहीं हो रहा था।

LogManager.Shutdown() वास्तव में तुल्यकालिक प्रभावी रूप से फ्लश AsyncTargetWrapper करने के लिए मजबूर करता है, लेकिन यह LogManager.Flush() के बाद इस्तेमाल किया जा रहा है क्योंकि इस तरह के रूप में BufferingTargetWrapper लक्ष्य नहीं वास्तव में पास पर फ्लश कर दिया होता। यह LogManager.Configuration = null सेट करना बेहतर हो सकता है क्योंकि यह फ्लश करता है और फिर एक हिट में लक्ष्य बंद कर देता है और कॉन्फ़िगरेशन को अगली बार उपयोग करने की आवश्यकता होने पर कॉन्फ़िगर किया जाएगा (कॉन्फ़िगरेशन फ़ाइल का उपयोग करते समय)।

मैं दोनों परीक्षण किया है और के रूप में मैं अपने प्रवेश वापस ऊपर चाहने कर रहा हूँ और मैं के बाद सब कुछ ठीक कर रख दिया है चल रहा उत्तरार्द्ध के साथ चले गए हैं, लेकिन सवाल दिया जाता है सिल्वरलाइट में मैं सिफारिश करेंगे:

LogManager.Flush(); 
LogManager.Shutdown(); 

संपादित

LogManager config डोमेन अनलोड या प्रक्रिया से बाहर निकलें ताकि हम इस समस्या नहीं देखी जानी चाहिए एक पुराने NLog संस्करण चला जब तक पर शून्य पर सेट करता है। एनएलओजी मुद्दा अक्टूबर 2012 में तय किया गया था। स्पष्ट शट डाउन या कॉन्फ़िगरेशन कॉन्फ़िगरेशन के बिना परीक्षण किया गया है और यह पुष्टि कर सकता है कि LogManager.Flush() पर कॉल करना पर्याप्त है।

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