1 //------------------------------------------------------------------------------
2 // <copyright file="TraceInternal.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Diagnostics {
8 using System.Threading;
10 using System.Security.Permissions;
11 using System.Collections;
13 internal static class TraceInternal {
14 private static volatile string appName = null;
15 static volatile TraceListenerCollection listeners;
16 static volatile bool autoFlush;
17 static volatile bool useGlobalLock;
19 static int indentLevel;
20 static volatile int indentSize;
21 static volatile bool settingsInitialized;
22 static volatile bool defaultInitialized;
25 // this is internal so TraceSource can use it. We want to lock on the same object because both TraceInternal and
26 // TraceSource could be writing to the same listeners at the same time.
27 internal static readonly object critSec = new object();
29 public static TraceListenerCollection Listeners {
32 if (listeners == null) {
34 if (listeners == null) {
35 // We only need to check that the main section exists. Everything else will get
36 // created for us if it doesn't exist already.
38 SystemDiagnosticsSection configSectionSav = DiagnosticsConfiguration.SystemDiagnosticsSection;
39 if (configSectionSav != null) {
40 listeners = configSectionSav.Trace.Listeners.GetRuntimeObject();
44 // If machine.config was deleted the code will get to here
45 // supply at least something to prevent the world from coming to
47 listeners = new TraceListenerCollection();
48 TraceListener defaultListener = new DefaultTraceListener();
49 defaultListener.IndentLevel = indentLevel;
50 defaultListener.IndentSize = indentSize;
51 listeners.Add(defaultListener);
62 internal static string AppName {
64 if (appName == null) {
66 new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Assert();
68 appName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
74 public static bool AutoFlush {
86 public static bool UseGlobalLock {
94 useGlobalLock = value;
98 public static int IndentLevel {
99 get { return indentLevel; }
104 // We don't want to throw here -- it is very bad form to have debug or trace
105 // code throw exceptions!
111 if (listeners != null) {
112 foreach (TraceListener listener in Listeners) {
113 listener.IndentLevel = indentLevel;
120 public static int IndentSize {
122 InitializeSettings();
127 InitializeSettings();
128 SetIndentSize(value);
132 static void SetIndentSize(int value) {
135 // We don't want to throw here -- it is very bad form to have debug or trace
136 // code throw exceptions!
143 if (listeners != null) {
144 foreach (TraceListener listener in Listeners) {
145 listener.IndentSize = indentSize;
151 public static void Indent() {
154 InitializeSettings();
155 if (indentLevel < Int32.MaxValue) {
158 foreach (TraceListener listener in Listeners) {
159 listener.IndentLevel = indentLevel;
164 public static void Unindent() {
167 InitializeSettings();
168 if (indentLevel > 0) {
171 foreach (TraceListener listener in Listeners) {
172 listener.IndentLevel = indentLevel;
177 public static void Flush() {
178 if (listeners != null) {
181 foreach (TraceListener listener in Listeners) {
187 foreach (TraceListener listener in Listeners) {
188 if (!listener.IsThreadSafe) {
201 public static void Close() {
202 if (listeners != null) {
205 foreach (TraceListener listener in Listeners) {
212 public static void Assert(bool condition) {
213 if (condition) return;
217 public static void Assert(bool condition, string message) {
218 if (condition) return;
222 public static void Assert(bool condition, string message, string detailMessage) {
223 if (condition) return;
224 Fail(message, detailMessage);
227 public static void Fail(string message) {
230 foreach (TraceListener listener in Listeners) {
231 listener.Fail(message);
232 if (AutoFlush) listener.Flush();
237 foreach (TraceListener listener in Listeners) {
238 if (!listener.IsThreadSafe) {
240 listener.Fail(message);
241 if (AutoFlush) listener.Flush();
245 listener.Fail(message);
246 if (AutoFlush) listener.Flush();
252 public static void Fail(string message, string detailMessage) {
255 foreach (TraceListener listener in Listeners) {
256 listener.Fail(message, detailMessage);
257 if (AutoFlush) listener.Flush();
262 foreach (TraceListener listener in Listeners) {
263 if (!listener.IsThreadSafe) {
265 listener.Fail(message, detailMessage);
266 if (AutoFlush) listener.Flush();
270 listener.Fail(message, detailMessage);
271 if (AutoFlush) listener.Flush();
277 private static void InitializeSettings() {
278 #if CONFIGURATION_DEP
279 // we want to redo this logic exactly once if the last time we entered the config
280 // system was still initializing. (ASURT 111941, VSWhidbey 149552)
281 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
282 // we should avoid 2 threads altering the state concurrently for predictable behavior
283 // though it may not be strictly necessary at present
285 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
286 defaultInitialized = DiagnosticsConfiguration.IsInitializing();
288 // Getting IndentSize and AutoFlush will load config on demand.
289 // If we load config and there are trace listeners added, we'll
290 // end up recursing, but that recursion will be stopped in
291 // DiagnosticsConfiguration.Initialize()
292 SetIndentSize(DiagnosticsConfiguration.IndentSize);
293 autoFlush = DiagnosticsConfiguration.AutoFlush;
294 useGlobalLock = DiagnosticsConfiguration.UseGlobalLock;
295 settingsInitialized = true;
302 // This method refreshes all the data from the configuration file, so that updated to the configuration file are mirrored
303 // in the System.Diagnostics.Trace class
304 static internal void Refresh() {
306 settingsInitialized = false;
309 InitializeSettings();
312 public static void TraceEvent(TraceEventType eventType, int id, string format, params object[] args) {
314 TraceEventCache EventCache = new TraceEventCache();
319 foreach (TraceListener listener in Listeners) {
320 listener.TraceEvent(EventCache, AppName, eventType, id, format);
321 if (AutoFlush) listener.Flush();
325 foreach (TraceListener listener in Listeners) {
326 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
327 if (AutoFlush) listener.Flush();
334 foreach (TraceListener listener in Listeners) {
335 if (!listener.IsThreadSafe) {
337 listener.TraceEvent(EventCache, AppName, eventType, id, format);
338 if (AutoFlush) listener.Flush();
342 listener.TraceEvent(EventCache, AppName, eventType, id, format);
343 if (AutoFlush) listener.Flush();
348 foreach (TraceListener listener in Listeners) {
349 if (!listener.IsThreadSafe) {
351 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
352 if (AutoFlush) listener.Flush();
356 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
357 if (AutoFlush) listener.Flush();
365 public static void Write(string message) {
368 foreach (TraceListener listener in Listeners) {
369 listener.Write(message);
370 if (AutoFlush) listener.Flush();
375 foreach (TraceListener listener in Listeners) {
376 if (!listener.IsThreadSafe) {
378 listener.Write(message);
379 if (AutoFlush) listener.Flush();
383 listener.Write(message);
384 if (AutoFlush) listener.Flush();
390 public static void Write(object value) {
393 foreach (TraceListener listener in Listeners) {
394 listener.Write(value);
395 if (AutoFlush) listener.Flush();
400 foreach (TraceListener listener in Listeners) {
401 if (!listener.IsThreadSafe) {
403 listener.Write(value);
404 if (AutoFlush) listener.Flush();
408 listener.Write(value);
409 if (AutoFlush) listener.Flush();
415 public static void Write(string message, string category) {
418 foreach (TraceListener listener in Listeners) {
419 listener.Write(message, category);
420 if (AutoFlush) listener.Flush();
425 foreach (TraceListener listener in Listeners) {
426 if (!listener.IsThreadSafe) {
428 listener.Write(message, category);
429 if (AutoFlush) listener.Flush();
433 listener.Write(message, category);
434 if (AutoFlush) listener.Flush();
440 public static void Write(object value, string category) {
443 foreach (TraceListener listener in Listeners) {
444 listener.Write(value, category);
445 if (AutoFlush) listener.Flush();
450 foreach (TraceListener listener in Listeners) {
451 if (!listener.IsThreadSafe) {
453 listener.Write(value, category);
454 if (AutoFlush) listener.Flush();
458 listener.Write(value, category);
459 if (AutoFlush) listener.Flush();
465 public static void WriteLine(string message) {
468 foreach (TraceListener listener in Listeners) {
469 listener.WriteLine(message);
470 if (AutoFlush) listener.Flush();
475 foreach (TraceListener listener in Listeners) {
476 if (!listener.IsThreadSafe) {
478 listener.WriteLine(message);
479 if (AutoFlush) listener.Flush();
483 listener.WriteLine(message);
484 if (AutoFlush) listener.Flush();
490 public static void WriteLine(object value) {
493 foreach (TraceListener listener in Listeners) {
494 listener.WriteLine(value);
495 if (AutoFlush) listener.Flush();
500 foreach (TraceListener listener in Listeners) {
501 if (!listener.IsThreadSafe) {
503 listener.WriteLine(value);
504 if (AutoFlush) listener.Flush();
508 listener.WriteLine(value);
509 if (AutoFlush) listener.Flush();
515 public static void WriteLine(string message, string category) {
518 foreach (TraceListener listener in Listeners) {
519 listener.WriteLine(message, category);
520 if (AutoFlush) listener.Flush();
525 foreach (TraceListener listener in Listeners) {
526 if (!listener.IsThreadSafe) {
528 listener.WriteLine(message, category);
529 if (AutoFlush) listener.Flush();
533 listener.WriteLine(message, category);
534 if (AutoFlush) listener.Flush();
540 public static void WriteLine(object value, string category) {
543 foreach (TraceListener listener in Listeners) {
544 listener.WriteLine(value, category);
545 if (AutoFlush) listener.Flush();
550 foreach (TraceListener listener in Listeners) {
551 if (!listener.IsThreadSafe) {
553 listener.WriteLine(value, category);
554 if (AutoFlush) listener.Flush();
558 listener.WriteLine(value, category);
559 if (AutoFlush) listener.Flush();
565 public static void WriteIf(bool condition, string message) {
570 public static void WriteIf(bool condition, object value) {
575 public static void WriteIf(bool condition, string message, string category) {
577 Write(message, category);
580 public static void WriteIf(bool condition, object value, string category) {
582 Write(value, category);
585 public static void WriteLineIf(bool condition, string message) {
590 public static void WriteLineIf(bool condition, object value) {
595 public static void WriteLineIf(bool condition, string message, string category) {
597 WriteLine(message, category);
600 public static void WriteLineIf(bool condition, object value, string category) {
602 WriteLine(value, category);