मेरे पास लॉग 4नेट में एक बग है, या मेरे हिस्से पर गलतफहमी है।log4net LogicalThreadContext काम नहीं कर रहा है
मैं कॉल संदर्भ के साथ कुछ डेटा जोड़ने के लिए LogicalThreadContext
का उपयोग करने की कोशिश कर रहा हूं और इसे उस संदर्भ में किसी भी थ्रेड द्वारा किए गए किसी भी लॉग बयान के प्रचार के लिए प्रचारित कर रहा हूं। यह LogicalThreadContext
का ThreadContext
से अधिक लाभ का लाभ है।
मैं काम करने के लिए प्रचार प्राप्त करने में सक्षम नहीं था, इसलिए मैंने यह देखने के लिए एक साधारण इकाई परीक्षण किया कि यह काम करेगा या नहीं। संदेश यह है:
[Fact]
public void log4net_logical_thread_context_test()
{
XmlConfigurator.Configure();
var log = LogManager.GetLogger(GetType());
var waitHandle = new ManualResetEvent(false);
using (LogicalThreadContext.Stacks["foo"].Push("Some contextual info"))
{
log.Debug("START");
ThreadPool.QueueUserWorkItem(delegate
{
log.Debug("A DIFFERENT THREAD");
waitHandle.Set();
});
waitHandle.WaitOne();
log.Debug("STOP");
}
}
मेरे log4net विन्यास इस तरह दिखता है:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%thread]|[%property{foo}]|%message%newline"/>
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
</configuration>
और मेरे उत्पादन इस तरह दिखता है:
[xUnit.net STA Test Execution Thread]|[Some contextual info]|START
[32]|[(null)]|A DIFFERENT THREAD
[xUnit.net STA Test Execution Thread]|[Some contextual info]|STOP
आप देख सकते हैं, डेटा मैं पुश एलटीसी स्टैक केवल को उसी थ्रेड पर लॉगिंग स्टेटमेंट में मौजूद है। पृष्ठभूमि धागे द्वारा किए गए लॉग स्टेटमेंट में प्रासंगिक डेटा की कमी है। परीक्षण के माध्यम से डीबगिंग मैं देख सकता था कि, वास्तव में, LogicalThreadContext.Stacks.Count
पृष्ठभूमि धागे पर शून्य है।
लॉग 4नेट स्रोत में खोदने के बाद, मैंने इसे CallContext
कक्षा का उपयोग किया। यह वर्ग टिन पर जो कहता है वह करता है - यह वर्तमान "कॉल" को संदर्भित करने और पुनर्प्राप्त करने के लिए संदर्भ की अनुमति देता है। यह निम्न स्तर पर कैसे करता है, मुझे कोई जानकारी नहीं है। GetData
/SetData
और LogicalGetData
/LogicalSetData
:
CallContext
तरीकों के दो सेट है जिसके साथ संदर्भ जानकारी संग्रहीत और पुनः प्राप्त किया जा सकता है। दस्तावेजों के इन दो सेटों के बीच अंतर के बारे में विवरणों पर दस्तावेज बहुत हल्का है, लेकिन उदाहरण GetData
/SetData
का उपयोग करते हैं। और इसलिए log4net का LogicalThreadContext
करता है।
एक त्वरित परीक्षण से पता चला कि GetData
/SetData
एक ही समस्या प्रदर्शित करता है - डेटा धागे भर में फैलता नहीं है। मैंने सोचा कि मैं देना चाहता हूँ LogicalGetData
/LogicalSetData
एक के बजाय जाना:
[Fact]
public void call_context_test()
{
XmlConfigurator.Configure();
var log = LogManager.GetLogger(GetType());
var count = 5;
var waitHandles = new ManualResetEvent[count];
for (var i = 0; i < count; ++i)
{
waitHandles[i] = new ManualResetEvent(false);
var localI = i;
// on a bg thread, set some call context data
ThreadPool.QueueUserWorkItem(delegate
{
CallContext.LogicalSetData("name", "value " + localI);
log.DebugFormat("Set call context data to '{0}'", CallContext.LogicalGetData("name"));
var localWaitHandle = new ManualResetEvent(false);
// then on another bg thread, make sure the logical call context value is correct with respect to the "owning" bg thread
ThreadPool.QueueUserWorkItem(delegate
{
var value = CallContext.LogicalGetData("name");
log.DebugFormat("Retrieved call context data '{0}'", value);
Assert.Equal("value " + localI, value);
localWaitHandle.Set();
});
localWaitHandle.WaitOne();
waitHandles[localI].Set();
});
}
foreach (var waitHandle in waitHandles)
{
waitHandle.WaitOne();
}
}
यह परीक्षण गुजरता है - प्रासंगिक जानकारी सफलतापूर्वक जब LogicalGetData
/LogicalSetData
का उपयोग कर धागे भर में प्रचारित किया जाता है।
तो मेरा सवाल यह है: क्या लॉग 4net ने यह गलत पाया है? या क्या मुझे कुछ याद आ रहा है?
अद्यतन: मैं भी अपने LogicalThreadContextProperties
श्रेणी से ऊपर मेरे निष्कर्ष के अनुसार बदल के साथ log4net के एक कस्टम निर्माण कर रही है की कोशिश की। मैंने अपना प्रारंभिक परीक्षण फिर से चलाया और यह काम किया। यह मुझे इतने सारे लोगों द्वारा उपयोग किए जाने वाले उत्पाद के लिए बहुत स्पष्ट समस्या के रूप में मारता है, इसलिए मुझे लगता है कि मुझे कुछ याद आ रहा है।
यह ध्यान देने योग्य है कि यह [निश्चित] (https://issues.apache.org/jira/browse/LOG4NET-317) log4net 1.2.12 में है लेकिन अभी तक इसके लिए रिलीज़ दिनांक प्रतीत नहीं होता है ; https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=10690&version=12318546 –