Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.2.9
    • Fix Version/s: 1.2 Maintenance Release
    • Component/s: Appenders, Core
    • Labels:
      None
    • Environment:
      From sourceforge

      Description

      Basically, I'm looking for the ability to set up a hierarchy of appenders so that if a log to an ADONETAppender fails, log4net could then log to one of more "back-up" appenders, for example, a RollingLogFile or SMTP.

      Thanks,
      Leo

      Leo J. Hart IV

      1. RemotingAppender.cs
        17 kB
        Julie Sheffield

        Activity

        Hide
        Dietmar Kurok added a comment -

        Hello Julie,
        sometimes reading helps; you wrote it perfectly in your comment: Just adding the appender-ref in the main appender like this helps:
        <!-- "Normal" appender which logs to a WCF-service (NetTcp.WCFAppenderServiceEndpoint is a named endpoint in my client's <system.serviceModel><client>configuration...)->

        <appender name="WcfAppender" type="log4net.Appender.WCFAppender, WCFAppender ">
        <!--<layout type="log4net.Layout.PatternLayout">
        <ConversionPattern value="%m" />
        </layout>-->
        <bufferSize value="5" />
        <lossy value="true"/>
        <!-<sink value="WCFAppenderServiceEndpoint" />->
        <sink value="NetTcp.WCFAppenderServiceEndpoint" />
        <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="ERROR" />
        </evaluator>
        <errorHandler type="log4net.Appender.WCFAppenderErrorHandler, WCFAppender" />
        <appender-ref ref="RollingLogFileAppender"/>
        </appender>

        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
        <file value="logfile.txt" />
        <appendToFile value="false" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="-1" />
        <maximumFileSize value="50GB" />
        <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property

        {NDC}

        ] - %message%newline" />
        </layout>
        </appender>

        Show
        Dietmar Kurok added a comment - Hello Julie, sometimes reading helps; you wrote it perfectly in your comment: Just adding the appender-ref in the main appender like this helps: <!-- "Normal" appender which logs to a WCF-service (NetTcp.WCFAppenderServiceEndpoint is a named endpoint in my client's <system.serviceModel><client> configuration...) -> <appender name="WcfAppender" type="log4net.Appender.WCFAppender, WCFAppender "> <!--<layout type="log4net.Layout.PatternLayout"> <ConversionPattern value="%m" /> </layout>--> <bufferSize value="5" /> <lossy value="true"/> <!- <sink value="WCFAppenderServiceEndpoint" /> -> <sink value="NetTcp.WCFAppenderServiceEndpoint" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="ERROR" /> </evaluator> <errorHandler type="log4net.Appender.WCFAppenderErrorHandler, WCFAppender" /> <appender-ref ref="RollingLogFileAppender"/> </appender> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="logfile.txt" /> <appendToFile value="false" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="-1" /> <maximumFileSize value="50GB" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property {NDC} ] - %message%newline" /> </layout> </appender>
        Hide
        Dietmar Kurok added a comment -

        Julie,
        your solution seems perfect for an issue I have with an appender using a WCF-service (little bit different from your RemotingAppender, nut very similar). How do you configure your appenders (both the RemotingAppender and the "failover"-appender so that in normal work the RemotingAppender is used but only in case of failure in this the other appender is used. Can you post your configuration ?

        Many thanks

        Dietmar

        Show
        Dietmar Kurok added a comment - Julie, your solution seems perfect for an issue I have with an appender using a WCF-service (little bit different from your RemotingAppender, nut very similar). How do you configure your appenders (both the RemotingAppender and the "failover"-appender so that in normal work the RemotingAppender is used but only in case of failure in this the other appender is used. Can you post your configuration ? Many thanks Dietmar
        Hide
        Nicko Cadell added a comment -

        I am currently out of the office with no access to emails until September 15th. If your email is urgent please contact Rick Hobbs or Nigel Atkinson on 020 7025 0950, otherwise I will respond on my return.

        Thanks,
        Nicko

        Show
        Nicko Cadell added a comment - I am currently out of the office with no access to emails until September 15th. If your email is urgent please contact Rick Hobbs or Nigel Atkinson on 020 7025 0950, otherwise I will respond on my return. Thanks, Nicko
        Hide
        Julie Sheffield added a comment - - edited

        I implemented this behavior for the RemotingAppender by having it implement IAppenderAttachable (exactly the way ForwardingAppender implements it). Then I could add the backup appender just by specifying appender-ref in log4net.config. Then in the catch block, before calling ErrorHandler.Error(message, ex), I look to see if any appenders have been attached and forward the LoggingEvent to them.

        Of course, this approach is specific only to the RemotingAppender. Since that's what I need for the project I'm working on, that's what I've tested extensively, but it seems like it wouldn't be hard to take a similar approach with other potentially error-prone appenders like ADONetAppender if it's too disruptive to change the entire IErrorHandler interface.

        In the meantime, should I check in my changes to RemotingAppender? Seems like that one is particularly susceptible to potential intermittent interruptions and other HA applications might need similar behavior to what I've implemented and tested. I've attached my code so people could take a look and see if it's worth including.

        Thanks!

        Show
        Julie Sheffield added a comment - - edited I implemented this behavior for the RemotingAppender by having it implement IAppenderAttachable (exactly the way ForwardingAppender implements it). Then I could add the backup appender just by specifying appender-ref in log4net.config. Then in the catch block, before calling ErrorHandler.Error(message, ex), I look to see if any appenders have been attached and forward the LoggingEvent to them. Of course, this approach is specific only to the RemotingAppender. Since that's what I need for the project I'm working on, that's what I've tested extensively, but it seems like it wouldn't be hard to take a similar approach with other potentially error-prone appenders like ADONetAppender if it's too disruptive to change the entire IErrorHandler interface. In the meantime, should I check in my changes to RemotingAppender? Seems like that one is particularly susceptible to potential intermittent interruptions and other HA applications might need similar behavior to what I've implemented and tested. I've attached my code so people could take a look and see if it's worth including. Thanks!
        Hide
        Tom Cooley added a comment -

        I have a fairly simple (if not naive) solution to the Fallback appender concept, something I wish were available right now.

        Why not add the following to the IAppender interface:

        IAppender FallbackAppender

        { get; set; }

        Implement the new property in the AppenderSkeleton, and then change the catch block of the two DoAppend methods to be something like:
        if (FallbackAppender != null)

        { FallbackAppender.DoAppend(loggingEvent); }

        else

        { ErrorHandler.Error("Failed in DoAppend", ex); }

        From a configuration perspective, you identify the FallbackAppender at each appender level, allowing a hierarchy of fallbacks. If it reaches the end of the chain and still cannot append the event, the ErrorHandler.Error finally kicks in.

        Too simple? I'm fairly new to log4net and have not spent a huge amount of time getting to know the code, but that seems like a fairly simple extension point that has fewer touch points than handling this within the ErrorHandler.

        Show
        Tom Cooley added a comment - I have a fairly simple (if not naive) solution to the Fallback appender concept, something I wish were available right now. Why not add the following to the IAppender interface: IAppender FallbackAppender { get; set; } Implement the new property in the AppenderSkeleton, and then change the catch block of the two DoAppend methods to be something like: if (FallbackAppender != null) { FallbackAppender.DoAppend(loggingEvent); } else { ErrorHandler.Error("Failed in DoAppend", ex); } From a configuration perspective, you identify the FallbackAppender at each appender level, allowing a hierarchy of fallbacks. If it reaches the end of the chain and still cannot append the event, the ErrorHandler.Error finally kicks in. Too simple? I'm fairly new to log4net and have not spent a huge amount of time getting to know the code, but that seems like a fairly simple extension point that has fewer touch points than handling this within the ErrorHandler.
        Hide
        Drew Schaeffer added a comment -

        Should the FallbackAppender property be added to OnlyOnceErrorHandler or to the IErrorHandler interface? I think it should be on the interface as this would be a nice feature for all implementations to have.

        Show
        Drew Schaeffer added a comment - Should the FallbackAppender property be added to OnlyOnceErrorHandler or to the IErrorHandler interface? I think it should be on the interface as this would be a nice feature for all implementations to have.
        Hide
        Nicko Cadell added a comment -

        Error handling in Appender is difficult. One potential way of implementing this is to use the error handler, however we may need to find a more robust solution.

        log4net appenders use the log4net.spi.IErrorHander interface to report errors.

        Change all the methods in this interface to add a LoggingEvent as the first argument.
        Change all the callers of this interface to pass the current logging event along with the error message.
        Change the implementation of log4net.Util.OnlyOnceErrorHandler to implement the interface changes.
        Add a property to the OnlyOnceErrorHandler called FallbackAppender of type IAppender, the value should be stored in a field.
        When one of the Error methods on OnlyOnceErrorHandler is called then call fallbackAppender.DoAppend with the logging event.

        This will cause the event to be routed to the fallback appender whenever an error occurs on the first appender. As each appender can have an ErrorHander defined this allows an unlimited number of fallback appenders.

        Show
        Nicko Cadell added a comment - Error handling in Appender is difficult. One potential way of implementing this is to use the error handler, however we may need to find a more robust solution. log4net appenders use the log4net.spi.IErrorHander interface to report errors. Change all the methods in this interface to add a LoggingEvent as the first argument. Change all the callers of this interface to pass the current logging event along with the error message. Change the implementation of log4net.Util.OnlyOnceErrorHandler to implement the interface changes. Add a property to the OnlyOnceErrorHandler called FallbackAppender of type IAppender, the value should be stored in a field. When one of the Error methods on OnlyOnceErrorHandler is called then call fallbackAppender.DoAppend with the logging event. This will cause the event to be routed to the fallback appender whenever an error occurs on the first appender. As each appender can have an ErrorHander defined this allows an unlimited number of fallback appenders.

          People

          • Assignee:
            Unassigned
            Reporter:
            Nicko Cadell
          • Votes:
            4 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:

              Development