2 // System.Diagnostics.TraceImpl.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2002, 2005 Jonathan Pryor
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
34 using System
.Diagnostics
;
35 using System
.Configuration
;
36 using System
.Threading
;
38 namespace System
.Diagnostics
{
40 internal class TraceImplSettings
{
41 public const string Key
= ".__TraceInfoSettingsKey__.";
43 public bool AutoFlush
;
44 public int IndentLevel
, IndentSize
= 4;
45 public TraceListenerCollection Listeners
= new TraceListenerCollection (false);
47 public TraceImplSettings ()
49 Listeners
.Add (new DefaultTraceListener (), this);
53 internal class TraceImpl
{
55 private static object initLock
= new object ();
57 private static bool autoFlush
;
60 static readonly LocalDataStoreSlot _indentLevelStore
= System
.Threading
.Thread
.AllocateDataSlot ();
61 static readonly LocalDataStoreSlot _indentSizeStore
= System
.Threading
.Thread
.AllocateDataSlot ();
63 private static int indentLevel
{
65 object o
= System
.Threading
.Thread
.GetData (_indentLevelStore
);
70 set { System.Threading.Thread.SetData (_indentLevelStore, value); }
73 private static int indentSize
{
75 object o
= System
.Threading
.Thread
.GetData (_indentSizeStore
);
80 set { System.Threading.Thread.SetData (_indentSizeStore, value); }
84 private static int indentLevel
= 0;
87 private static int indentSize
;
94 public static bool AutoFlush
{
105 public static int IndentLevel
{
111 lock (ListenersSyncRoot
) {
114 foreach (TraceListener t
in Listeners
) {
115 t
.IndentLevel
= indentLevel
;
121 public static int IndentSize
{
127 lock (ListenersSyncRoot
) {
130 foreach (TraceListener t
in Listeners
) {
131 t
.IndentSize
= indentSize
;
137 private static TraceListenerCollection listeners
;
139 public static TraceListenerCollection Listeners
{
147 private static object ListenersSyncRoot
{
149 return ((ICollection
) Listeners
).SyncRoot
;
153 static bool use_global_lock
;
155 static CorrelationManager correlation_manager
= new CorrelationManager ();
157 public static CorrelationManager CorrelationManager
{
160 return correlation_manager
;
165 [MonoLimitation ("the property exists but it does nothing.")]
166 public static bool UseGlobalLock
{
169 return use_global_lock
;
173 use_global_lock
= value;
177 // Initialize the world.
179 // This logically belongs in the static constructor (as it only needs
180 // to be done once), except for one thing: if the .config file has a
181 // syntax error, .NET throws a ConfigurationException. If we read the
182 // .config file in the static ctor, we throw a ConfigurationException
183 // from the static ctor, which results in a TypeLoadException. Oops.
184 // Reading the .config file here will allow the static ctor to
185 // complete successfully, allowing us to throw a normal
186 // ConfigurationException should the .config file contain an error.
188 // There are also some ordering issues.
190 // DiagnosticsConfigurationHandler doesn't store values within TraceImpl,
191 // but instead stores values it reads from the .config file within a
192 // TraceImplSettings object (accessible via the TraceImplSettings.Key key
193 // in the IDictionary returned).
194 private static void InitOnce ()
196 if (initLock
!= null) {
198 if (listeners
== null) {
199 IDictionary d
= DiagnosticsConfiguration
.Settings
;
200 TraceImplSettings s
= (TraceImplSettings
) d
[TraceImplSettings
.Key
];
202 d
.Remove (TraceImplSettings
.Key
);
204 autoFlush
= s
.AutoFlush
;
205 indentLevel
= s
.IndentLevel
;
206 indentSize
= s
.IndentSize
;
207 listeners
= s
.Listeners
;
214 // FIXME: According to MSDN, this method should display a dialog box
216 public static void Assert (bool condition
)
219 Fail (new StackTrace(true).ToString());
222 // FIXME: According to MSDN, this method should display a dialog box
224 public static void Assert (bool condition
, string message
)
230 // FIXME: According to MSDN, this method should display a dialog box
232 public static void Assert (bool condition
, string message
,
233 string detailMessage
)
236 Fail (message
, detailMessage
);
239 public static void Close ()
241 lock (ListenersSyncRoot
) {
242 foreach (TraceListener listener
in Listeners
) {
248 // FIXME: From testing .NET, this method should display a dialog
249 //(it probably depends on the listener)p
251 public static void Fail (string message
)
253 lock (ListenersSyncRoot
) {
254 foreach (TraceListener listener
in Listeners
) {
255 listener
.Fail (message
);
260 // FIXME: From testing .NET, this method should display a dialog
261 // (it probably depends on the listener)p
263 public static void Fail (string message
, string detailMessage
)
265 lock (ListenersSyncRoot
) {
266 foreach (TraceListener listener
in Listeners
) {
267 listener
.Fail (message
, detailMessage
);
272 public static void Flush ()
274 lock (ListenersSyncRoot
) {
275 foreach (TraceListener listener
in Listeners
){
281 public static void Indent ()
286 public static void Unindent ()
291 public static void Write (object value)
293 lock (ListenersSyncRoot
) {
294 foreach (TraceListener listener
in Listeners
) {
295 listener
.Write (value);
303 public static void Write (string message
)
305 lock (ListenersSyncRoot
) {
306 foreach (TraceListener listener
in Listeners
) {
307 listener
.Write (message
);
315 public static void Write (object value, string category
)
317 lock (ListenersSyncRoot
) {
318 foreach (TraceListener listener
in Listeners
) {
319 listener
.Write (value, category
);
327 public static void Write (string message
, string category
)
329 lock (ListenersSyncRoot
) {
330 foreach (TraceListener listener
in Listeners
) {
331 listener
.Write (message
, category
);
339 public static void WriteIf (bool condition
, object value)
345 public static void WriteIf (bool condition
, string message
)
351 public static void WriteIf (bool condition
, object value,
355 Write (value, category
);
358 public static void WriteIf (bool condition
, string message
,
362 Write (message
, category
);
365 public static void WriteLine (object value)
367 lock (ListenersSyncRoot
) {
368 foreach (TraceListener listener
in Listeners
) {
369 listener
.WriteLine (value);
377 public static void WriteLine (string message
)
379 lock (ListenersSyncRoot
) {
380 foreach (TraceListener listener
in Listeners
) {
381 listener
.WriteLine (message
);
389 public static void WriteLine (object value, string category
)
391 lock (ListenersSyncRoot
) {
392 foreach (TraceListener listener
in Listeners
) {
393 listener
.WriteLine (value, category
);
401 public static void WriteLine (string message
, string category
)
403 lock (ListenersSyncRoot
) {
404 foreach (TraceListener listener
in Listeners
) {
405 listener
.WriteLine (message
, category
);
413 public static void WriteLineIf (bool condition
, object value)
419 public static void WriteLineIf (bool condition
, string message
)
425 public static void WriteLineIf (bool condition
, object value,
429 WriteLine (value, category
);
432 public static void WriteLineIf (bool condition
, string message
,
436 WriteLine (message
, category
);