#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
using System;
using System.Collections;
using System.Diagnostics;
namespace log4net.Util
{
///
///
///
///
///
public delegate void LogReceivedEventHandler(object source, LogReceivedEventArgs e);
///
/// Outputs log statements from within the log4net assembly.
///
///
///
/// Log4net components cannot make log4net logging calls. However, it is
/// sometimes useful for the user to learn about what log4net is
/// doing.
///
///
/// All log4net internal debug calls go to the standard output stream
/// whereas internal error messages are sent to the standard error output
/// stream.
///
///
/// Nicko Cadell
/// Gert Driesen
public sealed class LogLog
{
///
/// The event raised when an internal message has been received.
///
public static event LogReceivedEventHandler LogReceived;
private readonly Type source;
private readonly DateTime timeStampUtc;
private readonly string prefix;
private readonly string message;
private readonly Exception exception;
///
/// The Type that generated the internal message.
///
public Type Source
{
get { return source; }
}
///
/// The DateTime stamp of when the internal message was received.
///
public DateTime TimeStamp
{
get { return timeStampUtc.ToLocalTime(); }
}
///
/// The UTC DateTime stamp of when the internal message was received.
///
public DateTime TimeStampUtc
{
get { return timeStampUtc; }
}
///
/// A string indicating the severity of the internal message.
///
///
/// "log4net: ",
/// "log4net:ERROR ",
/// "log4net:WARN "
///
public string Prefix
{
get { return prefix; }
}
///
/// The internal log message.
///
public string Message
{
get { return message; }
}
///
/// The Exception related to the message.
///
///
/// Optional. Will be null if no Exception was passed.
///
public Exception Exception
{
get { return exception; }
}
///
/// Formats Prefix, Source, and Message in the same format as the value
/// sent to Console.Out and Trace.Write.
///
///
public override string ToString()
{
return Prefix + Source.Name + ": " + Message;
}
#region Private Instance Constructors
///
/// Initializes a new instance of the class.
///
///
///
///
///
public LogLog(Type source, string prefix, string message, Exception exception)
{
timeStampUtc = DateTime.UtcNow;
this.source = source;
this.prefix = prefix;
this.message = message;
this.exception = exception;
}
#endregion Private Instance Constructors
#region Static Constructor
///
/// Static constructor that initializes logging by reading
/// settings from the application configuration file.
///
///
///
/// The log4net.Internal.Debug application setting
/// controls internal debugging. This setting should be set
/// to true to enable debugging.
///
///
/// The log4net.Internal.Quiet application setting
/// suppresses all internal logging including error messages.
/// This setting should be set to true to enable message
/// suppression.
///
///
static LogLog()
{
#if !NETCF
try
{
InternalDebugging = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Debug"), false);
QuietMode = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Quiet"), false);
EmitInternalMessages = OptionConverter.ToBoolean(SystemInfo.GetAppSetting("log4net.Internal.Emit"), true);
}
catch(Exception ex)
{
// If an exception is thrown here then it looks like the config file does not
// parse correctly.
//
// We will leave debug OFF and print an Error message
Error(typeof(LogLog), "Exception while reading ConfigurationSettings. Check your .config file is well formed XML.", ex);
}
#endif
}
#endregion Static Constructor
#region Public Static Properties
///
/// Gets or sets a value indicating whether log4net internal logging
/// is enabled or disabled.
///
///
/// true if log4net internal logging is enabled, otherwise
/// false.
///
///
///
/// When set to true, internal debug level logging will be
/// displayed.
///
///
/// This value can be set by setting the application setting
/// log4net.Internal.Debug in the application configuration
/// file.
///
///
/// The default value is false, i.e. debugging is
/// disabled.
///
///
///
///
/// The following example enables internal debugging using the
/// application configuration file :
///
///
///
///
///
///
///
///
///
public static bool InternalDebugging
{
get { return s_debugEnabled; }
set { s_debugEnabled = value; }
}
///
/// Gets or sets a value indicating whether log4net should generate no output
/// from internal logging, not even for errors.
///
///
/// true if log4net should generate no output at all from internal
/// logging, otherwise false.
///
///
///
/// When set to true will cause internal logging at all levels to be
/// suppressed. This means that no warning or error reports will be logged.
/// This option overrides the setting and
/// disables all debug also.
///
/// This value can be set by setting the application setting
/// log4net.Internal.Quiet in the application configuration file.
///
///
/// The default value is false, i.e. internal logging is not
/// disabled.
///
///
///
/// The following example disables internal logging using the
/// application configuration file :
///
///
///
///
///
///
///
///
public static bool QuietMode
{
get { return s_quietMode; }
set { s_quietMode = value; }
}
///
///
///
public static bool EmitInternalMessages
{
get { return s_emitInternalMessages; }
set { s_emitInternalMessages = value; }
}
#endregion Public Static Properties
#region Public Static Methods
///
/// Raises the LogReceived event when an internal messages is received.
///
///
///
///
///
public static void OnLogReceived(Type source, string prefix, string message, Exception exception)
{
if (LogReceived != null)
{
LogReceived(null, new LogReceivedEventArgs(new LogLog(source, prefix, message, exception)));
}
}
///
/// Test if LogLog.Debug is enabled for output.
///
///
/// true if Debug is enabled
///
///
///
/// Test if LogLog.Debug is enabled for output.
///
///
public static bool IsDebugEnabled
{
get { return s_debugEnabled && !s_quietMode; }
}
///
/// Writes log4net internal debug messages to the
/// standard output stream.
///
///
/// The message to log.
///
///
/// All internal debug messages are prepended with
/// the string "log4net: ".
///
///
public static void Debug(Type source, string message)
{
if (IsDebugEnabled)
{
if (EmitInternalMessages)
{
EmitOutLine(PREFIX + message);
}
OnLogReceived(source, PREFIX, message, null);
}
}
///
/// Writes log4net internal debug messages to the
/// standard output stream.
///
/// The Type that generated this message.
/// The message to log.
/// An exception to log.
///
///
/// All internal debug messages are prepended with
/// the string "log4net: ".
///
///
public static void Debug(Type source, string message, Exception exception)
{
if (IsDebugEnabled)
{
if (EmitInternalMessages)
{
EmitOutLine(PREFIX + message);
if (exception != null)
{
EmitOutLine(exception.ToString());
}
}
OnLogReceived(source, PREFIX, message, exception);
}
}
///
/// Test if LogLog.Warn is enabled for output.
///
///
/// true if Warn is enabled
///
///
///
/// Test if LogLog.Warn is enabled for output.
///
///
public static bool IsWarnEnabled
{
get { return !s_quietMode; }
}
///
/// Writes log4net internal warning messages to the
/// standard error stream.
///
/// The Type that generated this message.
/// The message to log.
///
///
/// All internal warning messages are prepended with
/// the string "log4net:WARN ".
///
///
public static void Warn(Type source, string message)
{
if (IsWarnEnabled)
{
if (EmitInternalMessages)
{
EmitErrorLine(WARN_PREFIX + message);
}
OnLogReceived(source, WARN_PREFIX, message, null);
}
}
///
/// Writes log4net internal warning messages to the
/// standard error stream.
///
/// The Type that generated this message.
/// The message to log.
/// An exception to log.
///
///
/// All internal warning messages are prepended with
/// the string "log4net:WARN ".
///
///
public static void Warn(Type source, string message, Exception exception)
{
if (IsWarnEnabled)
{
if (EmitInternalMessages)
{
EmitErrorLine(WARN_PREFIX + message);
if (exception != null)
{
EmitErrorLine(exception.ToString());
}
}
OnLogReceived(source, WARN_PREFIX, message, exception);
}
}
///
/// Test if LogLog.Error is enabled for output.
///
///
/// true if Error is enabled
///
///
///
/// Test if LogLog.Error is enabled for output.
///
///
public static bool IsErrorEnabled
{
get { return !s_quietMode; }
}
///
/// Writes log4net internal error messages to the
/// standard error stream.
///
/// The Type that generated this message.
/// The message to log.
///
///
/// All internal error messages are prepended with
/// the string "log4net:ERROR ".
///
///
public static void Error(Type source, string message)
{
if (IsErrorEnabled)
{
if (EmitInternalMessages)
{
EmitErrorLine(ERR_PREFIX + message);
}
OnLogReceived(source, ERR_PREFIX, message, null);
}
}
///
/// Writes log4net internal error messages to the
/// standard error stream.
///
/// The Type that generated this message.
/// The message to log.
/// An exception to log.
///
///
/// All internal debug messages are prepended with
/// the string "log4net:ERROR ".
///
///
public static void Error(Type source, string message, Exception exception)
{
if (IsErrorEnabled)
{
if (EmitInternalMessages)
{
EmitErrorLine(ERR_PREFIX + message);
if (exception != null)
{
EmitErrorLine(exception.ToString());
}
}
OnLogReceived(source, ERR_PREFIX, message, exception);
}
}
#endregion Public Static Methods
///
/// Writes output to the standard output stream.
///
/// The message to log.
///
///
/// Writes to both Console.Out and System.Diagnostics.Trace.
/// Note that the System.Diagnostics.Trace is not supported
/// on the Compact Framework.
///
///
/// If the AppDomain is not configured with a config file then
/// the call to System.Diagnostics.Trace may fail. This is only
/// an issue if you are programmatically creating your own AppDomains.
///
///
private static void EmitOutLine(string message)
{
try
{
#if NETCF
Console.WriteLine(message);
//System.Diagnostics.Debug.WriteLine(message);
#else
Console.Out.WriteLine(message);
Trace.WriteLine(message);
#endif
}
catch
{
// Ignore exception, what else can we do? Not really a good idea to propagate back to the caller
}
}
///
/// Writes output to the standard error stream.
///
/// The message to log.
///
///
/// Writes to both Console.Error and System.Diagnostics.Trace.
/// Note that the System.Diagnostics.Trace is not supported
/// on the Compact Framework.
///
///
/// If the AppDomain is not configured with a config file then
/// the call to System.Diagnostics.Trace may fail. This is only
/// an issue if you are programmatically creating your own AppDomains.
///
///
private static void EmitErrorLine(string message)
{
try
{
#if NETCF
Console.WriteLine(message);
//System.Diagnostics.Debug.WriteLine(message);
#else
Console.Error.WriteLine(message);
Trace.WriteLine(message);
#endif
}
catch
{
// Ignore exception, what else can we do? Not really a good idea to propagate back to the caller
}
}
#region Private Static Fields
///
/// Default debug level
///
private static bool s_debugEnabled = false;
///
/// In quietMode not even errors generate any output.
///
private static bool s_quietMode = false;
private static bool s_emitInternalMessages = true;
private const string PREFIX = "log4net: ";
private const string ERR_PREFIX = "log4net:ERROR ";
private const string WARN_PREFIX = "log4net:WARN ";
#endregion Private Static Fields
///
/// Subscribes to the LogLog.LogReceived event and stores messages
/// to the supplied IList instance.
///
public class LogReceivedAdapter : IDisposable
{
private readonly IList items;
private readonly LogReceivedEventHandler handler;
///
///
///
///
public LogReceivedAdapter(IList items)
{
this.items = items;
handler = new LogReceivedEventHandler(LogLog_LogReceived);
LogReceived += handler;
}
void LogLog_LogReceived(object source, LogReceivedEventArgs e)
{
items.Add(e.LogLog);
}
///
///
///
public IList Items
{
get { return items; }
}
///
///
///
public void Dispose()
{
LogReceived -= handler;
}
}
}
///
///
///
public class LogReceivedEventArgs : EventArgs
{
private readonly LogLog loglog;
///
///
///
///
public LogReceivedEventArgs(LogLog loglog)
{
this.loglog = loglog;
}
///
///
///
public LogLog LogLog
{
get { return loglog; }
}
}
}