1 #region Copyright & License
2 //
3 // Copyright 2001-2005 The Apache Software Foundation
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 #endregion
18 
19 using System;
20 using System.Configuration;
21 using System.Diagnostics;
22 
23 namespace log4net.Util
24 {
25 	/// <summary>
26 	/// Outputs log statements from within the log4net assembly.
27 	/// </summary>
28 	/// <remarks>
29 	/// <para>
30 	/// Log4net components cannot make log4net logging calls. However, it is
31 	/// sometimes useful for the user to learn about what log4net is
32 	/// doing.
33 	/// </para>
34 	/// <para>
35 	/// All log4net internal debug calls go to the standard output stream
36 	/// whereas internal error messages are sent to the standard error output
37 	/// stream.
38 	/// </para>
39 	/// </remarks>
40 	/// <author>Nicko Cadell</author>
41 	/// <author>Gert Driesen</author>
42 	public sealed class LogLog
43 	{
44 		#region Private Instance Constructors
45 
46 		/// <summary>
47 		/// Initializes a new instance of the <see cref="LogLog" /> class.
48 		/// </summary>
49 		/// <remarks>
50 		/// <para>
51 		/// Uses a private access modifier to prevent instantiation of this class.
52 		/// </para>
53 		/// </remarks>
LogLog()54 		private LogLog()
55 		{
56 		}
57 
58 		#endregion Private Instance Constructors
59 
60 		#region Static Constructor
61 
62 		/// <summary>
63 		/// Static constructor that initializes logging by reading
64 		/// settings from the application configuration file.
65 		/// </summary>
66 		/// <remarks>
67 		/// <para>
68 		/// The <c>log4net.Internal.Debug</c> application setting
69 		/// controls internal debugging. This setting should be set
70 		/// to <c>true</c> to enable debugging.
71 		/// </para>
72 		/// <para>
73 		/// The <c>log4net.Internal.Quiet</c> application setting
74 		/// suppresses all internal logging including error messages.
75 		/// This setting should be set to <c>true</c> to enable message
76 		/// suppression.
77 		/// </para>
78 		/// </remarks>
LogLog()79 		static LogLog()
80 		{
81 #if !NETCF
82 			try
83 			{
84 				InternalDebugging = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Debug"), false);
85 				QuietMode = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Quiet"), false);
86 			}
87 			catch(Exception ex)
88 			{
89 				// If an exception is thrown here then it looks like the config file does not
90 				// parse correctly.
91 				//
92 				// We will leave debug OFF and print an Error message
93 				Error("LogLog: Exception while reading ConfigurationSettings. Check your .config file is well formed XML.", ex);
94 			}
95 #endif
96 		}
97 
98 		#endregion Static Constructor
99 
100 		#region Public Static Properties
101 
102 		/// <summary>
103 		/// Gets or sets a value indicating whether log4net internal logging
104 		/// is enabled or disabled.
105 		/// </summary>
106 		/// <value>
107 		/// <c>true</c> if log4net internal logging is enabled, otherwise
108 		/// <c>false</c>.
109 		/// </value>
110 		/// <remarks>
111 		/// <para>
112 		/// When set to <c>true</c>, internal debug level logging will be
113 		/// displayed.
114 		/// </para>
115 		/// <para>
116 		/// This value can be set by setting the application setting
117 		/// <c>log4net.Internal.Debug</c> in the application configuration
118 		/// file.
119 		/// </para>
120 		/// <para>
121 		/// The default value is <c>false</c>, i.e. debugging is
122 		/// disabled.
123 		/// </para>
124 		/// </remarks>
125 		/// <example>
126 		/// <para>
127 		/// The following example enables internal debugging using the
128 		/// application configuration file :
129 		/// </para>
130 		/// <code lang="XML" escaped="true">
131 		/// <configuration>
132 		///		<appSettings>
133 		///			<add key="log4net.Internal.Debug" value="true" />
134 		///		</appSettings>
135 		/// </configuration>
136 		/// </code>
137 		/// </example>
138 		public static bool InternalDebugging
139 		{
140 			get { return s_debugEnabled; }
141 			set { s_debugEnabled = value; }
142 		}
143 
144 		/// <summary>
145 		/// Gets or sets a value indicating whether log4net should generate no output
146 		/// from internal logging, not even for errors.
147 		/// </summary>
148 		/// <value>
149 		/// <c>true</c> if log4net should generate no output at all from internal
150 		/// logging, otherwise <c>false</c>.
151 		/// </value>
152 		/// <remarks>
153 		/// <para>
154 		/// When set to <c>true</c> will cause internal logging at all levels to be
155 		/// suppressed. This means that no warning or error reports will be logged.
156 		/// This option overrides the <see cref="InternalDebugging"/> setting and
157 		/// disables all debug also.
158 		/// </para>
159 		/// <para>This value can be set by setting the application setting
160 		/// <c>log4net.Internal.Quiet</c> in the application configuration file.
161 		/// </para>
162 		/// <para>
163 		/// The default value is <c>false</c>, i.e. internal logging is not
164 		/// disabled.
165 		/// </para>
166 		/// </remarks>
167 		/// <example>
168 		/// The following example disables internal logging using the
169 		/// application configuration file :
170 		/// <code lang="XML" escaped="true">
171 		/// <configuration>
172 		///		<appSettings>
173 		///			<add key="log4net.Internal.Quiet" value="true" />
174 		///		</appSettings>
175 		/// </configuration>
176 		/// </code>
177 		/// </example>
178 		public static bool QuietMode
179 		{
180 			get { return s_quietMode; }
181 			set { s_quietMode = value; }
182 		}
183 
184 		#endregion Public Static Properties
185 
186 		#region Public Static Methods
187 
188 		/// <summary>
189 		/// Test if LogLog.Debug is enabled for output.
190 		/// </summary>
191 		/// <value>
192 		/// <c>true</c> if Debug is enabled
193 		/// </value>
194 		/// <remarks>
195 		/// <para>
196 		/// Test if LogLog.Debug is enabled for output.
197 		/// </para>
198 		/// </remarks>
199 		public static bool IsDebugEnabled
200 		{
201 			get { return s_debugEnabled && !s_quietMode; }
202 		}
203 
204 		/// <summary>
205 		/// Writes log4net internal debug messages to the
206 		/// standard output stream.
207 		/// </summary>
208 		/// <param name="message">The message to log.</param>
209 		/// <remarks>
210 		/// <para>
211 		///	All internal debug messages are prepended with
212 		///	the string "log4net: ".
213 		/// </para>
214 		/// </remarks>
Debug(string message)215 		public static void Debug(string message)
216 		{
217 			if (IsDebugEnabled)
218 			{
219 				EmitOutLine(PREFIX + message);
220 			}
221 		}
222 
223 		/// <summary>
224 		/// Writes log4net internal debug messages to the
225 		/// standard output stream.
226 		/// </summary>
227 		/// <param name="message">The message to log.</param>
228 		/// <param name="exception">An exception to log.</param>
229 		/// <remarks>
230 		/// <para>
231 		///	All internal debug messages are prepended with
232 		///	the string "log4net: ".
233 		/// </para>
234 		/// </remarks>
Debug(string message, Exception exception)235 		public static void Debug(string message, Exception exception)
236 		{
237 			if (IsDebugEnabled)
238 			{
239 				EmitOutLine(PREFIX + message);
240 				if (exception != null)
241 				{
242 					EmitOutLine(exception.ToString());
243 				}
244 			}
245 		}
246 
247 		/// <summary>
248 		/// Test if LogLog.Warn is enabled for output.
249 		/// </summary>
250 		/// <value>
251 		/// <c>true</c> if Warn is enabled
252 		/// </value>
253 		/// <remarks>
254 		/// <para>
255 		/// Test if LogLog.Warn is enabled for output.
256 		/// </para>
257 		/// </remarks>
258 		public static bool IsWarnEnabled
259 		{
260 			get { return !s_quietMode; }
261 		}
262 
263 		/// <summary>
264 		/// Writes log4net internal warning messages to the
265 		/// standard error stream.
266 		/// </summary>
267 		/// <param name="message">The message to log.</param>
268 		/// <remarks>
269 		/// <para>
270 		///	All internal warning messages are prepended with
271 		///	the string "log4net:WARN ".
272 		/// </para>
273 		/// </remarks>
Warn(string message)274 		public static void Warn(string message)
275 		{
276 			if (IsWarnEnabled)
277 			{
278 				EmitErrorLine(WARN_PREFIX + message);
279 			}
280 		}
281 
282 		/// <summary>
283 		/// Writes log4net internal warning messages to the
284 		/// standard error stream.
285 		/// </summary>
286 		/// <param name="message">The message to log.</param>
287 		/// <param name="exception">An exception to log.</param>
288 		/// <remarks>
289 		/// <para>
290 		///	All internal warning messages are prepended with
291 		///	the string "log4net:WARN ".
292 		/// </para>
293 		/// </remarks>
Warn(string message, Exception exception)294 		public static void Warn(string message, Exception exception)
295 		{
296 			if (IsWarnEnabled)
297 			{
298 				EmitErrorLine(WARN_PREFIX + message);
299 				if (exception != null)
300 				{
301 					EmitErrorLine(exception.ToString());
302 				}
303 			}
304 		}
305 
306 		/// <summary>
307 		/// Test if LogLog.Error is enabled for output.
308 		/// </summary>
309 		/// <value>
310 		/// <c>true</c> if Error is enabled
311 		/// </value>
312 		/// <remarks>
313 		/// <para>
314 		/// Test if LogLog.Error is enabled for output.
315 		/// </para>
316 		/// </remarks>
317 		public static bool IsErrorEnabled
318 		{
319 			get { return !s_quietMode; }
320 		}
321 
322 		/// <summary>
323 		/// Writes log4net internal error messages to the
324 		/// standard error stream.
325 		/// </summary>
326 		/// <param name="message">The message to log.</param>
327 		/// <remarks>
328 		/// <para>
329 		///	All internal error messages are prepended with
330 		///	the string "log4net:ERROR ".
331 		/// </para>
332 		/// </remarks>
Error(string message)333 		public static void Error(string message)
334 		{
335 			if (IsErrorEnabled)
336 			{
337 				EmitErrorLine(ERR_PREFIX + message);
338 			}
339 		}
340 
341 		/// <summary>
342 		/// Writes log4net internal error messages to the
343 		/// standard error stream.
344 		/// </summary>
345 		/// <param name="message">The message to log.</param>
346 		/// <param name="exception">An exception to log.</param>
347 		/// <remarks>
348 		/// <para>
349 		///	All internal debug messages are prepended with
350 		///	the string "log4net:ERROR ".
351 		/// </para>
352 		/// </remarks>
Error(string message, Exception exception)353 		public static void Error(string message, Exception exception)
354 		{
355 			if (IsErrorEnabled)
356 			{
357 				EmitErrorLine(ERR_PREFIX + message);
358 				if (exception != null)
359 				{
360 					EmitErrorLine(exception.ToString());
361 				}
362 			}
363 		}
364 
365 		#endregion Public Static Methods
366 
367 		/// <summary>
368 		/// Writes output to the standard output stream.
369 		/// </summary>
370 		/// <param name="message">The message to log.</param>
371 		/// <remarks>
372 		/// <para>
373 		/// Writes to both Console.Out and System.Diagnostics.Trace.
374 		/// Note that the System.Diagnostics.Trace is not supported
375 		/// on the Compact Framework.
376 		/// </para>
377 		/// <para>
378 		/// If the AppDomain is not configured with a config file then
379 		/// the call to System.Diagnostics.Trace may fail. This is only
380 		/// an issue if you are programmatically creating your own AppDomains.
381 		/// </para>
382 		/// </remarks>
EmitOutLine(string message)383 		private static void EmitOutLine(string message)
384 		{
385 			try
386 			{
387 #if NETCF
388 				Console.WriteLine(message);
389 				//System.Diagnostics.Debug.WriteLine(message);
390 #else
391 				Console.Out.WriteLine(message);
392 				Trace.WriteLine(message);
393 #endif
394 			}
395 			catch
396 			{
397 				// Ignore exception, what else can we do? Not really a good idea to propagate back to the caller
398 			}
399 		}
400 
401 		/// <summary>
402 		/// Writes output to the standard error stream.
403 		/// </summary>
404 		/// <param name="message">The message to log.</param>
405 		/// <remarks>
406 		/// <para>
407 		/// Writes to both Console.Error and System.Diagnostics.Trace.
408 		/// Note that the System.Diagnostics.Trace is not supported
409 		/// on the Compact Framework.
410 		/// </para>
411 		/// <para>
412 		/// If the AppDomain is not configured with a config file then
413 		/// the call to System.Diagnostics.Trace may fail. This is only
414 		/// an issue if you are programmatically creating your own AppDomains.
415 		/// </para>
416 		/// </remarks>
EmitErrorLine(string message)417 		private static void EmitErrorLine(string message)
418 		{
419 			try
420 			{
421 #if NETCF
422 				Console.WriteLine(message);
423 				//System.Diagnostics.Debug.WriteLine(message);
424 #else
425 				Console.Error.WriteLine(message);
426 				Trace.WriteLine(message);
427 #endif
428 			}
429 			catch
430 			{
431 				// Ignore exception, what else can we do? Not really a good idea to propagate back to the caller
432 			}
433 		}
434 
435 		#region Private Static Fields
436 
437 		/// <summary>
438 		///  Default debug level
439 		/// </summary>
440 		private static bool s_debugEnabled = false;
441 
442 		/// <summary>
443 		/// In quietMode not even errors generate any output.
444 		/// </summary>
445 		private static bool s_quietMode = false;
446 
447 		private const string PREFIX			= "log4net: ";
448 		private const string ERR_PREFIX		= "log4net:ERROR ";
449 		private const string WARN_PREFIX	= "log4net:WARN ";
450 
451 		#endregion Private Static Fields
452 	}
453 }
454