[ 
https://issues.apache.org/jira/browse/LOG4NET-2?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12554261
 ] 

Ron Grabowski commented on LOG4NET-2:
-------------------------------------

I'm finishing up code to support this syntax:

 ICollection configurationMessages = XmlConfigurator.Configure();

such that you can call ToString() on each item in the collection to produce the 
same internal message that is sent to Console.Out and Trace.Write:

  log4net: XmlHierarchyConfigurator: Loading Appender [MemoryAppender] type: 
[log4net.Appender.MemoryAppender]

I was going to use a return type of Array but with ICollection it might be 
possible to cast it to an implementation or another interface to extract 
messages based on severity like configurationMessages.GetErrorMessages().

I accomplished this by adding a static LogReceived event to the log4net logging 
class LogLog so an event is raised when an internal log message is recieved. 
During the configuration process I capture these events and return them to the 
user:

// XmlConfigurator
static public ICollection Configure() 
{
    ArrayList configurationMessages = new ArrayList();

    using (new LogLog.LogReceivedAdapter(configurationMessages))
    {
        
InternalConfigure(LogManager.GetRepository(Assembly.GetCallingAssembly()));
    }

    return configurationMessages;
}

A "configurationMessage" is really a LogLog object with its ToString() method 
overriden to mimic the output sent to Console.Out and Trace.Write. I added the 
following instance fields to LogLog:

public sealed class LogLog
{
    private Type source;
    private DateTime utcTimeStamp;
    private string prefix;
    private string message;
    private Exception exception;

    // snip

    public override string ToString()
    {
        return Prefix + Source.Name + ": " + Message;
    }
}

Notice that we now have the Type that generated the internal message 
(previously it was up to the LogLog.Debug caller to insert Type information 
into the message), the timestamp of when the internal message was created, and 
a real Exception object. This should allow someone to further filter the 
internal log messages to see messages coming from only certain types like 
RollingFileAppender.

I also added the ability to control whether or not an internal log message is 
emiited to the outside by introducing an EmitIternalMessage static property on 
LogLog so its possible to capture internal messages without emitting them via 
Console.Out or Trace.Write:

// LogLog
public static void Debug(Type source, string message)
{
    if (IsDebugEnabled)
    {
        if (EmitInternalMessages)
        {
            EmitOutLine(PREFIX + source.Name + ": " + message);
        }

        OnLogReceived(source, PREFIX, message, null);
    }
}

EmitInternalMessages defaults to true so the current behavior is unchanged.

Its also possible to attach to the repository's ConfigurationChanged event to 
see a list of messages captured from LogLog while the repository was being 
reconfigured:

 ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
 rep.ConfigurationChanged += new 
LoggerRepositoryConfigurationChangedEventHandler(rep_ConfigurationChanged);

 // snip

 void rep_ConfigurationChanged(object sender, EventArgs e)
 {
     ConfigurationChangedEventArgs configChanged = 
(ConfigurationChangedEventArgs)e; 
     Assert.IsTrue(configChanged.ConfigurationMessages.Count > 0);
 } 

An EventArgs is used because the ConfigurationChanged event is on the very 
general ILoggerRepository. I suppose ConfigurationChangedEventArgs could be 
used instead.

This should also allow the repository to keep a list of configuration messages 
that occurred during its last configuration which would be especially useful 
for the ConfigureAndWatch methods that are monitoring for file system changes 
on log4net.config:

 ILoggerRepository rep = LogManager.GetRepository();

 // could be exposed as an ICollection property on ILoggerRepository
 ICollection configurationMessages = 
     (ICollection)rep.Properties["log4net:ConfigurationMessages"];

The only other large internal change was that LogLog now requires a Type 
parameter be passed as its first parameter instead of embedded the type name as 
part of the message:

public class AdoNetAppender : BufferingAppenderSkeleton
{
    private readonly static Type declaringType = typeof(AdoNetAppender);

    // snip

    override protected void SendBuffer(LoggingEvent[] events)
    {
        LogLog.Debug(declaringType, "Preparing to send events...");
    }
}

Comments?

> Configurator should report errors
> ---------------------------------
>
>                 Key: LOG4NET-2
>                 URL: https://issues.apache.org/jira/browse/LOG4NET-2
>             Project: Log4net
>          Issue Type: Improvement
>          Components: Core
>    Affects Versions: 1.2.9
>         Environment: From sourceforege - Tor Hovland - torhovl
>            Reporter: Nicko Cadell
>            Assignee: Ron Grabowski
>             Fix For: v.Next
>
>
> I understand that you do not want to throw exceptions
> from within the logging methods, as a failure in log4net
> would make the hosting app fail.
> However, I think it is necessary that DOMConfigurator
> throws exceptions. If a failure occurs at that point, for
> example due to a malformed configuration file, I believe
> the hosting app would in most cases like to know. Even
> if it doesn't, it could easily just swallow any exceptions.
> In my case, I have a Windows Service app that will just
> quit logging if there is an error in the configuration file.
> That makes the logging mechanism rather more fragile
> than I would like.
> Tor Hovland - torhovl
> ---
> I completely agree.  I suggest that you take an additional
> step and provide an additional mechanism, perhaps a
> ValidateLoggers() method which operates like a standard
> logging call, but is capable of throwing exceptions or
> providing another form of feedback which would allow the
> caller to diagnose bad configurations.  The configuration
> file can be well-formed, but logging can still fail for any
> number of reasons.
> Most applications that provide a logging mechanism employ a
> 'start-up banner' log entry at an INFO level.  This would be
> a great time to detect any problems with the logging system
> itself.  I currently have a project deployed at a customer
> site and despite a well formed config file... no logging is
> taking place.  I don't know why, and there does not seem to
> be a simple way to  diagnose the problem.
> Ben Newman - benjamin91

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to