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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="DelimitedListTraceListener.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. using System;
  16. using System.Text;
  17. using System.Globalization;
  18. using System.IO;
  19. using System.Collections;
  20. using System.Security.Permissions;
  21. using System.Runtime.Versioning;
  22. namespace System.Diagnostics
  23. {
  24.     [HostProtection(Synchronization = true)]
  25.     public class DelimitedListTraceListener : TextWriterTraceListener
  26.     {
  27.         string delimiter = ";";
  28.         string secondaryDelim = ",";
  29.         bool initializedDelim = false;
  30.        
  31.         public DelimitedListTraceListener(Stream stream) : base(stream)
  32.         {
  33.         }
  34.        
  35.         public DelimitedListTraceListener(Stream stream, string name) : base(stream, name)
  36.         {
  37.         }
  38.        
  39.         public DelimitedListTraceListener(TextWriter writer) : base(writer)
  40.         {
  41.         }
  42.        
  43.         public DelimitedListTraceListener(TextWriter writer, string name) : base(writer, name)
  44.         {
  45.         }
  46.        
  47.         [ResourceExposure(ResourceScope.Machine)]
  48.         [ResourceConsumption(ResourceScope.Machine)]
  49.         public DelimitedListTraceListener(string fileName) : base(fileName)
  50.         {
  51.         }
  52.        
  53.         [ResourceExposure(ResourceScope.Machine)]
  54.         [ResourceConsumption(ResourceScope.Machine)]
  55.         public DelimitedListTraceListener(string fileName, string name) : base(fileName, name)
  56.         {
  57.         }
  58.        
  59.         public string Delimiter {
  60.             get {
  61.                 lock (this) {
  62.                     // Probably overkill
  63.                     if (!initializedDelim) {
  64.                        
  65.                         if (Attributes.ContainsKey("delimiter"))
  66.                             delimiter = Attributes["delimiter"];
  67.                        
  68.                         initializedDelim = true;
  69.                     }
  70.                 }
  71.                 return delimiter;
  72.             }
  73.             set {
  74.                 if (value == null)
  75.                     throw new ArgumentNullException("Delimiter");
  76.                
  77.                 if (value.Length == 0)
  78.                     throw new ArgumentException(SR.GetString("Generic_ArgCantBeEmptyString", "Delimiter"));
  79.                
  80.                 lock (this) {
  81.                     delimiter = value;
  82.                     initializedDelim = true;
  83.                 }
  84.                
  85.                 if (delimiter == ",")
  86.                     secondaryDelim = ";";
  87.                 else
  88.                     secondaryDelim = ",";
  89.             }
  90.         }
  91.        
  92.         protected internal override string[] GetSupportedAttributes()
  93.         {
  94.             return new string[] {"delimiter"};
  95.         }
  96.        
  97.        
  98.         public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
  99.         {
  100.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, format, args))
  101.                 return;
  102.            
  103.             WriteHeader(source, eventType, id);
  104.            
  105.             if (args != null)
  106.                 WriteEscaped(String.Format(CultureInfo.InvariantCulture, format, args));
  107.             else
  108.                 WriteEscaped(format);
  109.             Write(Delimiter);
  110.             // Use get_Delimiter
  111.             // one more delimiter for the data object
  112.             Write(Delimiter);
  113.             // Use get_Delimiter
  114.             WriteFooter(eventCache);
  115.         }
  116.        
  117.         public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
  118.         {
  119.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, message))
  120.                 return;
  121.            
  122.             WriteHeader(source, eventType, id);
  123.            
  124.             WriteEscaped(message);
  125.             Write(Delimiter);
  126.             // Use get_Delimiter
  127.             // one more delimiter for the data object
  128.             Write(Delimiter);
  129.             // Use get_Delimiter
  130.             WriteFooter(eventCache);
  131.         }
  132.        
  133.         public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
  134.         {
  135.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data))
  136.                 return;
  137.            
  138.             WriteHeader(source, eventType, id);
  139.            
  140.             // first a delimiter for the message
  141.             Write(Delimiter);
  142.             // Use get_Delimiter
  143.             WriteEscaped(data.ToString());
  144.             Write(Delimiter);
  145.             // Use get_Delimiter
  146.             WriteFooter(eventCache);
  147.         }
  148.        
  149.         public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
  150.         {
  151.             if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
  152.                 return;
  153.            
  154.             WriteHeader(source, eventType, id);
  155.            
  156.             // first a delimiter for the message
  157.             Write(Delimiter);
  158.             // Use get_Delimiter
  159.             if (data != null) {
  160.                 for (int i = 0; i < data.Length; i++) {
  161.                     if (i != 0)
  162.                         Write(secondaryDelim);
  163.                     WriteEscaped(data[i].ToString());
  164.                 }
  165.             }
  166.             Write(Delimiter);
  167.             // Use get_Delimiter
  168.             WriteFooter(eventCache);
  169.         }
  170.        
  171.         private void WriteHeader(string source, TraceEventType eventType, int id)
  172.         {
  173.             WriteEscaped(source);
  174.             Write(Delimiter);
  175.             // Use get_Delimiter
  176.             Write(eventType.ToString());
  177.             Write(Delimiter);
  178.             // Use get_Delimiter
  179.             Write(id.ToString(CultureInfo.InvariantCulture));
  180.             Write(Delimiter);
  181.             // Use get_Delimiter
  182.         }
  183.        
  184.         private void WriteFooter(TraceEventCache eventCache)
  185.         {
  186.             if (eventCache != null) {
  187.                 if (IsEnabled(TraceOptions.ProcessId))
  188.                     Write(eventCache.ProcessId.ToString(CultureInfo.InvariantCulture));
  189.                 Write(Delimiter);
  190.                 // Use get_Delimiter
  191.                 if (IsEnabled(TraceOptions.LogicalOperationStack))
  192.                     WriteStackEscaped(eventCache.LogicalOperationStack);
  193.                 Write(Delimiter);
  194.                 // Use get_Delimiter
  195.                 if (IsEnabled(TraceOptions.ThreadId))
  196.                     WriteEscaped(eventCache.ThreadId.ToString(CultureInfo.InvariantCulture));
  197.                 Write(Delimiter);
  198.                 // Use get_Delimiter
  199.                 if (IsEnabled(TraceOptions.DateTime))
  200.                     WriteEscaped(eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture));
  201.                 Write(Delimiter);
  202.                 // Use get_Delimiter
  203.                 if (IsEnabled(TraceOptions.Timestamp))
  204.                     Write(eventCache.Timestamp.ToString(CultureInfo.InvariantCulture));
  205.                 Write(Delimiter);
  206.                 // Use get_Delimiter
  207.                 if (IsEnabled(TraceOptions.Callstack))
  208.                     WriteEscaped(eventCache.Callstack);
  209.             }
  210.             else {
  211.                 for (int i = 0; i < 5; i++)
  212.                     Write(Delimiter);
  213.                 // Use get_Delimiter
  214.             }
  215.            
  216.             WriteLine("");
  217.         }
  218.        
  219.         private void WriteEscaped(string message)
  220.         {
  221.             if (!String.IsNullOrEmpty(message)) {
  222.                 StringBuilder sb = new StringBuilder("\"");
  223.                 int index;
  224.                 int lastindex = 0;
  225.                 while ((index = message.IndexOf('"', lastindex)) != -1) {
  226.                     sb.Append(message, lastindex, index - lastindex);
  227.                     sb.Append("\"\"");
  228.                     lastindex = index + 1;
  229.                 }
  230.                
  231.                 sb.Append(message, lastindex, message.Length - lastindex);
  232.                 sb.Append("\"");
  233.                 Write(sb.ToString());
  234.             }
  235.         }
  236.        
  237.         private void WriteStackEscaped(Stack stack)
  238.         {
  239.             StringBuilder sb = new StringBuilder("\"");
  240.             bool first = true;
  241.             foreach (object obj in stack) {
  242.                 if (!first)
  243.                     sb.Append(", ");
  244.                 else
  245.                     first = false;
  246.                
  247.                 string operation = obj.ToString();
  248.                
  249.                 int index;
  250.                 int lastindex = 0;
  251.                 while ((index = operation.IndexOf('"', lastindex)) != -1) {
  252.                     sb.Append(operation, lastindex, index - lastindex);
  253.                     sb.Append("\"\"");
  254.                     lastindex = index + 1;
  255.                 }
  256.                
  257.                 sb.Append(operation, lastindex, operation.Length - lastindex);
  258.             }
  259.             sb.Append("\"");
  260.             Write(sb.ToString());
  261.         }
  262.        
  263.     }
  264. }

Developer Fusion