My apologies for responding to a message 4 months old, but it's a better place to start than from scratch.. 

I have an app that I'm new too which has insufficient logging (and configuration therein) for my purposes. So, after years with log4net, I'm trying to switch the folks.. 

The app itself is a container with multiple sub applications within it..  all app-domained to insanity by most standards, but it's fairly necessary in the world i'm in. 

To that end, the logging we have now is closest to 1) below, just not log4net.  Well, actually, they write to log4net on the tail end of the process to get to an actual file, but lets not get into how much that isn't really using log4net.  The existing logging marshals itself to a central domain via intra app-domain remoting.  Unfortunately, the homegrown version loses almost everything but the log message and exception.ToString()... 

I'm wondering if it's possible to do a combination of the 2 answers below.  To use Remoting to get all the app domain's logging events back to a single master logging domain, but without going out to the network and incurring the resultant overhead of out of process serialization. 

Thinking out loud..  If each child app domain had a single appender (root, debug+ ) which itself internalized answer 1) to link to a master log4net instance in the main app-domain.  And then the main app-domain's log4net was normal, it could output everything or some things as configured normally.. 

I think I'd need 3 things for this plan to work.. 

#1.  A central sink for receiving messages in the parent app-domain and pumping them through it's log4net system (hopefully without losing the contextual information)  This would probably have to be MarshalByRef, and may already exist.  This would receive LoggingEvents from #2 and push them somehow into it's plumbing.  Where's the best entry point for entering LoggingEvents?

#2. Something similar to the ForwardingAppender which knows how to find #1 internally via remoting. (no sockets or smtp :)  I've extended appenders before, so the tricky part is probably it finding #1.  This would receive the LoggingEvents (assuming proper configuration) and pass them over to #1. 

#3. Some work specific to my app to hard code #2's setup/configuration into the startup of all child domains. 

Any thoughts on this approach? 

Thanks all for the many years of help.  As long as I'm doing dotnet development, log4net will be the standard everything else is measured by.. 

-Peter



On 2006-07-14, "Nicko Cadell" <nicko () neoworks ! com> wrote:
AppDomains are logical isolation units akin to lightweight processes.

log4net cannot exist outside an AppDomain because nothing can exist
outside an AppDomain. log4net must be configured in each AppDomain, and
it know nothing about the appenders or configuration in the other
AppDomains. Each AppDomain will have its own logger hierarchy and root
logger.

It is quite a challenge to find all the AppDomains in the process and
hook them up. There are 2 different approaches that I can think of:


1) Create a MarshalByRef appender implementation, i.e. a class that
extends MarshalByRefObject and implements the IAppender interface. This
could just be a simple wrapper that forwards the call to another
IAppender, allowing you to reuse the existing appenders.
This appender and the MarshalByRef appender wrapper would need to be
created in only 1 AppDomain. You would then need to get a reference to
this wrapper via remoting into each of the other AppDomains and then
attach that appender reference to the root logger in that AppDomain.

2) The other approach is similar in that it still requires remoting, but
rather than marshalling the appender across and attaching it to the
logger hierarchy in all the AppDomains, the events logged in the
AppDomains are sent via remoting to a single published listener which
re-logs the event it its AppDomain. This allows the logging events to be
centralised in a single AppDomain, but they can still be logged in their
own AppDomains.
 
To do this you will need to use the RemotingAppender in each of your

AppDomains. The RemotingAppender will sent the LoggingEvent via .NET
remoting to a published listener. The RemoteLoggingServerPlugin is a
built-in way of publishing a listener. See the Remoting examples in the
log4net download, examples\net\1.0\Remoting. In your case rather than
running separate processes, one of your AppDomains will be the server
(and receive logging events) and all the other AppDomains will be the
clients.

Cheers,
Nicko

Reply via email to