Friday, May 18, 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: Using log4Net to log multiple files by different users/tasks
Prev Next
You are not authorized to post a reply.

Author Messages
Mark A. DeMichele

10/05/2008 3:43 PM  
I have an asp.net site in which different users run different tasks.  Each individual task is managed by a TaskManager that I'm writing.  While each task is running it has the opportunity to log to it's own log file.  I'm trying to use Log4Net to do this, but so far I've been unable to figure out how exactly to accomplish this.  Any advice would be appreciated.
 
So far, I believe I must create an individual Appender for each task.  Something like this.

PatternLayout layout = new PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
FileAppender appender = new FileAppender();
appender.Layout = layout;
appender.File =
"d:\\logs\\" + TaskID.ToString()+ ".txt";
appender.AppendToFile =
true;
appender.Name =
"File";
appender.Threshold = log4net.Core.
Level.All;
appender.ActivateOptions();

And I know that eventaully, I'll want to code to call something like

ILog _Log = LogManager.GetLogger(TaskID.ToString());

But I can't figure out how to make that logger unique and how to associate that single appender to it and not to have that single appender interfere with other users and tasks.

I'm starting to think that this is not possible with Log4Net.  Maybe Log4Net is made more to have global loggers and not many individual task related ones.  I'd appreciate any help anyone can give me.

Thanks.

Ron Grabowski

10/05/2008 5:51 PM  
In your code the File property gets set when the Appender is created. Here's an example showing how to set the File property based on each logging event:

http://svn.apache.org/viewvc/logging/log4net/trunk/examples/net/1.0/Appenders/SampleAppendersApp/cs/src/Appender/PatternFileAppender.cs?view=markup

That example code is probably slow. log4j and nlog have file appenders that keep the most recent files open so you don't have to pay the open/close penalty.

You could probably extend the FileAppender and override a method or two to do what you want.
Mark A. DeMichele

10/06/2008 12:19 AM  
I'm not sure you're completing understanding my dilema.  I need to basically create loggers on the fly which are associated with separate files.
 
I did actually get something working, but now I can't figure out how to clean up.  This is what I have so far. 
 
To start I create a repostitory and give it a name.  I then store the repository pointer in a static variable.
 
Then when I start a specific task, I use the repository to create a logger and I add a file appender to that logger.  The file appender is associtated with a unique file name.  My task has a unique id and I used tha same id to name the logger.  All my logging for that task uses that logger with that name and everything seems ok.
 
Now here's the problem.  When my task is done, I would like to clean up that logger and remove it from the repositry, but there doesn't seem to be a way to do this.  I fear that based on my design, if my server is running for days on end, the hash table where the loggers are stored in the repository will grow and grow.   I used Reflector to look at the code in the Hierarchy object. but there doesn't seem to be a way to remove an object from the hash table.
 
Ron Grabowski

10/06/2008 5:48 AM  
The source code to log4net is available at:

 http://svn.apache.org/viewvc/logging/log4net/trunk/src/

If you're wondering how something works that may be a better place to look. Most (all?) of the source is commented.

Its acceptable to create a new repository for medium to long running tasks. When you shutdown the repository it automatically shuts down all of its appenders and loggers.

Mark A. DeMichele

10/06/2008 4:52 PM  
Actually I have been looking at the code.  Sometimes it's easier to do it in Reflector since you can easily drill down and also find where methods are called from.  In any case, my major problem was to clean up the ILogger objects when I was through with them.  Since that didn't seem possible, I did as you suggested and modified my code to create separate repositories.  One for each task.  The first problem was checking to see if the repository existed (without catching exceptions which are slow).   LogManager doesn't seem to have a .RespositoryExists method, but I was able to achieve it through some typecasting.   I wound up doing something like this.
 

ILoggerRepository loggerRep;
if (((DefaultRepositorySelector)LoggerManager.RepositorySelector).ExistsRepository(TaskID.ToString())) {
  loggerRep = LogManager.GetRepository(TaskID.ToString());
} else {
  loggerRep = LogManager.CreateRepository(TaskID.ToString());
}

It isn't pretty, but it did the job.  I suggest someone add a ExistsRepository to the LogManager class.

So now my design has one repository per Task, one Logger per repository, and one Appender per Logger.  Seems like an overkill, but what the heck, it's funcitonal.

So now after all this, I go to write the code to clean all this up when my task is completed.  So I do something like this.

if (((DefaultRepositorySelector)LoggerManager.RepositorySelector).ExistsRepository(TaskID.ToString())) {
  LogManager.ShutdownRepository(TaskID.ToString());
}

Well, this doesn't crash or anything, but if you look at the code when you call ShutdownRespository, it still doesn't clean up the pointers to the Repository so it stays in memory.  What's up with this.  I guess clean up isn't a high priority for Log4Net since it's meant to handle global type logging tasks.  For my design this is bad since now these objects will never being garbage collected.  I noticed that the repository has a Shutdown event.  I wonder if the RepositorSelector should listen to that event and remove the Repository from it's private hashtable.

I'm really starting to think the Log4Net is not a good choice for what I'm doing. 

All I'm really looking for is to write a tab delimitted file in a thread safe way while allowing other threads to read from it while I'm writing.  I wonder if there's something else out there that's simpler and more suited for what I'm trying to do.

Parrish, Ken

10/06/2008 5:44 PM  

I’ve been following this thread and wanted to suggest that you consider the possibility of using the MSMQ or ADO appenders for this purpose.  Both appenders, by the very nature of MSMQ and Database servers, allow for multiple, simultaneous connections and would afford a seamless, high level mechanism for gathering log messages from multiple applications, or across multiple load balanced or clustered servers into a single, serialized repository.

 

In the case of MSMQ, you’d need to write a very simple .NET Windows Service application that drains the queue and serializes the log messages into a single file (or other repository).  In the case of the ADO.NET appender, you’d need to perform and ad-hoc query, or write a very simple application to fetch log messages from the DB.

 

Both these solutions a little (really small) bit more work, but ultimately, far more flexible and better suited to gathering and distributing log messages from multiple applications and/or servers in an enterprise environment.

 

Ken Parrish

Gomez, Inc.

 

Francine Taylor

10/06/2008 10:00 PM  

What about a system where you have a “bank” of loggers?

 

First, you could have an array which would contain three values; the generated logger name, a flag indicating whether the logger was being used, and a task ID (empty if the logger was not being used).

 

Whenever you need a new logger, you check to see if one is available.  If not, you create it and add an entry to the logger array.

 

Either way, you just call the RemoveAllAppenders() method on that logger, create an appender and attach it to the logger, set the task ID for the logger, and mark it as not available.

Edwin McNamara

10/07/2008 12:36 AM  
Good idea.
You are not authorized to post a reply.
Forums > Log4Net > Log4Net Mail archive > Using log4Net to log multiple files by different users/tasks



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