2 // System.Diagnostics.TraceListener.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
6 // Atsushi Enomoto (atsushi@ximian.com)
8 // Comments from John R. Hicks <angryjohn69@nc.rr.com> original implementation
9 // can be found at: /mcs/docs/apidocs/xml/en/System.Diagnostics
11 // (C) 2002 Jonathan Pryor
12 // (C) 2007 Novell, Inc.
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System
.Collections
;
38 using System
.Collections
.Specialized
;
39 using System
.Runtime
.InteropServices
;
40 using System
.Diagnostics
;
42 namespace System
.Diagnostics
{
44 public abstract class TraceListener
: MarshalByRefObject
, IDisposable
{
47 readonly LocalDataStoreSlot _indentLevelStore
= System
.Threading
.Thread
.AllocateDataSlot ();
48 readonly LocalDataStoreSlot _indentSizeStore
= System
.Threading
.Thread
.AllocateDataSlot ();
49 readonly LocalDataStoreSlot _attributesStore
= System
.Threading
.Thread
.AllocateDataSlot ();
50 readonly LocalDataStoreSlot _filterStore
= System
.Threading
.Thread
.AllocateDataSlot ();
51 readonly LocalDataStoreSlot _optionsStore
= System
.Threading
.Thread
.AllocateDataSlot ();
53 private int indentLevel
{
55 object o
= System
.Threading
.Thread
.GetData (_indentLevelStore
);
60 set { System.Threading.Thread.SetData (_indentLevelStore, value); }
63 private int indentSize
{
65 object o
= System
.Threading
.Thread
.GetData (_indentSizeStore
);
70 set { System.Threading.Thread.SetData (_indentSizeStore, value); }
74 private StringDictionary attributes
{
75 get { return (StringDictionary) System.Threading.Thread.GetData (_attributesStore); }
76 set { System.Threading.Thread.SetData (_attributesStore, value); }
79 private TraceFilter filter
{
80 get { return (TraceFilter) System.Threading.Thread.GetData (_filterStore); }
81 set { System.Threading.Thread.SetData (_filterStore, value); }
84 private TraceOptions options
{
86 object o
= System
.Threading
.Thread
.GetData (_optionsStore
);
88 return TraceOptions
.None
;
89 return (TraceOptions
) o
;
91 set { System.Threading.Thread.SetData (_optionsStore, value); }
96 private int indentLevel
= 0;
99 private int indentSize
= 4;
103 private StringDictionary attributes
= new StringDictionary ();
105 private TraceFilter filter
;
107 private TraceOptions options
;
112 private bool needIndent
= true;
114 protected TraceListener () : this ("")
118 protected TraceListener (string name
)
123 public int IndentLevel
{
124 get {return indentLevel;}
125 set {indentLevel = value;}
128 public int IndentSize
{
129 get {return indentSize;}
130 set {indentSize = value;}
133 public virtual string Name
{
138 protected bool NeedIndent
{
139 get {return needIndent;}
140 set {needIndent = value;}
144 [MonoLimitation ("This property exists but is never considered.")]
145 public virtual bool IsThreadSafe
{
146 get { return false; }
150 public virtual void Close ()
155 public void Dispose ()
158 GC
.SuppressFinalize (this);
161 protected virtual void Dispose (bool disposing
)
165 public virtual void Fail (string message
)
170 public virtual void Fail (string message
, string detailMessage
)
172 WriteLine ("---- DEBUG ASSERTION FAILED ----");
173 WriteLine ("---- Assert Short Message ----");
175 WriteLine ("---- Assert Long Message ----");
176 WriteLine (detailMessage
);
180 public virtual void Flush ()
184 public virtual void Write (object o
)
186 Write (o
.ToString());
189 public abstract void Write (string message
);
191 public virtual void Write (object o
, string category
)
193 Write (o
.ToString(), category
);
196 public virtual void Write (string message
, string category
)
198 Write (category
+ ": " + message
);
201 protected virtual void WriteIndent ()
203 // Must set NeedIndent to false before Write; otherwise, we get endless
204 // recursion with Write->WriteIndent->Write->WriteIndent...*boom*
206 String indent
= new String (' ', IndentLevel
*IndentSize
);
210 public virtual void WriteLine (object o
)
212 WriteLine (o
.ToString());
215 public abstract void WriteLine (string message
);
217 public virtual void WriteLine (object o
, string category
)
219 WriteLine (o
.ToString(), category
);
222 public virtual void WriteLine (string message
, string category
)
224 WriteLine (category
+ ": " + message
);
228 internal static string FormatArray (ICollection list
, string joiner
)
230 string [] arr
= new string [list
.Count
];
232 foreach (object o
in list
)
233 arr
[i
++] = o
!= null ? o
.ToString () : String
.Empty
;
234 return String
.Join (joiner
, arr
);
238 public virtual void TraceData (TraceEventCache eventCache
, string source
,
239 TraceEventType eventType
, int id
, object data
)
241 if (Filter
!= null &&
242 !Filter
.ShouldTrace (eventCache
, source
, eventType
,
243 id
, null, null, data
, null))
246 WriteLine (String
.Format ("{0} {1}: {2} : {3}", source
, eventType
, id
, data
));
248 if (eventCache
== null)
251 if ((TraceOutputOptions
& TraceOptions
.ProcessId
) != 0)
252 WriteLine (" ProcessId=" + eventCache
.ProcessId
);
253 if ((TraceOutputOptions
& TraceOptions
.LogicalOperationStack
) != 0)
254 WriteLine (" LogicalOperationStack=" + FormatArray (eventCache
.LogicalOperationStack
, ", "));
255 if ((TraceOutputOptions
& TraceOptions
.ThreadId
) != 0)
256 WriteLine (" ThreadId=" + eventCache
.ThreadId
);
257 if ((TraceOutputOptions
& TraceOptions
.DateTime
) != 0)
258 WriteLine (" DateTime=" + eventCache
.DateTime
.ToString ("o"));
259 if ((TraceOutputOptions
& TraceOptions
.Timestamp
) != 0)
260 WriteLine (" Timestamp=" + eventCache
.Timestamp
);
261 if ((TraceOutputOptions
& TraceOptions
.Callstack
) != 0)
262 WriteLine (" Callstack=" + eventCache
.Callstack
);
266 public virtual void TraceData (TraceEventCache eventCache
, string source
,
267 TraceEventType eventType
, int id
, params object [] data
)
269 if (Filter
!= null &&
270 !Filter
.ShouldTrace (eventCache
, source
, eventType
,
271 id
, null, null, null, data
))
274 TraceData (eventCache
, source
, eventType
, id
, FormatArray (data
, " "));
278 public virtual void TraceEvent (TraceEventCache eventCache
, string source
, TraceEventType eventType
, int id
)
280 TraceEvent (eventCache
, source
, eventType
, id
, null);
284 public virtual void TraceEvent (TraceEventCache eventCache
, string source
, TraceEventType eventType
,
285 int id
, string message
)
287 TraceData (eventCache
, source
, eventType
, id
, message
);
291 public virtual void TraceEvent (TraceEventCache eventCache
, string source
, TraceEventType eventType
, int id
, string format
, params object [] args
)
293 TraceEvent (eventCache
, source
, eventType
, id
, String
.Format (format
, args
));
297 public virtual void TraceTransfer (TraceEventCache eventCache
, string source
, int id
, string message
, Guid relatedActivityId
)
299 TraceEvent (eventCache
, source
, TraceEventType
.Transfer
, id
, String
.Format ("{0}, relatedActivityId={1}", message
, relatedActivityId
));
302 protected internal virtual string [] GetSupportedAttributes ()
307 public StringDictionary Attributes
{
308 get { return attributes; }
311 [ComVisibleAttribute (false)]
312 public TraceFilter Filter
{
313 get { return filter; }
314 set { filter = value; }
317 [ComVisibleAttribute (false)]
318 public TraceOptions TraceOutputOptions
{
319 get { return options; }
320 set { options = value; }