2010-11-16 16 views
8

बस हाल ही में NLog के साथ प्रयोग में मिल गया के लिए उत्पन्न हैडर अनुभाग, और यह मेरे लिए होता है कि मैं इस तरह के रूप में एक लॉग फ़ाइल शीर्ष करने के लिए शीर्ष लेख जानकारी जोड़ने में सक्षम होना चाहते हैं:Nlog - एक लॉग फ़ाइल

निष्पादन नाम फ़ाइल संस्करण रिलीज की तारीख Windows उपयोगकर्ता आईडी आदि ...

कुछ खोज के बाद मैं मौजूदा ऑनलाइन प्रलेखन या कोड मंचों जो कार्यक्षमता के इस प्रकार को इंगित करता है में कुछ भी खोजने में असमर्थ किया गया है। क्या यह संभव है? मैंने हमेशा लॉग फाइलों में इस तरह की जानकारी शामिल की है, और इसे अतीत में कई मौकों पर उपयोगी पाया है, जब ग्राहक साइटों पर उत्पादन के मुद्दों पर जानकारी सोर्सिंग करते हैं। माना जाता है कि, यह कार्यक्षमता समाधान के लिए कस्टम बनाया गया था और वर्तमान .NET लॉगिंग फ्रेमवर्क के आधार पर नहीं।

उत्तर

4

मुझे लगता है कि ऐसा करने के लिए बहुत आसानी से एक तरह से के बारे में पता नहीं कर रहा हूँ। ऐसा कहकर, आपके द्वारा दिए गए सभी उदाहरण प्रत्येक लॉग संदेश में जोड़े जाने के लिए उपलब्ध हैं (या कुछ कस्टम कोड के साथ काफी आसानी से उपलब्ध हैं)। यही है, प्रत्येक लॉग संदेश को लेआउट और लेआउट रेंडरर्स के माध्यम से निष्पादन योग्य नाम, फ़ाइल संस्करण, रिलीज दिनांक, विंडोज उपयोगकर्ता आईडी आदि के साथ टैग किया जा सकता है।

यह स्पष्ट रूप से सिर्फ लॉग फ़ाइल के शीर्ष पर एक शीर्ष लेख बनाने के समान नहीं है, तो यह आपके लिए उपयोगी नहीं हो सकता है।

दूसरी ओर, यदि आप एक तकनीक पैट के जवाब in this post में उल्लेख किया है का उपयोग एक ही लक्ष्य के साथ कई लेआउट दाता संबद्ध करने के लिए कर सकता है। आप उस लेआउट को परिभाषित कर सकते हैं जिसमें आपके हेडर में इच्छित फ़ील्ड शामिल हैं और फ़िल्टरिंगप्रैपर में फ़िल्टर को केवल सत्र के पहले संदेश के लिए उस लेआउट को लागू करने के लिए सेट करें (या आप किसी अन्य तकनीक का उपयोग कर सकते हैं जिसे इसे आउटपुट फ़ाइल में जोड़ा गया है सिर्फ एक बार)।

अपनी NLog.config फ़ाइल का उपयोग करके, यहां एक तरीका है कि आप जो चाहते हैं उसे प्राप्त कर सकते हैं। ध्यान दें कि मैंने यह कोशिश नहीं की है, इसलिए मुझे नहीं पता कि यह कॉन्फ़िगरेशन फ़ाइल मान्य है या, यदि ऐसा है, तो यह परिणाम उत्पन्न करेगा जो आप चाहते हैं।

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     autoReload="true" 
     internalLogLevel="Warn" 
     internalLogFile="nlog log.log" 
     > 
    <variable name="HeaderLayout" value="${processname} ${gdc:item=version} ${gdc:item=releasedate} ${windows-identity}" /> 
    <variable name="NormalLayout" value="${longdate} ${logger} ${level} ${message} /> 

    <targets async="true"> 
     <target name="file" xsi:type="File" fileName="log.log" 
       layout="${NormalLayout}"> 
     </target> 

     <target name="fileHeader" xsi:type="File" fileName="log.log" 
       layout="${HeaderLayout}"> 
     </target>  
    </targets> 

    <rules> 
     <logger name="HeaderLogger" minlevel="Trace" writeTo="fileHeader" final="true" />   
     <logger name="*" minlevel="Trace" writeTo="file" /> 
    </rules> 

</nlog> 

अपने कोड में, अपने स्टार्टअप तर्क इस प्रकार दिखाई देंगे:

public void Main() 
{ 
    AddHeaderToLogFile(); 
} 

public void AddHeaderToLogFile() 
{ 
    Logger headerlogger = LogManager.GetLogger("HeaderLogger"); 

    //Use GlobalDiagnosticContext in 2.0, GDC in pre-2.0 
    GlobalDiagnosticContext["releasedate"] = GetReleaseDate();  
    GlobalDiagnosticContext["version"] = GetFileVersion();  
    GlobalDiagnosticContext["someotherproperty"] = GetSomeOtherProperty(); 

    headerlogger.Info("message doesn't matter since it is not specified in the layout"); 

    //Log file should now have the header as defined by the HeaderLayout 

    //You could remove the global properties now if you are not going to log them in any 
    //more messages. 
} 

विचार यहाँ है कि आप जीडीसी में फ़ाइल संस्करण, रिलीज की तारीख, आदि डाल जब कार्यक्रम शुरू होता है। "हेडर लॉगर" लॉगर के साथ एक संदेश लॉग करें। यह संदेश के बाद से "HeaderLogger" "fileHeader" लक्ष्य जो "HeaderLayout" साथ जुड़ा हुआ है साथ जुड़ा हुआ है "HeaderLayout" का उपयोग कर लॉग फ़ाइल के लिए लिखा जाएगा। हेडर लेआउट में परिभाषित फ़ील्ड लॉग फ़ाइल में लिखे गए हैं। इसके बाद लॉग संदेश, क्योंकि वे "हेडर लॉगर" का उपयोग नहीं करेंगे, "रूट" (*) लेआउट का उपयोग करेंगे। वे एक ही फाइल पर जाएंगे क्योंकि दोनों "फाइल" और "फाइलहेडर" लक्ष्य अंततः उसी फ़ाइल नाम पर इंगित करते हैं।

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

शुभकामनाएं!

[संपादित करें] इस तरह के स्तर के आधार पर लेआउट बदलने के लिए काम कर सकते हैं। पहले खंड में मैंने कई चर परिभाषित किए हैं, जिनमें से प्रत्येक एक लेआउट को परिभाषित करता है। अगले खंड में मैंने कई लक्ष्यों को परिभाषित किया है जिनमें से प्रत्येक एक ही फ़ाइल का उपयोग करता है, लेकिन केवल एक विशिष्ट स्तर के संदेशों को लिखे जाने के लिए फ़िल्टर किया जाता है। अंतिम खंड में मैं एक नियम को परिभाषित करता हूं जो सभी लक्ष्यों को भेजेगा (इसलिए "*" लॉगर नाम) सभी लक्ष्यों को।चूंकि प्रत्येक लक्ष्य के स्तर से फ़िल्टर किया जाता है, "ट्रेस" लक्ष्य केवल "ट्रेस" संदेशों आदि तो, "ट्रेस" संदेश "का पता लगाने" लेआउट का उपयोग कर लिखा जाएगा, "डिबग" संदेश "डिबग" का उपयोग कर लिखा जाएगा लिखेंगे लेआउट, आदि। चूंकि सभी लक्ष्य अंततः एक ही फाइल को लिखते हैं, इसलिए सभी संदेश एक ही फाइल में समाप्त हो जाएंगे। मैंने यह कोशिश नहीं की है, लेकिन मुझे लगता है कि यह शायद काम करेगा।

<variable name="TraceLayout" value="THIS IS A TRACE: ${longdate} ${level:upperCase=true} ${message}" /> 
<variable name="DebugLayout" value="THIS IS A DEBUG: ${longdate} ${level:upperCase=true} ${message}" /> 
<variable name="InfoLayout" value="THIS IS AN INFO: ${longdate} ${level:upperCase=true} ${message}" /> 


<targets async="true"> 
    <target name="fileAsTrace" xsi:type="FilteringWrapper" condition="level==LogLevel.Trace"> 
     <target xsi:type="File" fileName="log.log" layout="${TraceLayout}" /> 
    </target> 
    <target name="fileAsDebug" xsi:type="FilteringWrapper" condition="level==LogLevel.Debug"> 
     <target xsi:type="File" fileName="log.log" layout="${DebugLayout}" /> 
    </target> 
    <target name="fileAsInfo" xsi:type="FilteringWrapper" condition="level==LogLevel.Info"> 
     <target xsi:type="File" fileName="log.log" layout="${InfoLayout}" /> 
    </target> 
</targets> 

<rules> 
    <logger name="*" minlevel="Trace" writeTo="fileAsTrace, fileAsDebug, fileAsInfo" /> 
</rules> 

(ध्यान दें कि मैंने केवल 3 स्तरों को शामिल किया है)।

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

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

यह काम करता है:

<variable name="TraceLayout" value="This is a TRACE - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <variable name="DebugLayout" value="This is a DEBUG - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <variable name="InfoLayout" value="This is an INFO - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <variable name="WarnLayout" value="This is a WARN - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <variable name="ErrorLayout" value="This is an ERROR - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <variable name="FatalLayout" value="This is a FATAL - ${longdate} | ${logger} | ${level} | ${message}"/> 
    <targets> 
    <target name="fileAsTrace" xsi:type="FilteringWrapper" condition="level==LogLevel.Trace"> 
     <target xsi:type="File" fileName="xxx.log" layout="${TraceLayout}" /> 
    </target> 
    <target name="fileAsDebug" xsi:type="FilteringWrapper" condition="level==LogLevel.Debug"> 
     <target xsi:type="File" fileName="xxx.log" layout="${DebugLayout}" /> 
    </target> 
    <target name="fileAsInfo" xsi:type="FilteringWrapper" condition="level==LogLevel.Info"> 
     <target xsi:type="File" fileName="xxx.log" layout="${InfoLayout}" /> 
    </target> 
    <target name="fileAsWarn" xsi:type="FilteringWrapper" condition="level==LogLevel.Warn"> 
     <target xsi:type="File" fileName="xxx.log" layout="${WarnLayout}" /> 
    </target> 
    <target name="fileAsError" xsi:type="FilteringWrapper" condition="level==LogLevel.Error"> 
     <target xsi:type="File" fileName="xxx.log" layout="${ErrorLayout}" /> 
    </target> 
    <target name="fileAsFatal" xsi:type="FilteringWrapper" condition="level==LogLevel.Fatal"> 
     <target xsi:type="File" fileName="xxx.log" layout="${FatalLayout}" /> 
    </target> 
    </targets> 


    <rules> 
     <logger name="*" minlevel="Trace" writeTo="fileAsTrace,fileAsDebug,fileAsInfo,fileAsWarn,fileAsError,fileAsFatal" /> 
     <logger name="*" minlevel="Info" writeTo="dbg" /> 
    </rules> 

मैं हर लॉगिंग स्तर के लिए एक लेआउट की स्थापना की है, शुरुआत है कि (संदेश का स्तर इस दिखाने के लिए है कि एक अलग प्रारूप प्रयोग किया जाता है का वर्णन करता है पर एक शाब्दिक स्ट्रिंग जोड़ने प्रत्येक स्तर के लिए)। प्रत्येक लेआउट एक FilteringWrapper उस संदेश के स्तर के आधार और निर्देशन फ़िल्टर कोई संदेश है कि फिल्टर पारित आउटपुट फ़ाइल में लॉग इन करने के साथ जुड़ा हुआ है। प्रत्येक फ़िल्टरिंगवापर एक ही आउटपुट फ़ाइल को लपेट रहा है, इसलिए सभी लॉग संदेशों को उसी फ़ाइल में लॉग किया जाएगा। यहाँ

logger.Trace("Trace msg"); 
    logger.Debug("Debug msg"); 
    logger.Info("Info msg"); 
    logger.Warn("Warn msg"); 
    logger.Error("Error msg"); 
    logger.Fatal("Fatal msg"); 

और क्या उत्पादन लग रहा है की तरह है::

यहाँ है कि मैं परीक्षण के लिए इस्तेमाल किया कोड का एक वर्ग है

This is a TRACE - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Trace | Trace msg 
This is a DEBUG - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Debug | Debug msg 
This is an INFO - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Info | Info msg 
This is a WARN - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Warn | Warn msg 
This is an ERROR - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Error | Error msg 
This is a FATAL - 2010-11-22 13:20:00.4131 | NLogTest.Form1 | Fatal | Fatal msg 

जाहिर है मेरे पहले config जानकारी में समस्या अंतरिक्ष था "writeTo" मानों के बीच। मुझे लगता है कि एनएलओजी इस के प्रति संवेदनशील है। जब मैं बदल कि "writeTo=blah1,blah2,blah3" करने के लिए त्रुटि दूर चला गया मैं "writeTo=blah1, blah2, blah3". की तरह कुछ था। शुभकामनाएँ!

+0

कई धन्यवाद मजदूरी, जिसने एक इलाज किया है। हालांकि हमेशा के रूप में, बुनियादी कार्यक्षमता काम करने में सफल होने के बाद मुझे अब चीजों को ठीक करने की आवश्यकता है :-) मूल रूप से मुझे अलग-अलग लॉगिंग स्तरों के लिए अलग-अलग लेआउट की आवश्यकता होती है, आप चयनित स्तर पर लेआउट को सशर्त कैसे बनाते हैं? –

+0

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

+0

सुझाए गए तकनीक का उपयोग करते हुए, निम्नलिखित के लिए: मुझे कॉन्फ़िगरेशन फ़ाइल में निम्न त्रुटि मिलती है: '' लिखने के लिए 'विशेषता अमान्य है ....' –

9

बस इस समय एक लॉग में एक शीर्षलेख/पादलेख नकल log4net के साथ बनाया अपने सहकर्मियों में से एक को देख पर ठोकर हुआ। मैंने इसे कुछ ओपन-सोर्स प्रोजेक्ट से पाया और इसे एक आंतरिक उदाहरण के रूप में अनुकूलित किया। मुझे लगता है कि यह आपकी जरूरतों के लिए संशोधित करना आसान होना चाहिए।

<target name="logfile2" xsi:type="File" fileName="Logs\NLogDemo2.txt"> 
    <layout xsi:type="LayoutWithHeaderAndFooter"> 
    <header xsi:type="SimpleLayout" text="----------NLog Demo Starting---------&#xD;&#xA;"/> 
    <layout xsi:type="SimpleLayout" text="${longdate}|${level:uppercase=true}|${logger}|${message}" /> 
    <footer xsi:type="SimpleLayout" text="----------NLog Demo Ending-----------&#xD;&#xA;"/> 
    </layout> 
</target> 

यह मेरे उत्पादन है कि इस तरह दिखता है देता है:

----------NLog Demo Starting--------- 

2013-03-01 16:40:19.5404|INFO|Project.Form1|Sample informational message 
2013-03-01 16:40:19.5714|WARN|Project.Form1|Sample warning message 
2013-03-01 16:40:19.5714|ERROR|Project.Form1|Sample error message 
2013-03-01 16:40:19.5714|FATAL|Project.Form1|Sample fatal error message 
----------NLog Demo Ending----------- 

मैं इस undocumented किया जा रहा है यही कारण है कि पता नहीं है। केवल संदर्भ मैं मिल सकता है यहाँ था: https://github.com/nlog/NLog/wiki/LayoutWithHeaderAndFooter

-Jody

+0

लिंक टूटा हुआ है? https://github.com/nlog/NLog/wiki/LayoutWithHeaderAndFooter – drzaus

+0

लिंक को फिक्स्ड करें। धन्यवाद। – JKoplo

1

आप प्रति "उदाहरण" एक शीर्षलेख/पादलेख अनुभाग उत्पन्न कर सकते हैं (अर्थातindicated by previous answer रूप में पहली बार एप्लिकेशन और पिछली बार एप्लिकेशन किसी भी फाइल करने के लिए लिखते हैं) लेआउट का उपयोग:

अधिक विस्तार:

+0

हो सकता है कि हम आपके उत्तर को पिछले एक के साथ विलय कर सकें, क्योंकि आप केवल नए लिंक जोड़ रहे हैं। Https://github.com/NLog/NLog/issues/2119 पर भी इंगित कर सकता है जहां कोई भी ऐप शुरू होने और बंद होने पर प्रत्येक बार हेडर और पाद लेख रखने के लिए कहता है। – user276648

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