6

Is there any .NET logging framework that have ability to switch appender if something is wrong with current one. Actually what I want is following:

If I'm using database appender and when something goes wrong with database (e.g. server goes down, lose power...) I want to switch to second appender (e.g. which log into file).

Does this ability have one of following: log4net, NLog, Enterprise Library? I was looking for this but no luck.

zvjerka24
  • 1,772
  • 1
  • 21
  • 27
  • Nlog allows you to write your own Target. You can then add your requirements. http://nlog-project.org/wiki/How_to_write_a_Target#Do_I_really_need_to_create_a_separate_DLL.3F (As a last resort maybe :) – robasta Jan 13 '12 at 11:01
  • I've found solution, please see my answer below. – zvjerka24 Jan 17 '12 at 10:39

5 Answers5

3

For completeness: Enterprise Library supports a configurable Error Special Source where you can set an "appender" to log messages that have errored. Once configured this just works without any programming.

The only downside is that it will actually log the exception that occurred along with the Log Entry details in a specific format that cannot be changed so it is not flexible. This is good for troubleshooting but it might not be ideal if you want to extract errored log messages and import them into the original logging destination (although the format is known so it would be possible to parse).

Randy Levy
  • 22,566
  • 4
  • 68
  • 94
2

As far as I know log4net currently does not support backup appenders, there is (or was?) an open issue in the log4net feature backlog. But I think that the project called FallbackAppender does exactly what you need.

Igor Korkhov
  • 8,283
  • 1
  • 26
  • 31
  • You are right, this is exactly I need, but when I tried it and tested it seems that this is not working as expected. e.g. If you are using two FileAppenders and one fails, next time when that one is recovered, it tries to use it again, but fails. Same problem is happening with database. Maybe I didn't configure it correctly, but definitely it is not working as expected. Thank you for your tine. – zvjerka24 Jan 17 '12 at 08:29
  • I've found solution, please see my answer below. – zvjerka24 Jan 17 '12 at 10:41
2

Because log4netContribute FallbackAppender is not working as expected I've made deep research and found that this ability has nLog. I tested it and it is working like a charm ;) Here is an example:

[app.config]

<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="appTitle" value="My Application"/>
<targets>
<target name="file" xsi:type="FallbackGroup" returnToFirstOnSuccess="true">
<target xsi:type="File" fileName="x:\vladimir.txt" />
<target xsi:type="File" fileName="w:\pavlovic.txt" />
<target xsi:type="File" fileName="w:\zvjerka24.txt" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
</configuration>

[code]

Logger _logger = LogManager.GetCurrentClassLogger();
_logger.Info("Neki Info");
_logger.Debug("Neki debug");
_logger.Error("Neki  ERROR");
_logger.Error("Pa jos neki");
zvjerka24
  • 1,772
  • 1
  • 21
  • 27
1

Yes, Log4Net allows you to have multiple log destinations, such as: Log file, Email, Database, and Event Viewer.

You can change the destination in the application's config file. You can also run more than one at the same time - e.g. log to the Event Viewer and database.

I'd always recommend having two log destinations by default - in case one of the them has a problem.

Joe Ratzer
  • 18,176
  • 3
  • 37
  • 51
  • I know that, but is there a way to switch appender from database to file at runtime (from code) if we got exception while logging into DB? – zvjerka24 Jan 13 '12 at 11:09
  • Not via Log4Net iteself, but you can easily update the web.config within your code. As one log destination might have problems, it's always a good idea to have two anyway. Which would mean you don't need to worry about writing code that updates the web.config. – Joe Ratzer Jan 13 '12 at 11:11
  • I've found solution, please see my answer below. – zvjerka24 Jan 17 '12 at 10:41
1

NLog allows you to log to multiple targets via a configuration file. Don't forget to set ignoreFailures to true to ensure that any install/uninstall failures are ignored:

<?xml version="1.0" encoding="utf-8" ?> 
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets>
        <target name="logfile" xsi:type="File" />
        <target name="db" xsi:type="Database" />
    </targets>

    <rules>
        <logger name="*" levels="Info" writeTo="logfile,db" />
    </rules>
</nlog> 

See database target in the NLog documentation for more information

Edit: You could also create a custom target in order to achieve this in code:

using NLog; 
using NLog.Targets; 

namespace MyNamespace 
{ 
    [Target("MyFirst")] 
    public sealed class MyFirstTarget: TargetWithLayout 
    { 
        public MyFirstTarget()
        {
            this.Host = "localhost";
        }

        [Required] 
        public string Host { get; set; }

        protected override void Write(LogEventInfo logEvent) 
        { 
            string logMessage = this.Layout.Render(logEvent); 

            SendTheMessageToRemoteHost(this.Host, logMessage); 
        } 

        private void SendTheMessageToRemoteHost(string host, string message) 
        { 
            // Detect your database state here or do something else with the error.
        } 
    } 
}

and use it with:

<nlog> 
  <extensions> 
    <add assembly="MyAssembly"/> 
  </extensions> 
  <targets> 
    <target name="a1" type="MyFirst" host="localhost"/> 
  </targets> 
  <rules> 
    <logger name="*" minLevel="Info" appendTo="a1"/> 
  </rules> 
</nlog>

See this page for more information.

Nick
  • 5,844
  • 11
  • 52
  • 98