2011-03-02 32 views
5

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

<variable name="commonLog" value="${logDir}\Common.log" /> 
<variable name="username" value="${identity:fSNormalize=true:authType=false:isAuthenticated=false}" /> 
<variable name="userLog" value="${logDir}\ByUser\${username}.log" /> 
<variable name="dateLog" value="${logDir}\ByDate\${shortdate}.log" /> 

<target name="logFiles" xsi:type="SplitGroup"> 
    <target xsi:type="File" fileName="${commonLog}" layout="${myLayout}" /> 
    <target xsi:type="File" fileName="${userLog}" layout="${myLayout}" /> 
    <target xsi:type="File" fileName="${dateLog}" layout="${myLayout}" /> 
</target> 

यह महान है, लेकिन मैं भी के लिए विभिन्न लेआउट का उपयोग करना चाहते गंभीरता के विभिन्न स्तर। उदाहरण के लिए, errorLayout अपवाद जानकारी शामिल और सम्मिलित [!] मार्कर तो मैं बाद में BareTail तरह लॉग दर्शकों में त्रुटियों को उजागर सकता है:

<variable name="stamp" value="${date} ${username} ${logger}" /> 

<variable name="debugLayout" value="${stamp} ... ${message}" /> 
<variable name="infoLayout" value="${stamp} [i] ${message}" /> 
<variable name="warnLayout" value="${stamp} [!] ${message}" /> 
<variable name="errorLayout" 
    value="${warnLayout}${newline}${pad:padding=10:inner=${exception:format=ToString}}" /> 

<!-- logFiles target --> 

<rules> 
    <logger name="*" level="Debug" writeTo="logFiles" layout="debugLayout" /> 
    <logger name="*" level="Info" writeTo="logFiles" layout="infoLayout" /> 
    <logger name="*" level="Warn" writeTo="logFiles" layout="warnLayout" /> 
    <logger name="*" level="Error" writeTo="logFiles" layout="errorLayout" /> 
</rules> 

इस कोड को मान लिया गया Error रों हमेशा अपवादों के साथ आते हैं और Warning रों नहीं है, लेकिन वह नहीं है बिंदु।

समस्या है यह कॉन्फ़िगरेशन गलत है। यह काम नहीं करेगा क्योंकि logger में layout विशेषता नहीं है। यह केवल target के लिए परिभाषित किया गया है।

लेआउट जिसका उपयोग किया जा रहा है, लक्ष्य को स्वयं घोषित किया जाना चाहिए, लेकिन मुझे विभिन्न गंभीरता स्तरों के लिए अलग-अलग लेआउट निर्दिष्ट करने का कोई मतलब नहीं दिखता है।

<targets> 
    <target name="logFilesDebug" xsi:type="SplitGroup"> 
    <target xsi:type="File" fileName="${commonLog}" layout="${debugLayout}" /> 
    <target xsi:type="File" fileName="${userLog}" layout="${debugLayout}" /> 
    <target xsi:type="File" fileName="${dateLog}" layout="${debugLayout}" /> 
    </target> 

    <target name="logFilesInfo" xsi:type="SplitGroup"> 
    <target xsi:type="File" fileName="${commonLog}" layout="${infoLayout}" /> 
    <target xsi:type="File" fileName="${userLog}" layout="${infoLayout}" /> 
    <target xsi:type="File" fileName="${dateLog}" layout="${infoLayout}" /> 
    </target> 

    <target name="logFilesWarn" xsi:type="SplitGroup"> 
    <target xsi:type="File" fileName="${commonLog}" layout="${warnLayout}" /> 
    <target xsi:type="File" fileName="${userLog}" layout="${warnLayout}" /> 
    <target xsi:type="File" fileName="${dateLog}" layout="${warnLayout}" /> 
    </target> 

    <target name="logFilesError" xsi:type="SplitGroup"> 
    <target xsi:type="File" fileName="${commonLog}" layout="${errorLayout}" /> 
    <target xsi:type="File" fileName="${userLog}" layout="${errorLayout}" /> 
    <target xsi:type="File" fileName="${dateLog}" layout="${errorLayout}" /> 
    </target> 
</targets> 

<rules> 
    <logger name="*" level="Debug" writeTo="logFilesDebug" /> 
    <logger name="*" level="Info" writeTo="logFilesInfo" /> 
    <logger name="*" level="Warn" writeTo="logFilesWarn" /> 
    <logger name="*" level="Error" writeTo="logFilesError" /> 
</rules> 

यह सिर्फ मेरी आँखों दर्द होता है:

अभी के लिए, मैं सिर्फ फाइलों का एक ही सेट के लिए चार अलग-अलग layout रों है करने के लिए एक ही विन्यास कोड चार बार कॉपी-पेस्ट करने के लिए किया था।
क्या ऐसा करने का कोई बेहतर तरीका है और नकल से बचें?

उत्तर

1

मुझे यकीन नहीं है, लेकिन मुझे लगता है कि आप शायद नकल के साथ फंस गए हैं। आप एक ही फाइल पर 4 अलग-अलग लेआउट का उपयोग करना चाहते हैं और आप 3 अलग-अलग फाइलें चाहते हैं। एक लक्ष्य के लिए एक लेआउट की आवश्यकता होती है। इसलिए, यदि आप केवल 1 फ़ाइल पर लॉग इन करना चाहते हैं, तो आपको अभी भी 4 लक्ष्य परिभाषित करना होगा, प्रत्येक एक ही फाइल को इंगित करेगा और प्रत्येक अपने स्वयं के लेआउट के साथ। मुझे नहीं लगता कि एनएलओजी के पास लक्ष्य के साथ एकाधिक लेआउट को जोड़ने और फिर लॉगिंग संदेश की सामग्री के आधार पर एक लेआउट चुनने का एक और सुविधाजनक तरीका है।

अपने प्रारूपों के साथ आप जो हासिल करना चाहते हैं उसके आधार पर, आप एक कस्टम लेआउट रेंडरर लिखकर कुछ हद तक डुप्लिकेशंस को कम करने में सक्षम हो सकते हैं। आपके उदाहरण में, आप दिखाते हैं कि डीबग लेआउट में "..." है, जानकारी में [i], चेतावनी है [!], और त्रुटि चेतावनी + अपवाद है। आप एक लेआउट रेन्डरर लिख सकते हैं जो संदेश के स्तर के आधार पर विशेष मार्कर जोड़ता है। इस तरह, आप डीबग, जानकारी को रोल करेंगे, और सभी को एक लेआउट में चेतावनी देंगे और त्रुटि अपने स्वयं के लेआउट को बनाए रखेगी।

एक कस्टम LayoutRenderer के लिए

कुछ इस तरह (NLog के आधार पर 1.0 ताज़ा, नहीं 2.0):

[LayoutRenderer("LevelMarkerLayoutRenderer")] 
    class LevelMarkerLayoutRenderer : LayoutRenderer 
    {  
    int estimatedSize = 3;  
    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    {  
     string marker; 
     switch (logEvent.Level) 
     { 
     case Debug: 
      marker = "..."; 
      break; 
     case Info: 
      marker = "[i]"; 
      break; 
     case Warn: 
      marker = "[!]"; 
      break; 
     case Error: 
      marker = "[!]"; 
      break; 
     case Fatal: 
      marker = "[!]"; 
      break; 
     default: 
      marker = "?"; 
     } 

     builder.Append(marker);  
    }  

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)  
    {  
     return estimatedSize;  
    } 
    } 

अब आपके पास दो लेआउट कॉन्फ़िगर कर सकते हैं:

उदाहरण के लिए

"सामान्य", और "त्रुटि "।

कुछ की तरह:

<variable name="stamp" value="${date} ${username} ${logger}" /> 

<variable name="normal" value="${stamp} ${LevelMarkerLayoutRenderer} ${message}" /> 
<variable name="error" 
    value="${warnLayout}${newline}${pad:padding=10:inner=${exception:format=ToString}}" /> 

आप शायद भी अपवाद को संभालने के लिए एक कस्टम LayoutRenderer बना सकते हैं। अगर कोई अपवाद नहीं है, तो कुछ भी आउटपुट न करें। अगर अपवाद, समेकित न्यूलाइन, पैडिंग, और अपवाद स्ट्रिंग।

<variable name="normal" value="${stamp} ${LevelMarkerLayoutRenderer} ${message} ${ConditionalExceptionLayoutRenderer}" /> 

अधिकांश समय, ConditionalExceptionLayoutRenderer अशक्त प्राप्त होते हैं क्योंकि वहाँ एक नहीं होगा:

आप एक "सशर्त" अपवाद लेआउट रेंडरर था, तो आप सिर्फ एक लेआउट है कि इस प्रकार दिखाई देंगे हो सकता था अपवाद।

उम्मीद है कि इससे मदद मिलती है।

+0

आपकी टिप्पणी के लिए धन्यवाद। अभी के लिए मैं न्यूनतम निर्भरताओं के साथ रहना चाहता हूं लेकिन जब मैं सिस्टम को पुन: इंजीनियर करता हूं, तो शायद मैं इसे कार्यान्वित करूंगा। –

8

लेआउट में स्थिति के दौरान एक वैकल्पिक समाधान है।

target.Layout = "${longdate}|[${level}]|${logger}|${message}${onexception:inner=|${exception}${when:when=(level > LogLevel.Warn):inner=|[!] ${exception:format=ToString:innerFormat=Message:maxInnerExceptionLevel=5} }}" 

मैं त्रुटि से कम कुछ भी होने पर अपवाद संदेश प्रदान करना चाहता था। जब कोई त्रुटि हुई तो मैं पूर्ण स्टैक ट्रेस चाहता था।

+0

यह स्वीकार्य उत्तर होना चाहिए। यदि मैं ओपी को सही ढंग से समझता हूं, तो सवाल को विशेष रूप से संबोधित करने के लिए प्रश्न को दोहराया जाना चाहिए: "मैं गंभीरता के विभिन्न स्तरों के लिए विभिन्न लेआउट का भी उपयोग करना चाहता हूं", और उसके बाद यह उचित जवाब होगा। – MattM

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

  • कोई संबंधित समस्या नहीं^_^