2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System / System.Diagnostics / TraceListener.cs
blob873a62343c63dd7e6c17524706b06f0ee1166874
1 //
2 // System.Diagnostics.TraceListener.cs
3 //
4 // Authors:
5 // Jonathan Pryor (jonpryor@vt.edu)
6 // Atsushi Enomoto (atsushi@ximian.com)
7 //
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:
23 //
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 //
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.
36 using System;
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 {
46 #if TARGET_JVM
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 {
54 get {
55 object o = System.Threading.Thread.GetData (_indentLevelStore);
56 if (o == null)
57 return 0;
58 return (int) o;
60 set { System.Threading.Thread.SetData (_indentLevelStore, value); }
63 private int indentSize {
64 get {
65 object o = System.Threading.Thread.GetData (_indentSizeStore);
66 if (o == null)
67 return 4;
68 return (int) o;
70 set { System.Threading.Thread.SetData (_indentSizeStore, value); }
73 #if NET_2_0
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 {
85 get {
86 object o = System.Threading.Thread.GetData (_optionsStore);
87 if (o == null)
88 return TraceOptions.None;
89 return (TraceOptions) o;
91 set { System.Threading.Thread.SetData (_optionsStore, value); }
93 #endif
94 #else
95 [ThreadStatic]
96 private int indentLevel = 0;
98 [ThreadStatic]
99 private int indentSize = 4;
101 #if NET_2_0
102 [ThreadStatic]
103 private StringDictionary attributes = new StringDictionary ();
104 [ThreadStatic]
105 private TraceFilter filter;
106 [ThreadStatic]
107 private TraceOptions options;
108 #endif
109 #endif
111 private string name;
112 private bool needIndent = true;
114 protected TraceListener () : this ("")
118 protected TraceListener (string name)
120 Name = 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 {
134 get {return name;}
135 set {name = value;}
138 protected bool NeedIndent {
139 get {return needIndent;}
140 set {needIndent = value;}
143 #if NET_2_0
144 [MonoLimitation ("This property exists but is never considered.")]
145 public virtual bool IsThreadSafe {
146 get { return false; }
148 #endif
150 public virtual void Close ()
152 Dispose ();
155 public void Dispose ()
157 Dispose (true);
158 GC.SuppressFinalize (this);
161 protected virtual void Dispose (bool disposing)
165 public virtual void Fail (string message)
167 Fail (message, "");
170 public virtual void Fail (string message, string detailMessage)
172 WriteLine ("---- DEBUG ASSERTION FAILED ----");
173 WriteLine ("---- Assert Short Message ----");
174 WriteLine (message);
175 WriteLine ("---- Assert Long Message ----");
176 WriteLine (detailMessage);
177 WriteLine ("");
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*
205 NeedIndent = false;
206 String indent = new String (' ', IndentLevel*IndentSize);
207 Write (indent);
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);
227 #if NET_2_0
228 internal static string FormatArray (ICollection list, string joiner)
230 string [] arr = new string [list.Count];
231 int i = 0;
232 foreach (object o in list)
233 arr [i++] = o != null ? o.ToString () : String.Empty;
234 return String.Join (joiner, arr);
237 [ComVisible (false)]
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))
244 return;
246 WriteLine (String.Format ("{0} {1}: {2} : {3}", source, eventType, id, data));
248 if (eventCache == null)
249 return;
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);
265 [ComVisible (false)]
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))
272 return;
274 TraceData (eventCache, source, eventType, id, FormatArray (data, " "));
277 [ComVisible (false)]
278 public virtual void TraceEvent (TraceEventCache eventCache, string source, TraceEventType eventType, int id)
280 TraceEvent (eventCache, source, eventType, id, null);
283 [ComVisible (false)]
284 public virtual void TraceEvent (TraceEventCache eventCache, string source, TraceEventType eventType,
285 int id, string message)
287 TraceData (eventCache, source, eventType, id, message);
290 [ComVisible (false)]
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));
296 [ComVisible (false)]
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 ()
304 return null;
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; }
322 #endif