log4net across appdomains

前端 未结 5 1479
失恋的感觉
失恋的感觉 2020-12-30 02:18

I have an application which initializes log4net from one appdomain and needs to use it in another appdomain. Is it supported?

If not, should I initialize log4net fro

5条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2020-12-30 03:08

    Although the question is several years old - maybe it helps someone:

    It is possible to use the loggers configured in the parent AppDomain. What needs to be done is route the LoggingEvents from the child AppDomain to the parent AppDomain. For this you need to create a custom Appender that forwards the records out of the Child domain...

    /// 
    /// Represents an  implementation that forwards a  to a given Receiver.
    /// Instances of this class should be created in the child domain.
    /// 
    public class CrossDomainOutboundAppender : AppenderSkeleton
    {
        private readonly CrossDomainParentAppender crossDomainParentAppender;
        public CrossDomainOutboundAppender(CrossDomainParentAppender crossDomainParentAppender)
        {
            if (crossDomainParentAppender == null)
            {
                throw new ArgumentNullException("crossDomainParentAppender");
            }
            this.crossDomainParentAppender = crossDomainParentAppender;
    
        }
    
        protected override void Append(LoggingEvent loggingEvent)
        {
            LoggingEvent copied = new LoggingEvent(loggingEvent.GetLoggingEventData());
            crossDomainParentAppender.Append(copied);
        }
    }
    

    , a custom class that receives the forwarded LoggingEvent and appends them to available IAppenders ...

    /// 
    /// Represents a Receiver that sends Log4Nets  to all available s.
    /// Instances of this class should be created in the ParentDomain.
    /// 
    [Serializable]
    public class CrossDomainParentAppender : MarshalByRefObject
    {
        public void Append(LoggingEvent loggingEvent)
        {
            foreach (IAppender usedAppender in LogManager.GetRepository().GetAppenders())
            {
                usedAppender.DoAppend(loggingEvent);
            }
        }
    }
    

    and finally a setup class that ties the two and configures log4net:

    public class CrossDomainChildLoggingSetup : MarshalByRefObject
    {
        private CrossDomainParentAppender parentAppender;
    
        public void ConfigureAppender(CrossDomainParentAppender crossDomainParentAppender)
        {
           parentAppender = crossDomainParentAppender;
           CrossDomainOutboundAppender outboundAppender = new CrossDomainOutboundAppender(parentAppender);
           log4net.Config.BasicConfigurator.Configure(outboundAppender);
        }
    }
    

    Now - when you setup up your AppDomain you can add the following code...

    CrossDomainParentAppender crossDomainParentAppender = new CrossDomainParentAppender();
    Type crossDomainType = typeof(CrossDomainChildLoggingSetup);
    CrossDomainChildLoggingSetup crossDomainChildLoggingSetup = (CrossDomainChildLoggingSetup)domain.CreateInstanceFrom(crossDomainType.Assembly.Location, crossDomainType.FullName).Unwrap();
    crossDomainChildLoggingSetup.ConfigureAppender(crossDomainParentAppender);
    

    ...and everything logged in the child domain turns up in the parent domains log. (Please note: I used CreateInstaceFrom(assemblyFilePath,...) - depending on your setup you may not require loading by filePath)

    Although I haven't found any bugs or problems: If you see any flaws or problems that could arise please let me know.

提交回复
热议问题