2010-11-10 14 views
16

के माध्यम से ट्रेसिंग बंद करना मैं कुछ बहुत ही बुनियादी लॉगिंग करने के लिए System.Diagnostics का उपयोग करने का प्रयास कर रहा हूं। मुझे लगता है कि मैं Log4Net या EntLib जैसे अतिरिक्त निर्भरता को लेने के बजाय बॉक्स में क्या उपयोग करता हूं।app.config

मैं सब तैयार हूं, ट्रेसिंग अद्भुत काम कर रही है। कोड स्निपेट:

Trace.TraceInformation("Hello World") 

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
    <trace autoflush="true" indentsize="4"> 
     <listeners> 
     <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" /> 
     <remove name="Default" /> 
     </listeners> 
    </trace> 
    </system.diagnostics> 
</configuration> 

और मेरा छोटा "नमस्ते दुनिया" अच्छी तरह से मेरी Trace.log फ़ाइल में दिखाई देता है। लेकिन अब मैं ऑफ ट्रेसिंग स्विच करना चाहता हूं, इसलिए मैं एमएसडीएन में खोदता हूं और How to: Configure Trace Switches ढूंढता हूं। मैं <switches> तत्व जोड़ है, और अब मेरी app.config लग रहा है इस तरह:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
    <trace autoflush="true" indentsize="4"> 
     <listeners> 
     <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" /> 
     <remove name="Default" /> 
     </listeners> 
    </trace> 
    <switches> 
     <add name="Data" value="0" /> 
    </switches> 
    </system.diagnostics> 
</configuration> 

value="0" अनुरेखण बंद कर देना चाहिए - कम से कम आप तो How to: Create and Initialize Trace Switches का पालन करें, जो कोड की इस पंक्ति को जोड़ने के लिए आपको बताता है कि यदि:

Dim dataSwitch As New BooleanSwitch("Data", "DataAccess module") 

कि मेरे लिए कोई मतलब नहीं है: मैं बस की घोषणा करने के BooleanSwicth का एक उदाहरण का प्रबंधन करने में सक्षम होना चाहिए (अक्षम) .config फ़ाइल के माध्यम से पता लगाने? मुझे पसंद है ... का उपयोग करें ... ऑब्जेक्ट कहीं कहीं?

वैसे भी, मुझे यकीन है कि मैंने कहीं कुछ स्पष्ट रूप से स्पष्ट किया है। कृपया मदद करे।

मैं app.config में ट्रेसिंग कैसे बंद कर सकता हूं?

उत्तर

32

मैं @Alex हम्फ्रे की सिफारिश से सहमत TraceSources उपयोग करने का प्रयास करने के लिए। TraceSources के साथ आप अपने लॉगिंग/ट्रेसिंग कथन कैसे निष्पादित करते हैं, इस पर अधिक नियंत्रण प्राप्त करते हैं। उदाहरण के लिए, अगर आप इस तरह कोड हो सकता है:

public class MyClass1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyClass1"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class MyClass2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyClass2"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

TraceSource.TraceEvent कॉल स्वचालित रूप से जुड़े स्विच के लिए कॉन्फ़िगर किया गया स्तर के खिलाफ संदेश (TraceEventType.Information) के स्तर की जाँच करेगा और चाहे या नहीं का निर्धारण करेगा संदेश वास्तव में लिखा जाना चाहिए।

प्रत्येक प्रकार के लिए एक अलग नाम TraceSource का उपयोग करके आप उन वर्गों को व्यक्तिगत रूप से प्रवेश नियंत्रित कर सकते हैं। आप MyClass1 लॉगिंग को सक्षम कर सकते हैं या आप इसे अक्षम कर सकते हैं या आप इसे सक्षम कर सकते हैं, लेकिन अगर यह संदेश का स्तर (TraceEventType) एक निश्चित मान से अधिक है (शायद केवल "चेतावनी" और उच्चतर लॉग हो) तो यह लॉग हो सकता है। साथ ही, आप MyClass2 में लॉग ऑन करना बंद कर सकते हैं या MyClass1 के पूरी तरह से स्वतंत्र रूप से स्तर पर सेट कर सकते हैं। यह सभी सक्षम/अक्षम/स्तर की सामग्री app.config फ़ाइल में होती है।

app.config फ़ाइल का प्रयोग करके आप एक ही तरह से सभी TraceSources (या TraceSources के समूह) को नियंत्रित कर सकता है। तो, आप कॉन्फ़िगर कर सकते हैं ताकि MyClass1 और MyClass2 दोनों एक ही स्विच द्वारा नियंत्रित हो।

आप प्रत्येक प्रकार के लिए एक अलग नाम TraceSource है नहीं करना चाहते हैं, तो आप सिर्फ एक ही TraceSource हर कक्षा में बना सकते हैं:

public class MyClass1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class MyClass2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

इस तरह, आप सब अपने आवेदन के भीतर प्रवेश करने से हो कर सकता है एक ही स्तर पर (या बंद हो या एक ही TraceListener, या जो भी हो)।

तुम भी स्वतंत्र रूप से विन्यास होने के लिए अपने आवेदन के विभिन्न भागों को कॉन्फ़िगर कर सकता है प्रत्येक प्रकार में एक अद्वितीय TraceSource को परिभाषित करने की "मुसीबत" पर जाए बिना:

public class Analysis1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class Analysis2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class DataAccess1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class DataAccess2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 
अपने वर्ग इस तरह से instrumented साथ

, आप कर सकते थे एक स्तर पर अपने अनुप्रयोग लॉग का "DataAccess" हिस्सा बनाने, जबकि "विश्लेषण" एक अलग स्तर पर अपने अनुप्रयोग लॉग का हिस्सा (जाहिर है, या तो या आपके एप्लिकेशन के दोनों भागों विन्यस्त किया जा सकता है, ताकि लॉगिंग अक्षम है)।

यहाँ एक app.config फ़ाइल कि TraceSources और TraceSwitches कॉन्फ़िगर करता है का एक हिस्सा है:

<system.diagnostics> 
    <trace autoflush="true"></trace> 
    <sources> 
    <source name="MyClass1" switchName="switch1"> 
     <listeners> 
     <remove name="Default"></remove> 
     <add name="console"></add> 
     </listeners> 
    </source> 
    <source name="MyClass2" switchName="switch2"> 
     <listeners> 
     <remove name="Default"></remove> 
     <add name="console"></add> 
     </listeners> 
    </source> 
    </sources> 
    <switches> 
    <add name="switch1" value="Information"/> 
    <add name="switch2" value="Warning"/> 
    </switches> 
    <sharedListeners> 
    <add name="console" 
     type="System.Diagnostics.ConsoleTraceListener"> 
    </add> 
    <add name="file" 
     type="System.Diagnostics.TextWriterTraceListener" 
     initializeData="trace.txt"> 
    </add> 
    </sharedListeners> 
</system.diagnostics> 

आप देख सकते हैं, आप एक ही TraceSource और एक भी स्विच कॉन्फ़िगर कर सकता है और सभी प्रवेश के लिए एक एकल के साथ होता है नियंत्रण का स्तर (यानी आप सभी लॉगिंग बंद कर सकते हैं या इसे एक निश्चित स्तर पर लॉग कर सकते हैं)।

वैकल्पिक रूप से, आप एक से अधिक TraceSources निर्धारित कर सकते हैं (और अपने कोड में इसी TraceSources संदर्भ) और कई स्विच करता है। स्विच साझा किए जा सकते हैं (यानी एकाधिक ट्रेसे स्रोत एक ही स्विच का उपयोग कर सकते हैं)।

आखिरकार, ट्रेस स्रोतों का उपयोग करने के लिए थोड़ा और प्रयास करके और अपने कोड में उचित नाम वाले ट्रेस स्रोतों का संदर्भ देने के लिए (यानी ट्रेस स्रोत नामों को तार्किक रूप से परिभाषित करें ताकि आपके ऐप में लॉगिंग पर वांछित डिग्री हो), आप लंबे समय तक महत्वपूर्ण लचीलापन हासिल करेंगे।

यहाँ कुछ लिंक है कि आप System.Diagnostics के साथ मदद कर सकता है के रूप में आप आगे जाने हैं:

.net Diagnostics best practices?

Logging best practices

What's the best approach to logging?

Does the .Net TraceSource/TraceListener framework have something similar to log4net's Formatters?

लिंक में मैं पोस्ट किया गया, अक्सर "सर्वश्रेष्ठ" लॉगिंग की चर्चा होती है ढांचा। मैं आपको System.Diagnostics से बदलने के लिए मनाने की कोशिश नहीं कर रहा हूं। लिंक भी System.Diagnostics का उपयोग कर के बारे में अच्छी जानकारी है, यही वजह है कि मैं उन्हें पोस्ट करते हैं।

मेरे द्वारा पोस्ट किए गए कई लिंक Ukadc.Diagnostics पर एक लिंक शामिल हैं। यह System.Diagnostics के लिए लाइब्रेरी पर वास्तव में एक अच्छा जोड़ है जो लॉग 4नेट और एनएलओजी के साथ आप क्या कर सकते हैं के समान समृद्ध स्वरूपण क्षमता जोड़ता है। यह लाइब्रेरी आपके ऐप पर कॉन्फ़िगर-केवल निर्भरता लागू करती है, कोड या संदर्भ निर्भरता नहीं।

+0

बहुत बढ़िया जवाब। धन्यवाद। :) –

+0

एक आकर्षण की तरह काम करता है। आप नमूना .config फ़ाइल में '' तत्व खो रहे हैं। –

+0

मैंने नोड को बंद करने के लिए जोड़ा। – wageoghe

1

यह है स्रोत नोड के switchValue विशेषता:

<system.diagnostics> 
<sources> 
    <source name="System.ServiceModel" 
      switchValue="Off" 
      propagateActivity="true"> 
    <listeners> 
     <add name="traceListener" 
      type="System.Diagnostics.XmlWriterTraceListener" 
      initializeData= "somePath" /> 
    </listeners> 
    </source> 
</sources> 
<trace autoflush="true" /> 

+0

अपना नमूना आजमाया, दुर्भाग्य से यह काम नहीं किया। कुछ भी लॉग नहीं किया गया था ... –

1

dataSwitch के राज्य की जाँच करें जब भी आप के अनुसार, लॉग इन करने की जरूरत है:

http://msdn.microsoft.com/en-us/library/aa984285%28v=VS.71%29.aspx

हालांकि , यह बहुत बुरा है, उन चेकों को हर जगह रखना है। क्या उनका एक कारण है कि आप app.config में श्रोताओं के संग्रह से TraceListener को आसानी से हटाना नहीं चाहते हैं?

इसके अलावा, मैं .NET 2.0+ ट्रेस सामग्री का उपयोग करके जांच करता हूं जिसमें TraceSource शामिल है। नई (एर) सामग्री कॉन्फ़िगरेशन की एक बहुत अधिक डिग्री प्रदान करती है, और आपको लगता है कि यह अधिक उपयुक्त है।

http://msdn.microsoft.com/en-us/library/ms228993.aspx

3

आप इस तरह से वैश्विक स्तर पर ट्रेसिंग बंद नहीं करते हैं।

आप
1) एक स्विच की घोषणा करने के लिए है और इसके मूल्य सेट करें:

<switches> 
    <add name="MySwitch" value="Information"/> 
</switches> 

2) एक TraceSource आप का उपयोग के साथ इस स्विच सहयोगी:

<sources> 
    <source name="MySource" switchName="MySwitch"/> 
</source> 

तो, जो भी आप के माध्यम से लिखना "माईसोर्स" नामक ट्रेससोर्स को स्विच वैल्यू के हिसाब से फ़िल्टर किया जाता है।

यदि आप Trace.Write जैसी स्थिर विधियों का उपयोग करते हैं, तो मुझे लगता है कि आप स्विच का उपयोग नहीं कर सकते हैं, क्योंकि फिल्टर लागू करने के लिए कोई TraceSource नहीं है।
यदि आप स्थैतिक तरीकों से ट्रेसिंग बंद करना चाहते हैं, तो बस सभी श्रोताओं को हटा दें: <listeners> <clear/> </listeners>

1

देर app.config बारे में एक त्वरित फुटनोट के साथ शामिल होने की स्थिति में यह कुछ दिनों के बाहर किसी के जीवन से बचाता है:

मान लें कि बनाता है जो स्टार्टअप (.exe) PROJECTA ClassA युक्त है ProjectB (.dll) का उपयोग कक्षा बी युक्त।

क्लासबी बदले में एक नए ट्रेससोर्स ("कक्षाबी") उदाहरण का उपयोग करता है। इसे कॉन्फ़िगर करने के लिए आपको app.config या projectA को संशोधित करने की आवश्यकता है। प्रोजेक्टबी के app.config को ट्वीव करना कहीं भी नहीं ले जाएगा।

भी ध्यान रखें कि app.config अंदर

<system.diagnostics> 

धारा की नियुक्ति समस्याओं का कारण हो सकता है अगर अनुभाग के समक्ष रखा लगता है:

<configSections> 

या अनुभाग के बाद:

<userSettings> 

कम से कम मेरे मामले में, जब मुझे इन स्थानों में इसे स्थानांतरित करने का प्रयास किया गया तो मुझे त्रुटियां मिल रही थीं मेरी परियोजना के e app.config। मेरे लिए काम किया गया लेआउट था:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     ...config sections here if any... 
    </configSections> 
    <system.diagnostics> 
     <trace autoflush="true"/> 
     <sources> 
      <source name="classB" 
       switchName="mySwitch" 
       switchType="System.Diagnostics.SourceSwitch" > 
       <listeners> 
        <clear/> 
        <add name="textwriterListener" 
         type="System.Diagnostics.TextWriterTraceListener" 
         initializeData="ClassBLog.txt" 
         traceOutputOptions="DateTime" /> 
       </listeners> 
      </source> 
      </sources> 
      <switches> 
      <add name="mySwitch" value="Verbose" /> 
      </switches> 
    </system.diagnostics> 
    <runtime> 
     ...runtime sections here if any... 
    </runtime> 
    <userSettings> 
     ...usersettings sections here if any... 
    </userSettings> 
</configuration>