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;
22 static volatile bool settingsInitialized;
23 static volatile bool defaultInitialized;
27 // this is internal so TraceSource can use it. We want to lock on the same object because both TraceInternal and
28 // TraceSource could be writing to the same listeners at the same time.
29 internal static readonly object critSec = new object();
31 public static TraceListenerCollection Listeners {
34 if (listeners == null) {
36 if (listeners == null) {
37 // We only need to check that the main section exists. Everything else will get
38 // created for us if it doesn't exist already.
40 SystemDiagnosticsSection configSectionSav = DiagnosticsConfiguration.SystemDiagnosticsSection;
41 if (configSectionSav != null) {
42 listeners = configSectionSav.Trace.Listeners.GetRuntimeObject();
46 // If machine.config was deleted the code will get to here
47 // supply at least something to prevent the world from coming to
49 listeners = new TraceListenerCollection();
50 TraceListener defaultListener = new DefaultTraceListener();
51 defaultListener.IndentLevel = indentLevel;
52 defaultListener.IndentSize = indentSize;
53 listeners.Add(defaultListener);
64 internal static string AppName {
66 if (appName == null) {
68 new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Assert();
70 appName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
76 public static bool AutoFlush {
88 public static bool UseGlobalLock {
96 useGlobalLock = value;
100 public static int IndentLevel {
101 get { return indentLevel; }
106 // We don't want to throw here -- it is very bad form to have debug or trace
107 // code throw exceptions!
113 if (listeners != null) {
114 foreach (TraceListener listener in Listeners) {
115 listener.IndentLevel = indentLevel;
122 public static int IndentSize {
124 InitializeSettings();
129 InitializeSettings();
130 SetIndentSize(value);
134 static void SetIndentSize(int value) {
137 // We don't want to throw here -- it is very bad form to have debug or trace
138 // code throw exceptions!
145 if (listeners != null) {
146 foreach (TraceListener listener in Listeners) {
147 listener.IndentSize = indentSize;
153 public static void Indent() {
156 InitializeSettings();
157 if (indentLevel < Int32.MaxValue) {
160 foreach (TraceListener listener in Listeners) {
161 listener.IndentLevel = indentLevel;
166 public static void Unindent() {
169 InitializeSettings();
170 if (indentLevel > 0) {
173 foreach (TraceListener listener in Listeners) {
174 listener.IndentLevel = indentLevel;
179 public static void Flush() {
180 if (listeners != null) {
183 foreach (TraceListener listener in Listeners) {
189 foreach (TraceListener listener in Listeners) {
190 if (!listener.IsThreadSafe) {
203 public static void Close() {
204 if (listeners != null) {
207 foreach (TraceListener listener in Listeners) {
214 public static void Assert(bool condition) {
215 if (condition) return;
219 public static void Assert(bool condition, string message) {
220 if (condition) return;
224 public static void Assert(bool condition, string message, string detailMessage) {
225 if (condition) return;
226 Fail(message, detailMessage);
229 public static void Fail(string message) {
232 foreach (TraceListener listener in Listeners) {
233 listener.Fail(message);
234 if (AutoFlush) listener.Flush();
239 foreach (TraceListener listener in Listeners) {
240 if (!listener.IsThreadSafe) {
242 listener.Fail(message);
243 if (AutoFlush) listener.Flush();
247 listener.Fail(message);
248 if (AutoFlush) listener.Flush();
254 public static void Fail(string message, string detailMessage) {
257 foreach (TraceListener listener in Listeners) {
258 listener.Fail(message, detailMessage);
259 if (AutoFlush) listener.Flush();
264 foreach (TraceListener listener in Listeners) {
265 if (!listener.IsThreadSafe) {
267 listener.Fail(message, detailMessage);
268 if (AutoFlush) listener.Flush();
272 listener.Fail(message, detailMessage);
273 if (AutoFlush) listener.Flush();
279 private static void InitializeSettings() {
280 #if CONFIGURATION_DEP
281 // we want to redo this logic exactly once if the last time we entered the config
282 // system was still initializing. (ASURT 111941, VSWhidbey 149552)
283 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
284 // we should avoid 2 threads altering the state concurrently for predictable behavior
285 // though it may not be strictly necessary at present
287 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
288 defaultInitialized = DiagnosticsConfiguration.IsInitializing();
290 // Getting IndentSize and AutoFlush will load config on demand.
291 // If we load config and there are trace listeners added, we'll
292 // end up recursing, but that recursion will be stopped in
293 // DiagnosticsConfiguration.Initialize()
294 SetIndentSize(DiagnosticsConfiguration.IndentSize);
295 autoFlush = DiagnosticsConfiguration.AutoFlush;
296 useGlobalLock = DiagnosticsConfiguration.UseGlobalLock;
297 settingsInitialized = true;
304 // This method refreshes all the data from the configuration file, so that updated to the configuration file are mirrored
305 // in the System.Diagnostics.Trace class
306 static internal void Refresh() {
308 #if CONFIGURATION_DEP
309 settingsInitialized = false;
313 InitializeSettings();
316 public static void TraceEvent(TraceEventType eventType, int id, string format, params object[] args) {
318 TraceEventCache EventCache = new TraceEventCache();
323 foreach (TraceListener listener in Listeners) {
324 listener.TraceEvent(EventCache, AppName, eventType, id, format);
325 if (AutoFlush) listener.Flush();
329 foreach (TraceListener listener in Listeners) {
330 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
331 if (AutoFlush) listener.Flush();
338 foreach (TraceListener listener in Listeners) {
339 if (!listener.IsThreadSafe) {
341 listener.TraceEvent(EventCache, AppName, eventType, id, format);
342 if (AutoFlush) listener.Flush();
346 listener.TraceEvent(EventCache, AppName, eventType, id, format);
347 if (AutoFlush) listener.Flush();
352 foreach (TraceListener listener in Listeners) {
353 if (!listener.IsThreadSafe) {
355 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
356 if (AutoFlush) listener.Flush();
360 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
361 if (AutoFlush) listener.Flush();
369 public static void Write(string message) {
372 foreach (TraceListener listener in Listeners) {
373 listener.Write(message);
374 if (AutoFlush) listener.Flush();
379 foreach (TraceListener listener in Listeners) {
380 if (!listener.IsThreadSafe) {
382 listener.Write(message);
383 if (AutoFlush) listener.Flush();
387 listener.Write(message);
388 if (AutoFlush) listener.Flush();
394 public static void Write(object value) {
397 foreach (TraceListener listener in Listeners) {
398 listener.Write(value);
399 if (AutoFlush) listener.Flush();
404 foreach (TraceListener listener in Listeners) {
405 if (!listener.IsThreadSafe) {
407 listener.Write(value);
408 if (AutoFlush) listener.Flush();
412 listener.Write(value);
413 if (AutoFlush) listener.Flush();
419 public static void Write(string message, string category) {
422 foreach (TraceListener listener in Listeners) {
423 listener.Write(message, category);
424 if (AutoFlush) listener.Flush();
429 foreach (TraceListener listener in Listeners) {
430 if (!listener.IsThreadSafe) {
432 listener.Write(message, category);
433 if (AutoFlush) listener.Flush();
437 listener.Write(message, category);
438 if (AutoFlush) listener.Flush();
444 public static void Write(object value, string category) {
447 foreach (TraceListener listener in Listeners) {
448 listener.Write(value, category);
449 if (AutoFlush) listener.Flush();
454 foreach (TraceListener listener in Listeners) {
455 if (!listener.IsThreadSafe) {
457 listener.Write(value, category);
458 if (AutoFlush) listener.Flush();
462 listener.Write(value, category);
463 if (AutoFlush) listener.Flush();
469 public static void WriteLine(string message) {
472 foreach (TraceListener listener in Listeners) {
473 listener.WriteLine(message);
474 if (AutoFlush) listener.Flush();
479 foreach (TraceListener listener in Listeners) {
480 if (!listener.IsThreadSafe) {
482 listener.WriteLine(message);
483 if (AutoFlush) listener.Flush();
487 listener.WriteLine(message);
488 if (AutoFlush) listener.Flush();
494 public static void WriteLine(object value) {
497 foreach (TraceListener listener in Listeners) {
498 listener.WriteLine(value);
499 if (AutoFlush) listener.Flush();
504 foreach (TraceListener listener in Listeners) {
505 if (!listener.IsThreadSafe) {
507 listener.WriteLine(value);
508 if (AutoFlush) listener.Flush();
512 listener.WriteLine(value);
513 if (AutoFlush) listener.Flush();
519 public static void WriteLine(string message, string category) {
522 foreach (TraceListener listener in Listeners) {
523 listener.WriteLine(message, category);
524 if (AutoFlush) listener.Flush();
529 foreach (TraceListener listener in Listeners) {
530 if (!listener.IsThreadSafe) {
532 listener.WriteLine(message, category);
533 if (AutoFlush) listener.Flush();
537 listener.WriteLine(message, category);
538 if (AutoFlush) listener.Flush();
544 public static void WriteLine(object value, string category) {
547 foreach (TraceListener listener in Listeners) {
548 listener.WriteLine(value, category);
549 if (AutoFlush) listener.Flush();
554 foreach (TraceListener listener in Listeners) {
555 if (!listener.IsThreadSafe) {
557 listener.WriteLine(value, category);
558 if (AutoFlush) listener.Flush();
562 listener.WriteLine(value, category);
563 if (AutoFlush) listener.Flush();
569 public static void WriteIf(bool condition, string message) {
574 public static void WriteIf(bool condition, object value) {
579 public static void WriteIf(bool condition, string message, string category) {
581 Write(message, category);
584 public static void WriteIf(bool condition, object value, string category) {
586 Write(value, category);
589 public static void WriteLineIf(bool condition, string message) {
594 public static void WriteLineIf(bool condition, object value) {
599 public static void WriteLineIf(bool condition, string message, string category) {
601 WriteLine(message, category);
604 public static void WriteLineIf(bool condition, object value, string category) {
606 WriteLine(value, category);