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) {
65 new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Assert();
66 appName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
72 public static bool AutoFlush {
84 public static bool UseGlobalLock {
92 useGlobalLock = value;
96 public static int IndentLevel {
97 get { return indentLevel; }
102 // We don't want to throw here -- it is very bad form to have debug or trace
103 // code throw exceptions!
109 if (listeners != null) {
110 foreach (TraceListener listener in Listeners) {
111 listener.IndentLevel = indentLevel;
118 public static int IndentSize {
120 InitializeSettings();
125 InitializeSettings();
126 SetIndentSize(value);
130 static void SetIndentSize(int value) {
133 // We don't want to throw here -- it is very bad form to have debug or trace
134 // code throw exceptions!
141 if (listeners != null) {
142 foreach (TraceListener listener in Listeners) {
143 listener.IndentSize = indentSize;
149 public static void Indent() {
152 InitializeSettings();
153 if (indentLevel < Int32.MaxValue) {
156 foreach (TraceListener listener in Listeners) {
157 listener.IndentLevel = indentLevel;
162 public static void Unindent() {
165 InitializeSettings();
166 if (indentLevel > 0) {
169 foreach (TraceListener listener in Listeners) {
170 listener.IndentLevel = indentLevel;
175 public static void Flush() {
176 if (listeners != null) {
179 foreach (TraceListener listener in Listeners) {
185 foreach (TraceListener listener in Listeners) {
186 if (!listener.IsThreadSafe) {
199 public static void Close() {
200 if (listeners != null) {
203 foreach (TraceListener listener in Listeners) {
210 public static void Assert(bool condition) {
211 if (condition) return;
215 public static void Assert(bool condition, string message) {
216 if (condition) return;
220 public static void Assert(bool condition, string message, string detailMessage) {
221 if (condition) return;
222 Fail(message, detailMessage);
225 public static void Fail(string message) {
228 foreach (TraceListener listener in Listeners) {
229 listener.Fail(message);
230 if (AutoFlush) listener.Flush();
235 foreach (TraceListener listener in Listeners) {
236 if (!listener.IsThreadSafe) {
238 listener.Fail(message);
239 if (AutoFlush) listener.Flush();
243 listener.Fail(message);
244 if (AutoFlush) listener.Flush();
250 public static void Fail(string message, string detailMessage) {
253 foreach (TraceListener listener in Listeners) {
254 listener.Fail(message, detailMessage);
255 if (AutoFlush) listener.Flush();
260 foreach (TraceListener listener in Listeners) {
261 if (!listener.IsThreadSafe) {
263 listener.Fail(message, detailMessage);
264 if (AutoFlush) listener.Flush();
268 listener.Fail(message, detailMessage);
269 if (AutoFlush) listener.Flush();
275 private static void InitializeSettings() {
276 #if CONFIGURATION_DEP
277 // we want to redo this logic exactly once if the last time we entered the config
278 // system was still initializing. (ASURT 111941, VSWhidbey 149552)
279 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
280 // we should avoid 2 threads altering the state concurrently for predictable behavior
281 // though it may not be strictly necessary at present
283 if (!settingsInitialized || (defaultInitialized && DiagnosticsConfiguration.IsInitialized())) {
284 defaultInitialized = DiagnosticsConfiguration.IsInitializing();
286 // Getting IndentSize and AutoFlush will load config on demand.
287 // If we load config and there are trace listeners added, we'll
288 // end up recursing, but that recursion will be stopped in
289 // DiagnosticsConfiguration.Initialize()
290 SetIndentSize(DiagnosticsConfiguration.IndentSize);
291 autoFlush = DiagnosticsConfiguration.AutoFlush;
292 useGlobalLock = DiagnosticsConfiguration.UseGlobalLock;
293 settingsInitialized = true;
300 // This method refreshes all the data from the configuration file, so that updated to the configuration file are mirrored
301 // in the System.Diagnostics.Trace class
302 static internal void Refresh() {
304 settingsInitialized = false;
307 InitializeSettings();
310 public static void TraceEvent(TraceEventType eventType, int id, string format, params object[] args) {
312 TraceEventCache EventCache = new TraceEventCache();
317 foreach (TraceListener listener in Listeners) {
318 listener.TraceEvent(EventCache, AppName, eventType, id, format);
319 if (AutoFlush) listener.Flush();
323 foreach (TraceListener listener in Listeners) {
324 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
325 if (AutoFlush) listener.Flush();
332 foreach (TraceListener listener in Listeners) {
333 if (!listener.IsThreadSafe) {
335 listener.TraceEvent(EventCache, AppName, eventType, id, format);
336 if (AutoFlush) listener.Flush();
340 listener.TraceEvent(EventCache, AppName, eventType, id, format);
341 if (AutoFlush) listener.Flush();
346 foreach (TraceListener listener in Listeners) {
347 if (!listener.IsThreadSafe) {
349 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
350 if (AutoFlush) listener.Flush();
354 listener.TraceEvent(EventCache, AppName, eventType, id, format, args);
355 if (AutoFlush) listener.Flush();
363 public static void Write(string message) {
366 foreach (TraceListener listener in Listeners) {
367 listener.Write(message);
368 if (AutoFlush) listener.Flush();
373 foreach (TraceListener listener in Listeners) {
374 if (!listener.IsThreadSafe) {
376 listener.Write(message);
377 if (AutoFlush) listener.Flush();
381 listener.Write(message);
382 if (AutoFlush) listener.Flush();
388 public static void Write(object value) {
391 foreach (TraceListener listener in Listeners) {
392 listener.Write(value);
393 if (AutoFlush) listener.Flush();
398 foreach (TraceListener listener in Listeners) {
399 if (!listener.IsThreadSafe) {
401 listener.Write(value);
402 if (AutoFlush) listener.Flush();
406 listener.Write(value);
407 if (AutoFlush) listener.Flush();
413 public static void Write(string message, string category) {
416 foreach (TraceListener listener in Listeners) {
417 listener.Write(message, category);
418 if (AutoFlush) listener.Flush();
423 foreach (TraceListener listener in Listeners) {
424 if (!listener.IsThreadSafe) {
426 listener.Write(message, category);
427 if (AutoFlush) listener.Flush();
431 listener.Write(message, category);
432 if (AutoFlush) listener.Flush();
438 public static void Write(object value, string category) {
441 foreach (TraceListener listener in Listeners) {
442 listener.Write(value, category);
443 if (AutoFlush) listener.Flush();
448 foreach (TraceListener listener in Listeners) {
449 if (!listener.IsThreadSafe) {
451 listener.Write(value, category);
452 if (AutoFlush) listener.Flush();
456 listener.Write(value, category);
457 if (AutoFlush) listener.Flush();
463 public static void WriteLine(string message) {
466 foreach (TraceListener listener in Listeners) {
467 listener.WriteLine(message);
468 if (AutoFlush) listener.Flush();
473 foreach (TraceListener listener in Listeners) {
474 if (!listener.IsThreadSafe) {
476 listener.WriteLine(message);
477 if (AutoFlush) listener.Flush();
481 listener.WriteLine(message);
482 if (AutoFlush) listener.Flush();
488 public static void WriteLine(object value) {
491 foreach (TraceListener listener in Listeners) {
492 listener.WriteLine(value);
493 if (AutoFlush) listener.Flush();
498 foreach (TraceListener listener in Listeners) {
499 if (!listener.IsThreadSafe) {
501 listener.WriteLine(value);
502 if (AutoFlush) listener.Flush();
506 listener.WriteLine(value);
507 if (AutoFlush) listener.Flush();
513 public static void WriteLine(string message, string category) {
516 foreach (TraceListener listener in Listeners) {
517 listener.WriteLine(message, category);
518 if (AutoFlush) listener.Flush();
523 foreach (TraceListener listener in Listeners) {
524 if (!listener.IsThreadSafe) {
526 listener.WriteLine(message, category);
527 if (AutoFlush) listener.Flush();
531 listener.WriteLine(message, category);
532 if (AutoFlush) listener.Flush();
538 public static void WriteLine(object value, string category) {
541 foreach (TraceListener listener in Listeners) {
542 listener.WriteLine(value, category);
543 if (AutoFlush) listener.Flush();
548 foreach (TraceListener listener in Listeners) {
549 if (!listener.IsThreadSafe) {
551 listener.WriteLine(value, category);
552 if (AutoFlush) listener.Flush();
556 listener.WriteLine(value, category);
557 if (AutoFlush) listener.Flush();
563 public static void WriteIf(bool condition, string message) {
568 public static void WriteIf(bool condition, object value) {
573 public static void WriteIf(bool condition, string message, string category) {
575 Write(message, category);
578 public static void WriteIf(bool condition, object value, string category) {
580 Write(value, category);
583 public static void WriteLineIf(bool condition, string message) {
588 public static void WriteLineIf(bool condition, object value) {
593 public static void WriteLineIf(bool condition, string message, string category) {
595 WriteLine(message, category);
598 public static void WriteLineIf(bool condition, object value, string category) {
600 WriteLine(value, category);