Code Listings
Chapter 23: Diagnostics
Conditional compilation:
#define TESTMODE // #define directives must be at top of file // Symbol names are uppercase by convention. using System; class Program { static void Main() { #if TESTMODE Console.WriteLine ("in test mode!"); // OUTPUT: in test mode! #endif } }
Conditional attribute:
[Conditional ("LOGGINGMODE")] static void LogStatus (string msg) { ... }
Debug and Trace classes:
Debug.Write ("Data"); Debug.WriteLine (23 * 34); int x = 5, y = 3; Debug.WriteIf (x > y, "x is greater than y");
TraceListener:
// Clear the default listener: Trace.Listeners.Clear(); // Add a writer that appends to the trace.txt file: Trace.Listeners.Add (new TextWriterTraceListener ("trace.txt")); // Obtain the Console's output stream, then add that as a listener: System.IO.TextWriter tw = Console.Out; Trace.Listeners.Add (new TextWriterTraceListener (tw)); // Set up a Windows Event log source and then create/add listener: if (!EventLog.SourceExists ("DemoApp")) EventLog.CreateEventSource ("DemoApp", "Application"); Trace.Listeners.Add (new EventLogTraceListener ("DemoApp"));
Enumerating processes:
foreach (Process p in Process.GetProcesses()) { Console.WriteLine (p.ProcessName); Console.WriteLine (" PID: " + p.Id); Console.WriteLine (" Started: " + p.StartTime); Console.WriteLine (" Memory: " + p.WorkingSet64); Console.WriteLine (" CPU time: " + p.TotalProcessorTime); Console.WriteLine (" Threads: " + p.Threads.Count); }
Enumerating process threads:
public void EnumerateThreads (Process p) { foreach (ProcessThread pt in p.Threads) { Console.WriteLine (pt.Id); Console.WriteLine (" State: " + pt.ThreadState); Console.WriteLine (" Priority: " + pt.PriorityLevel); Console.WriteLine (" Started: " + pt.StartTime); Console.WriteLine (" CPU time: " + pt.TotalProcessorTime); } }
StackTrace and StackFrame:
static void Main() { A (); } static void A() { B (); } static void B() { C (); } static void C() { StackTrace s = new StackTrace (true); Console.WriteLine ("Total frames: " + s.FrameCount); Console.WriteLine ("Current method: " + s.GetFrame(0).GetMethod().Name); Console.WriteLine ("Calling method: " + s.GetFrame(1).GetMethod().Name); Console.WriteLine ("Entry method: " + s.GetFrame (s.FrameCount-1).GetMethod().Name); Console.WriteLine ("Call Stack:"); foreach (StackFrame f in s.GetFrames()) Console.WriteLine ( " File: " + f.GetFileName() + " Line: " + f.GetFileLineNumber() + " Col: " + f.GetFileColumnNumber() + " Offset: " + f.GetILOffset() + " Method: " + f.GetMethod().Name); }
Writing to the Windows Event Log:
const string SourceName = "MyCompany.WidgetServer"; if (!EventLog.SourceExists (SourceName)) EventLog.CreateEventSource (SourceName, "Application"); EventLog.WriteEntry (SourceName, "Service started; using configuration file=...", EventLogEntryType.Information);
Reading from the Windows Event Log:
EventLog log = new EventLog ("Application"); Console.WriteLine ("Total entries: " + log.Entries.Count); EventLogEntry last = log.Entries [log.Entries.Count - 1]; Console.WriteLine ("Index: " + last.Index); Console.WriteLine ("Source: " + last.Source); Console.WriteLine ("Type: " + last.EntryType); Console.WriteLine ("Time: " + last.TimeWritten); Console.WriteLine ("Message: " + last.Message);
Monitoring the Windows Event Log:
static void Main() { EventLog log = new EventLog ("Application"); log.EnableRaisingEvents = true; log.EntryWritten += DisplayEntry; Console.ReadLine(); } static void DisplayEntry (object sender, EntryWrittenEventArgs e) { EventLogEntry entry = e.Entry; Console.WriteLine (entry.Message); }
Enumerating performance counters:
PerformanceCounterCategory[] cats = PerformanceCounterCategory.GetCategories(); foreach (PerformanceCounterCategory cat in cats) { Console.WriteLine ("Category: " + cat.CategoryName); string[] instances = cat.GetInstanceNames(); if (instances.Length == 0) { foreach (PerformanceCounter ctr in cat.GetCounters()) Console.WriteLine (" Counter: " + ctr.CounterName); } else // Dump counters with instances { foreach (string instance in instances) { Console.WriteLine (" Instance: " + instance); if (cat.InstanceExists (instance)) foreach (PerformanceCounter ctr in cat.GetCounters (instance)) Console.WriteLine (" Counter: " + ctr.CounterName); } } }
Enumerating performance counters with LINQ to XML:
var x = new XElement ("counters", from PerformanceCounterCategory cat in PerformanceCounterCategory.GetCategories() where cat.CategoryName.StartsWith (".NET") let instances = cat.GetInstanceNames() select new XElement ("category", new XAttribute ("name", cat.CategoryName), instances.Length == 0 ? from c in cat.GetCounters () select new XElement ("counter", new XAttribute ("name", c.CounterName)) : from i in instances select new XElement ("instance", new XAttribute ("name", i), !cat.InstanceExists (i) ? null : from c in cat.GetCounters (i) select new XElement ("counter", new XAttribute ("name", c.CounterName)) ) ) ); x.Save ("counters.xml");
Reading performance counter data:
using (PerformanceCounter pc = new PerformanceCounter ("Processor", "% Processor Time", "_Total")) Console.WriteLine (pc.NextValue()); string procName = Process.GetCurrentProcess().ProcessName; using (PerformanceCounter pc = new PerformanceCounter ("Process", "Private Bytes", procName)) Console.WriteLine (pc.NextValue());
Polling performance counters:
static void Monitor (string category, string counter, string instance, EventWaitHandle stopper) { if (!PerformanceCounterCategory.Exists (category)) throw new InvalidOperationException ("Category does not exist"); if (!PerformanceCounterCategory.CounterExists (counter, category)) throw new InvalidOperationException ("Counter does not exist"); if (instance == null) instance = ""; // "" == no instance (not null!) if (instance != "" && !PerformanceCounterCategory.InstanceExists (instance, category)) throw new InvalidOperationException ("Instance does not exist"); float lastValue = 0f; using (PerformanceCounter pc = new PerformanceCounter (category, counter, instance)) while (!stopper.WaitOne (200, false)) { float value = pc.NextValue(); if (value != lastValue) // Only write out the value { // if it has changed. Console.WriteLine (value); lastValue = value; } } }
static void Main() { EventWaitHandle stopper = new ManualResetEvent (false); new Thread (delegate() { Monitor ("Processor", "% Processor Time", "_Total", stopper); } ).Start(); new Thread (delegate() { Monitor ("LogicalDisk", "% Idle Time", "C:", stopper); } ).Start(); Console.WriteLine ("Monitoring - press any key to quit"); Console.ReadKey(); stopper.Set(); }
Creating counters:
string category = "Nutshell Monitoring"; // We'll create two counters in this category: string eatenPerMin = "Macadamias eaten so far"; string tooHard = "Macadamias deemed too hard"; if (!PerformanceCounterCategory.Exists (category)) { CounterCreationDataCollection cd = new CounterCreationDataCollection(); cd.Add (new CounterCreationData (eatenPerMin, "Number of macadamias consumed, including shelling time", PerformanceCounterType.NumberOfItems32)); cd.Add (new CounterCreationData (tooHard, "Number of macadamias that will not crack, despite much effort", PerformanceCounterType.NumberOfItems32)); PerformanceCounterCategory.Create (category, "Test Category", PerformanceCounterCategoryType.SingleInstance, cd); }
Updating a counter value:
string category = "Nutshell Monitoring"; string eatenPerMin = "Macadamias eaten so far"; using (PerformanceCounter pc = new PerformanceCounter (category, eatenPerMin, "")) { pc.ReadOnly = false; pc.RawValue = 1000; pc.Increment(); pc.IncrementBy (10); Console.WriteLine (pc.NextValue()); // 1011 }
© 2007, O'Reilly Media, Inc. All rights reserved