**** Merged from MCS ****
[mono-project.git] / mcs / class / System / System.Diagnostics / DefaultTraceListener.cs
blob06e0473a4dc1b11f627d8c0370c4327ed91441f8
1 //
2 // System.Diagnostics.DefaultTraceListener.cs
3 //
4 // Authors:
5 // Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // Comments from John R. Hicks <angryjohn69@nc.rr.com> original implementation
8 // can be found at: /mcs/docs/apidocs/xml/en/System.Diagnostics
9 //
10 // (C) 2002 Jonathan Pryor
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.IO;
36 using System.Collections;
37 using System.Diagnostics;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
41 namespace System.Diagnostics {
43 [ComVisible(false)]
44 public class DefaultTraceListener : TraceListener {
46 private static readonly bool OnWin32;
48 private const string ConsoleOutTrace = "Console.Out";
49 private const string ConsoleErrorTrace = "Console.Error";
51 private static readonly string MonoTracePrefix;
52 private static readonly string MonoTraceFile;
54 static DefaultTraceListener ()
56 // Determine what platform we're on. This impacts how where we send
57 // messages. On Win32 platforms (OnWin32 = true), we use the
58 // `OutputDebugString' api.
60 // On Linux platforms, we use MONO_TRACE to figure things out. See the
61 // API documentation for more information on MONO_TRACE.
62 OnWin32 = (Path.DirectorySeparatorChar == '\\');
64 if (!OnWin32) {
65 // If we're running on Unix, we don't have OutputDebugString.
66 // Instead, send output to...wherever the MONO_TRACE environment
67 // variables says to.
68 String trace = Environment.GetEnvironmentVariable("MONO_TRACE");
70 if (trace != null) {
71 string file = null;
72 string prefix = null;
74 if (trace.StartsWith (ConsoleOutTrace)) {
75 file = ConsoleOutTrace;
76 prefix = GetPrefix (trace, ConsoleOutTrace);
78 else if (trace.StartsWith (ConsoleErrorTrace)) {
79 file = ConsoleErrorTrace;
80 prefix = GetPrefix (trace, ConsoleErrorTrace);
82 else {
83 file = trace;
85 // We can't firgure out what the prefix would be, as ':' is a
86 // valid filename character. Thus, arbitrary files don't support
87 // prefixes.
89 // I don't consider this to be a major issue. Prefixes are useful
90 // with Console.Out and Console.Error to help separate trace
91 // output from the actual program output. Writing to an arbitrary
92 // file doesn't introduce issues with disambiguation.
93 prefix = "";
96 MonoTraceFile = file;
97 MonoTracePrefix = prefix;
103 * Get the prefix for the specified variable.
105 * "Prefixes" are used in the MONO_TRACE variable, and specify text that
106 * should precede each message printed to the console. The prefix is
107 * appended to the console location with a colon (':') separating them.
108 * For example, if MONO_TRACE is "Console.Out:** my prefix", the prefix is
109 * "** my prefix".
111 * Everything after the colon, if the colon is present, is used as the
112 * prefix.
114 * @param var The current MONO_TRACE variable
115 * @param target The name of the output location, e.g. "Console.Out"
117 private static string GetPrefix (string var, string target)
119 // actually, we permit any character to separate `target' and the prefix;
120 // we just skip over target the ':' would be. This means that a space or
121 // anything else would suffice, as long as it was only a single
122 // character.
123 if (var.Length > target.Length)
124 return var.Substring (target.Length + 1);
125 return "";
128 private string logFileName = null;
130 private bool assertUiEnabled = false;
132 public DefaultTraceListener () : base ("Default")
136 // It's hard to do anything with a UI when we don't have Windows.Forms...
137 [MonoTODO]
138 public bool AssertUiEnabled {
139 get {return assertUiEnabled;}
140 set {/* ignore */}
143 [MonoTODO]
144 public string LogFileName {
145 get {return logFileName;}
146 set {logFileName = value;}
149 public override void Fail (string message)
151 base.Fail (message);
152 WriteLine (new StackTrace().ToString());
155 public override void Fail (string message, string detailMessage)
157 base.Fail (message, detailMessage);
158 WriteLine (new StackTrace().ToString());
161 [MethodImplAttribute(MethodImplOptions.InternalCall)]
162 private extern static void WriteWindowsDebugString (string message);
164 private void WriteDebugString (string message)
166 if (OnWin32)
167 WriteWindowsDebugString (message);
168 else
169 WriteMonoTrace (message);
172 private void WriteMonoTrace (string message)
174 switch (MonoTraceFile) {
175 case ConsoleOutTrace:
176 Console.Out.Write (message);
177 break;
178 case ConsoleErrorTrace:
179 Console.Error.Write (message);
180 break;
181 default:
182 WriteLogFile (message, MonoTraceFile);
183 break;
187 private void WritePrefix ()
189 if (!OnWin32) {
190 WriteMonoTrace (MonoTracePrefix);
194 private void WriteImpl (string message)
196 if (NeedIndent) {
197 WriteIndent ();
198 WritePrefix ();
201 WriteDebugString (message);
203 if (Debugger.IsLogging())
204 Debugger.Log (0, null, message);
206 WriteLogFile (message, LogFileName);
209 private void WriteLogFile (string message, string logFile)
211 string fname = logFile;
212 if (fname != null && fname.Length != 0) {
213 FileInfo info = new FileInfo (fname);
214 StreamWriter sw = null;
216 // Open the file
217 try {
218 if (info.Exists)
219 sw = info.AppendText ();
220 else
221 sw = info.CreateText ();
223 catch {
224 // We weren't able to open the file for some reason.
225 // We can't write to the log file; so give up.
226 return;
229 using (sw) {
230 sw.Write (message);
231 sw.Flush ();
236 public override void Write (string message)
238 WriteImpl (message);
241 public override void WriteLine (string message)
243 string msg = message + Environment.NewLine;
244 WriteImpl (msg);
246 NeedIndent = true;