Monday, May 21, 2012
 
The best way to analyze your logs! Minimize
 Log4Net Mail archive   

The Log4Net mailing list is a great source of information about using log4Net, in this forum we collect all the messages in the log4net user list and some selected threads from the developer list.

Subject: Re: Error destroying my productivity Please Help!: log4net:ERROR [] Attempted to append to closed appender named []
Prev Next
You are not authorized to post a reply.

Author Messages
Ross Hinkley

04/08/2009 2:54 PM  
You can specify a threshold value in the appender.  That would allow you to log messages from a given level and higher.  For example, as a child to the appender node:

<threshold value="INFO">

would log Info messages, Warning messages, and so on.  From there, you can use Ron's suggestion for controlling what you want to see overall and to manage multiple appenders.

If I understand your question, Omatase, it sounds like you want to log one log level per file, maybe?  I'm not certain you can specify an upper threshold to an appender.  I've never used log4net in such a fashion.  Does anyone know if you can set an upper limit on an appender?

Omatase, if you need a more complete example, let me know.

-Ross
Daniel Marohn

04/08/2009 4:59 PM  

Hi!

...
Someone else might have an application that they would like to send
DEBUG messages to the FileAppender
even though my application may only send FATAL
...

this is, why you have different logger.
from your first post:

<logger name="Invoicing">
...
</logger>

<logger name="Invoicing">
...
</logger>

this makes no sense. You configure the logger 'Invoicing' and later
you configure the SAME logger with different properties. How do you
want to access these 'two' loggers from your code?
LogManger.GetLogger("Invoicing, but please first version") ? ;-)

You can do this:

  <appender name="consoleTestAppender" type="log4net.Appender.ConsoleAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %-5level %logger - %message%newline" />
    </layout>
  </appender>

<logger name="Invoicing.Application1">
 <level value="ERROR" />
 <appender-ref ref="consoleTestAppender" />
</logger>

<logger name="Invoicing.Application2">
 <level value="WARN" />
 <appender-ref ref="consoleTestAppender" />
</logger>

now you have two different loggers  (one for each app), using the same
appender. And you can set the Level per Logger.

Perhaps you want to define another one:

<logger name="Invoicing">
 <level value="ALL" />
 <appender-ref ref="consoleTestAppender" />
</logger>

now you have also the root logger (Invoicing). So you can configure
global settings for all Invoicing loggers or for every single one ...


have fun!

Daniel

Ross Hinkley

04/08/2009 6:07 PM  
Omatase,

What you want would be something like the following (I'm guessing):

<log4net debug="false" threshold="ALL" >
    <appender name="WarningAppender" type="log4net.Appender.ConsoleAppender">
        <threshold value="WARN"/>
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[WarningAppender] - %message%newline" />
        </layout>
    </appender>
    <appender name="InfoAppender" type="log4net.Appender.ConsoleAppender">
        <threshold value="INFO"/>
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[InfoAppender] - %message%newline" />
        </layout>
    </appender>

    <root>
        <appender-ref ref="WarningAppender" />
        <appender-ref ref="InfoAppender"/>
    </root>
</log4net>

This way, if you log to the same logger, you'll get two separate messages in (potentially) two separate places. 

It sounds like you want to tackle a fairly common scenario: When your application encounters a fatal error, you want to receive a notification about it.  You could set up your SNMP appender to have a threshold of FATAL.  You would also receive that error in the other appenders you have set up.  Typically, I would think you wouldn't care if you get the fatal error logged multiple times, especially so you could figure out (from the DEBUG log, for example) what your application was trying to do when the error occurred.

Does that make sense?

-Ross
Daniel Marohn

04/08/2009 6:12 PM  

>
> log4net is intelligent enough to handle this.
>

thx for pointing this out.


what about this:

<appender name="FatalSmtAppender" type= ...>
<threshold value="WARN"/>
</appender>

<root>
        <appender-ref ref="FatalSmtAppender" />
</root>


this will deliver all Messages to the appender, but only fatals are delivered...

Daniel Marohn

04/08/2009 6:41 PM  

I did some research about this

I checked the log4net sources. The error is thrown in
AppenderSkelleton (the base class of all appenders).
public void DoAppend(LoggingEvent[] loggingEvents)  {
..
if (m_closed)
  {
    ErrorHandler.Error("Attempted to append to closed appender named
["+m_name+"].");
    return;
  }
}

m_closed in only set in
public void Close()

it reads in code docu:
It is a programming error to append to a closed appender.

Perhaps this is really a bug in one of the log4net appenders.

Can you post a simple as possible config, that reproduces the error on
your system? I will try to reproduce this and debug into log4net to
see whats going wrong with the appender.

Edwin McNamara

04/09/2009 12:34 AM  


2009/4/8 omatase <Omatase@gmail.com>


Daniel Marohn wrote:
>
> I did some research about this
>
> I checked the log4net sources. The error is thrown in
> AppenderSkelleton (the base class of all appenders).
> public void DoAppend(LoggingEvent[] loggingEvents)  {
> ..
> if (m_closed)
>   {
>     ErrorHandler.Error("Attempted to append to closed appender named
> ["+m_name+"].");
>     return;
>   }
> }
>
> m_closed in only set in
> public void Close()
>
> it reads in code docu:
> It is a programming error to append to a closed appender.
>
> Perhaps this is really a bug in one of the log4net appenders.
>
> Can you post a simple as possible config, that reproduces the error on
> your system? I will try to reproduce this and debug into log4net to
> see whats going wrong with the appender.
>
>

Thanks for your help. Following is a minimalist example of one that fails.
The error it causes is "log4net:ERROR [FileAppender] Attempted to append to
closed appender named [FileAppender]." and can be seen in the Visual Studio
"Output" window.


 <log4net>
   <root>
     <level value="DEBUG" />
     <appender-ref ref="FileAppender" />
   </root>
   <logger name="Invoicing">
     <level value="DEBUG" />
     <appender-ref ref="FileAppender" />
   </logger>
   <logger name="Invoicing">
     <level value="FATAL" />
     <appender-ref ref="FileAppenderFatal" />
   </logger>
   <!-- Setup the root category, add the appenders and set the default
level -->
   <appender name="FileAppender" type="log4net.Appender.FileAppender">
     <file value="C:\Log.txt" />
     <appendToFile value="true" />
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
     <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
     </layout>
   </appender>
   <appender name="FileAppenderFatal" type="log4net.Appender.FileAppender">
     <file value="C:\LogFatal.txt" />
     <appendToFile value="true" />
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
     <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
     </layout>
   </appender>
 </log4net>

You'll see that although the example *may* not be practical, it should be
possible. It's not super realistic for someone to want a FileAppender only
for FATAL messages although it *could* happen. I replaced the AdoNetAppender
with the FileAppenderFatal in the interest of making the smallest possible
reproducible configuration.

Interestingly, this configuration does *not* reproduce the error:

 <log4net>
   <root>
     <level value="DEBUG" />
     <appender-ref ref="FileAppender" />
   </root>
   <logger name="Invoicing">
     <level value="FATAL" />
     <appender-ref ref="FileAppenderFatal" />
   </logger>
   <logger name="Invoicing">
     <level value="DEBUG" />
     <appender-ref ref="FileAppender" />
   </logger>
   <!-- Setup the root category, add the appenders and set the default
level -->
   <appender name="FileAppender" type="log4net.Appender.FileAppender">
     <file value="C:\Log.txt" />
     <appendToFile value="true" />
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
     <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
     </layout>
   </appender>
   <appender name="FileAppenderFatal" type="log4net.Appender.FileAppender">
     <file value="C:\LogFatal.txt" />
     <appendToFile value="true" />
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
     <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
     </layout>
   </appender>
 </log4net>

The only difference between the two was I swapped the positioning of the two
loggers.
Daniel Marohn

04/15/2009 2:31 PM  

Hallo again ...

I was not able to reproduce your problem. The config runs without
errors on my system.

But I had some time to study the log4net sources and can tell you,
that there is totaly no way to configure 2 Loggers  with the same
name.

The reason: The Repository stores all Logers in a Hashtable; the
logger name is used as the key for this table, so it's impossible to
store two loggers with the same name. What happens in XmlConfig is
like this:

It loops through root xml elements. For every Logger element, it calls
getLogger(Name) to get the logger (wich will create a new logger or
return the allready created if exists). Level is set/overriden,
AppenderRefs are erased, and recreated.

In the end, your Logger is allways configured like the last definition
in configfile.

You can profe this very simple for yourself:
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net")]
namespace ConsoleApplication1
{
   class Program
   {
       static void Main(string[] args)
       {
           foreach (log4net.Repository.Hierarchy.Logger  curLog in
log4net.LogManager.GetRepository().GetCurrentLoggers())
           {
               Console.WriteLine("logger {0} - level {1} ",
curLog.Name,curLog.Level);
               foreach (log4net.Appender.IAppender curAppender in
curLog.Appenders )
               {
                   Console.WriteLine("{0} - {1}", curAppender.Name,
curAppender.GetType().FullName);
               }
           }
           Console.ReadLine();
       }
   }
}

Hard to say why your FileAppender crashes. Are you using the target
file in other processes? Perhaps log4net is not able to open the
FileHandle and runs into the 'cannot write to closed appender'
exception?

You are not authorized to post a reply.
Forums > Log4Net > Log4Net Mail archive > Re: Error destroying my productivity Please Help!: log4net:ERROR [] Attempted to append to closed appender named []



ActiveForums 3.7

 

 

 

 

 

 

 

 

Log4Net Dashboard

Log analysis and monitoring made easy!

Log4Net Dashboard is a log viewer that can read log statements from a variety of logging output targets.

You can download a free developer version.

  

Check it out!

On the demonstration site you can try it  with live data.demo.l4ndash.com - Try Log4Net Dashboard with live data

The mail archive is a copy of all the mail sent to the mail address: log4net-user@logging.apache.org, organized as a forum.

If you would like to participate in the mail list, send a mail to log4net-user-subscribe@logging.apache.org.

More information about the mailing list is available on: http://logging.apache.org/log4net/support.html

 

A complete topic list is available and can be viewed here (warning, it takes some time to load)

 

Copyright 2005-2008 by FaktNet AS Terms Of Use Privacy Statement