The Labs \ Source Viewer \ SSCLI \ System.Diagnostics \ TraceListener

  1. //------------------------------------------------------------------------------
  2. // <copyright file="TraceListener.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. /*
  16. */
  17. namespace System.Diagnostics
  18. {
  19.     using System;
  20.     using System.Text;
  21.     using System.Security.Permissions;
  22.     using System.Collections.Specialized;
  23.     using System.Globalization;
  24.     using System.Runtime.InteropServices;
  25.     using System.Collections;
  26.     using System.Configuration;
  27.     using System.Runtime.Versioning;
  28.    
  29.     /// <devdoc>
  30.     /// <para>Provides the <see langword='abstract '/>base class for the listeners who
  31.     /// monitor trace and debug output.</para>
  32.     /// </devdoc>
  33.     [HostProtection(Synchronization = true)]
  34.     public abstract class TraceListener : MarshalByRefObject, IDisposable
  35.     {
  36.        
  37.         int indentLevel;
  38.         int indentSize = 4;
  39.         TraceOptions traceOptions = TraceOptions.None;
  40.         bool needIndent = true;
  41.        
  42.         string listenerName;
  43.         TraceFilter filter = null;
  44.         StringDictionary attributes;
  45.         internal string initializeData;
  46.        
  47.         /// <devdoc>
  48.         /// <para>Initializes a new instance of the <see cref='System.Diagnostics.TraceListener'/> class.</para>
  49.         /// </devdoc>
  50.         protected TraceListener()
  51.         {
  52.         }
  53.        
  54.         /// <devdoc>
  55.         /// <para>Initializes a new instance of the <see cref='System.Diagnostics.TraceListener'/> class using the specified name as the
  56.         /// listener.</para>
  57.         /// </devdoc>
  58.         protected TraceListener(string name)
  59.         {
  60.             this.listenerName = name;
  61.         }
  62.        
  63.         public StringDictionary Attributes {
  64.             get {
  65.                 if (attributes == null)
  66.                     attributes = new StringDictionary();
  67.                 return attributes;
  68.             }
  69.         }
  70.        
  71.         /// <devdoc>
  72.         /// <para> Gets or sets a name for this <see cref='System.Diagnostics.TraceListener'/>.</para>
  73.         /// </devdoc>
  74.         public virtual string Name {
  75.             get { return (listenerName == null) ? "" : listenerName; }
  76.            
  77.             set { listenerName = value; }
  78.         }
  79.        
  80.         public virtual bool IsThreadSafe {
  81.             get { return false; }
  82.         }
  83.        
  84.         /// <devdoc>
  85.         /// </devdoc>
  86.         public void Dispose()
  87.         {
  88.             Dispose(true);
  89.             GC.SuppressFinalize(this);
  90.         }
  91.        
  92.         /// <devdoc>
  93.         /// </devdoc>
  94.         protected virtual void Dispose(bool disposing)
  95.         {
  96.             return;
  97.         }
  98.        
  99.        
  100.         /// <devdoc>
  101.         /// <para>When overridden in a derived class, closes the output stream
  102.         /// so that it no longer receives tracing or debugging output.</para>
  103.         /// </devdoc>
  104.         public virtual void Close()
  105.         {
  106.             return;
  107.         }
  108.        
  109.         /// <devdoc>
  110.         /// <para>When overridden in a derived class, flushes the output buffer.</para>
  111.         /// </devdoc>
  112.         public virtual void Flush()
  113.         {
  114.             return;
  115.         }
  116.        
  117.         /// <devdoc>
  118.         /// <para>Gets or sets the indent level.</para>
  119.         /// </devdoc>
  120.         public int IndentLevel {
  121.             get { return indentLevel; }
  122.            
  123.             set { indentLevel = (value < 0) ? 0 : value; }
  124.         }
  125.        
  126.         /// <devdoc>
  127.         /// <para>Gets or sets the number of spaces in an indent.</para>
  128.         /// </devdoc>
  129.         public int IndentSize {
  130.             get { return indentSize; }
  131.            
  132.             set {
  133.                 if (value < 0)
  134.                     throw new ArgumentOutOfRangeException("IndentSize", value, SR.GetString(SR.TraceListenerIndentSize));
  135.                 indentSize = value;
  136.             }
  137.         }
  138.        
  139.         [ComVisible(false)]
  140.         public TraceFilter Filter {
  141.             get { return filter; }
  142.             set { filter = value; }
  143.         }
  144.        
  145.        
  146.         /// <devdoc>
  147.         /// <para>Gets or sets a value indicating whether an indent is needed.</para>
  148.         /// </devdoc>
  149.         protected bool NeedIndent {
  150.             get { return needIndent; }
  151.            
  152.             set { needIndent = value; }
  153.         }
  154.        
  155.         [ComVisible(false)]
  156.         public TraceOptions TraceOutputOptions {
  157.             get { return traceOptions; }
  158.             set {
  159.                 if (((int)value >> 6) != 0) {
  160.                     throw new ArgumentOutOfRangeException("value");
  161.                 }
  162.                
  163.                 traceOptions = value;
  164.             }
  165.         }
  166.        
  167.         internal void SetAttributes(Hashtable attribs)
  168.         {
  169.             TraceUtils.VerifyAttributes(attribs, GetSupportedAttributes(), this);
  170.            
  171.             attributes = new StringDictionary();
  172.             attributes.contents = attribs;
  173.         }
  174.        
  175.         /// <devdoc>
  176.         /// <para>Emits or displays a message for an assertion that always fails.</para>
  177.         /// </devdoc>
  178.         public virtual void Fail(string message)
  179.         {
  180.             Fail(message, null);
  181.         }
  182.        
  183.         /// <devdoc>
  184.         /// <para>Emits or displays messages for an assertion that always fails.</para>
  185.         /// </devdoc>
  186.         public virtual void Fail(string message, string detailMessage)
  187.         {
  188.             StringBuilder failMessage = new StringBuilder();
  189.             failMessage.Append(SR.GetString(SR.TraceListenerFail));
  190.             failMessage.Append(" ");
  191.             failMessage.Append(message);
  192.             if (detailMessage != null) {
  193.                 failMessage.Append(" ");
  194.                 failMessage.Append(detailMessage);
  195.             }
  196.            
  197.             WriteLine(failMessage.ToString());
  198.         }
  199.        
  200.         protected internal virtual string[] GetSupportedAttributes()
  201.         {
  202.             return null;
  203.         }
  204.        
  205.         /// <devdoc>
  206.         /// <para>When overridden in a derived class, writes the specified
  207.         /// message to the listener you specify in the derived class.</para>
  208.         /// </devdoc>
  209.         public abstract void Write(string message);
  210.        
  211.         /// <devdoc>
  212.         /// <para>Writes the name of the <paramref name="o"/> parameter to the listener you specify when you inherit from the <see cref='System.Diagnostics.TraceListener'/>
  213.         /// class.</para>
  214.         /// </devdoc>
  215.         public virtual void Write(object o)
  216.         {
  217.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, null, null, o))
  218.                 return;
  219.            
  220.             if (o == null)
  221.                 return;
  222.             Write(o.ToString());
  223.         }
  224.        
  225.         /// <devdoc>
  226.         /// <para>Writes a category name and a message to the listener you specify when you
  227.         /// inherit from the <see cref='System.Diagnostics.TraceListener'/>
  228.         /// class.</para>
  229.         /// </devdoc>
  230.         public virtual void Write(string message, string category)
  231.         {
  232.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, message))
  233.                 return;
  234.            
  235.             if (category == null)
  236.                 Write(message);
  237.             else
  238.                 Write(category + ": " + ((message == null) ? string.Empty : message));
  239.         }
  240.        
  241.         /// <devdoc>
  242.         /// <para>Writes a category name and the name of the <paramref name="o"/> parameter to the listener you
  243.         /// specify when you inherit from the <see cref='System.Diagnostics.TraceListener'/>
  244.         /// class.</para>
  245.         /// </devdoc>
  246.         public virtual void Write(object o, string category)
  247.         {
  248.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, category, null, o))
  249.                 return;
  250.            
  251.             if (category == null)
  252.                 Write(o);
  253.             else
  254.                 Write(o == null ? "" : o.ToString(), category);
  255.         }
  256.        
  257.         /// <devdoc>
  258.         /// <para>Writes the indent to the listener you specify when you
  259.         /// inherit from the <see cref='System.Diagnostics.TraceListener'/>
  260.         /// class, and resets the <see cref='TraceListener.NeedIndent'/> property to <see langword='false'/>.</para>
  261.         /// </devdoc>
  262.         protected virtual void WriteIndent()
  263.         {
  264.             NeedIndent = false;
  265.             for (int i = 0; i < indentLevel; i++) {
  266.                 if (indentSize == 4)
  267.                     Write(" ");
  268.                 else {
  269.                     for (int j = 0; j < indentSize; j++) {
  270.                         Write(" ");
  271.                     }
  272.                 }
  273.             }
  274.         }
  275.        
  276.         /// <devdoc>
  277.         /// <para>When overridden in a derived class, writes a message to the listener you specify in
  278.         /// the derived class, followed by a line terminator. The default line terminator is a carriage return followed
  279.         /// by a line feed (\r\n).</para>
  280.         /// </devdoc>
  281.         public abstract void WriteLine(string message);
  282.        
  283.         /// <devdoc>
  284.         /// <para>Writes the name of the <paramref name="o"/> parameter to the listener you specify when you inherit from the <see cref='System.Diagnostics.TraceListener'/> class, followed by a line terminator. The default line terminator is a
  285.         /// carriage return followed by a line feed
  286.         /// (\r\n).</para>
  287.         /// </devdoc>
  288.         public virtual void WriteLine(object o)
  289.         {
  290.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, null, null, o))
  291.                 return;
  292.            
  293.             WriteLine(o == null ? "" : o.ToString());
  294.         }
  295.        
  296.         /// <devdoc>
  297.         /// <para>Writes a category name and a message to the listener you specify when you
  298.         /// inherit from the <see cref='System.Diagnostics.TraceListener'/> class,
  299.         /// followed by a line terminator. The default line terminator is a carriage return followed by a line feed (\r\n).</para>
  300.         /// </devdoc>
  301.         public virtual void WriteLine(string message, string category)
  302.         {
  303.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, message))
  304.                 return;
  305.             if (category == null)
  306.                 WriteLine(message);
  307.             else
  308.                 WriteLine(category + ": " + ((message == null) ? string.Empty : message));
  309.         }
  310.        
  311.         /// <devdoc>
  312.         /// <para>Writes a category
  313.         /// name and the name of the <paramref name="o"/>parameter to the listener you
  314.         /// specify when you inherit from the <see cref='System.Diagnostics.TraceListener'/>
  315.         /// class, followed by a line terminator. The default line terminator is a carriage
  316.         /// return followed by a line feed (\r\n).</para>
  317.         /// </devdoc>
  318.         public virtual void WriteLine(object o, string category)
  319.         {
  320.             if (Filter != null && !Filter.ShouldTrace(null, "", TraceEventType.Verbose, 0, category, null, o))
  321.                 return;
  322.            
  323.             WriteLine(o == null ? "" : o.ToString(), category);
  324.         }
  325.        
  326.        
  327.         // new write methods used by TraceSource
  328.        
  329.         [ComVisible(false)]
  330.         public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
  331.         {
  332.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data))
  333.                 return;
  334.            
  335.             WriteHeader(source, eventType, id);
  336.             string datastring = String.Empty;
  337.             if (data != null)
  338.                 datastring = data.ToString();
  339.            
  340.             WriteLine(datastring);
  341.             WriteFooter(eventCache);
  342.         }
  343.        
  344.         [ComVisible(false)]
  345.         public virtual void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
  346.         {
  347.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
  348.                 return;
  349.            
  350.             WriteHeader(source, eventType, id);
  351.            
  352.             StringBuilder sb = new StringBuilder();
  353.             if (data != null) {
  354.                 for (int i = 0; i < data.Length; i++) {
  355.                     if (i != 0)
  356.                         sb.Append(", ");
  357.                    
  358.                     if (data[i] != null)
  359.                         sb.Append(data[i].ToString());
  360.                 }
  361.             }
  362.             WriteLine(sb.ToString());
  363.            
  364.             WriteFooter(eventCache);
  365.         }
  366.        
  367.         [ComVisible(false)]
  368.         public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
  369.         {
  370.             TraceEvent(eventCache, source, eventType, id, String.Empty);
  371.         }
  372.        
  373.         // All other TraceEvent methods come through this one.
  374.         [ComVisible(false)]
  375.         public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
  376.         {
  377.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, message))
  378.                 return;
  379.            
  380.             WriteHeader(source, eventType, id);
  381.             WriteLine(message);
  382.            
  383.             WriteFooter(eventCache);
  384.         }
  385.        
  386.         [ComVisible(false)]
  387.         public virtual void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
  388.         {
  389.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, format, args))
  390.                 return;
  391.            
  392.             WriteHeader(source, eventType, id);
  393.             if (args != null)
  394.                 WriteLine(String.Format(CultureInfo.InvariantCulture, format, args));
  395.             else
  396.                 WriteLine(format);
  397.            
  398.             WriteFooter(eventCache);
  399.         }
  400.        
  401.         [ComVisible(false)]
  402.         public virtual void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId)
  403.         {
  404.             TraceEvent(eventCache, source, TraceEventType.Transfer, id, message + ", relatedActivityId=" + relatedActivityId.ToString());
  405.         }
  406.        
  407.         private void WriteHeader(string source, TraceEventType eventType, int id)
  408.         {
  409.             Write(String.Format(CultureInfo.InvariantCulture, "{0} {1}: {2} : ", source, eventType.ToString(), id.ToString(CultureInfo.InvariantCulture)));
  410.         }
  411.        
  412.         [ResourceExposure(ResourceScope.None)]
  413.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  414.         private void WriteFooter(TraceEventCache eventCache)
  415.         {
  416.             if (eventCache == null)
  417.                 return;
  418.            
  419.             indentLevel++;
  420.             if (IsEnabled(TraceOptions.ProcessId))
  421.                 WriteLine("ProcessId=" + eventCache.ProcessId);
  422.            
  423.             if (IsEnabled(TraceOptions.LogicalOperationStack)) {
  424.                 Write("LogicalOperationStack=");
  425.                 Stack operationStack = eventCache.LogicalOperationStack;
  426.                 bool first = true;
  427.                 foreach (object obj in operationStack) {
  428.                     if (!first)
  429.                         Write(", ");
  430.                     else
  431.                         first = false;
  432.                    
  433.                     Write(obj.ToString());
  434.                 }
  435.                 WriteLine(String.Empty);
  436.             }
  437.            
  438.             if (IsEnabled(TraceOptions.ThreadId))
  439.                 WriteLine("ThreadId=" + eventCache.ThreadId);
  440.            
  441.             if (IsEnabled(TraceOptions.DateTime))
  442.                 WriteLine("DateTime=" + eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture));
  443.            
  444.             if (IsEnabled(TraceOptions.Timestamp))
  445.                 WriteLine("Timestamp=" + eventCache.Timestamp);
  446.            
  447.             if (IsEnabled(TraceOptions.Callstack))
  448.                 WriteLine("Callstack=" + eventCache.Callstack);
  449.             indentLevel--;
  450.         }
  451.        
  452.         internal bool IsEnabled(TraceOptions opts)
  453.         {
  454.             return (opts & TraceOutputOptions) != 0;
  455.         }
  456.     }
  457. }

Developer Fusion