Adding Diagnostics To .NET Code

by Richard Grimes



Listing One



   // Assembly app.exe

   int i = 42;

#if DEBUG

   Console.WriteLine(

      "initial value of i is " + i.ToString());

#endif // DEBUG





Listing Two



// Assembly lib.dll

class DbgCode

{

   [Conditional("DEBUG")]

   public static void PrintDebug(string str)

   {

      Console.WriteLine();

   }

}

// Assembly uselib.exe

int i = 42;

// Next line will compile only if this assembly is compiled with DEBUG defined

DbgCode.PrintDebug("initial value of i is " + i.ToString());





Listing Three



// Call PRINTDEBUG rather than PrintDebug

#ifdef DEBUG

   #define PRINTDEBUG DbgCode::PrintDebug

#else

   #define PRINTDEBUG __noop

#endif





Listing Four



<configuration>

 <system.diagnostics>

  <trace autoflush="true">

   <listeners>

    <remove name="Default"/>

    <add name="myListener" 

     type="System.Diagnostics.TextWriterTraceListener" 

     initializeData="MyListener.txt"/>

   </listeners>

  </trace>            

 </system.diagnostics>

</configuration>





Listing Five



class MySwitches

{

   public static bool DataAcquisition {get;}

   public static bool DataAnalysis {get;}

   public static bool Presentation {get;}

   // Implementation omitted

}

// Use switches

WriteLineIf(MySwitches.DataAnalysis, "Searching for user...");



Listing Six



<configuration>

   <system.diagnostics>

      <switches>

         <add name="DataAnalysis" value="1"/>

      </switches>

   </system.diagnostics>

</configuration>

// MySwitches constructor

static MySwitches()

{

   BooleanSwitch data = new BooleanSwitch(

    "DataAnalysis", "this parameter is not used");

   dataAnalysis = data.Enabled;

   // other code

}





Listing Seven



// Unmanaged C++

LPCSTR str = "Test String\n";

OutputDebugString(str);

LPCSTR args[2] = {reinterpret_cast<LPCSTR>(strlen(str)), str};

RaiseException(0x40010006, 0, 2, reinterpret_cast<const DWORD*>(args));



Listing Eight



<configuration>

 <system.diagnostics>

  <trace autoflush="true">

   <listeners>

    <add name="myListener"

     type="System.Diagnostics.TextWriterTraceListener" 

     initializeData="logFile.log"/>

   </listeners>

  </trace>            

 </system.diagnostics>

</configuration>





Listing Nine



// Defined in assembly domainsafe.dll

class DomainSafeTextTrace : TextWriterTraceListener

{

   public DomainSafeTextTrace() 

   {

      Initialize("Trace");

   }

   // The parameter is the base name for the log file.

   public DomainSafeTextTrace(string str) 

   {

      Initialize(str);

   }

   // Create a file with a name that includes the name of application domain.

   //  This will be unique for each application domain.

   protected void Initialize(string str)

   {

      this.Name = "DomainSafeTextTrace";

      string strFile = str + AppDomain.CurrentDomain.FriendlyName + ".log";

      this.Writer = new StreamWriter(strFile, true);

   }

}





Listing Ten



<configuration>

 <system.diagnostics>

  <trace autoflush="true">

   <listeners>

    <add name="myListener"

      type="DomainSafeTextTrace, domainsafe" 

      initializeData="domainSafeLog"/>

   </listeners>

  </trace>            

 </system.diagnostics>

</configuration>

















1



