Help: How to log exception to the same file?

Topics: Exception Handling Application Block, Logging Application Block
Nov 4, 2007 at 11:55 AM
Hi,

I am using EntLib 3.1 and I have a very simple configuration. I have set up a Exception Policy and it intercepts an exception, in my demo it is IndexOutOfRangeException and I add a Logging handler in this policy.

The Logging Handler's LogCategory is set to 'General' and in my Logging Application Block, I have a 'General' category and the trace listener is set to a 'FlatFile TraceListener' and the trace file is the 'trace.log'. I do not use any other trace listener - only one.

In my Demo, I deliberately threw the IndexOutOfRangeException and I followed the example to pass this exception to the exception policy. I also have used Logger.Write() at various places.

When my demo program completes, instead of having one trace.log file, I have 2 files! What is going one?

One is the trace.log file and it contains all the messages I wrote out with Logger.Write(). The second one has the suffix 'trace.log' with a prefix that is a Guid like this '1e623643-48b5-469d-90d3-90eccd70dc15trace.log'. The content of this one is the exception being logged in the Logging Handler in the Exception Policy.

Can someone explain to me why it is like this? Is it possible to direct the exception log and logger message into one file so that they appear in chronological order?

This is driving me mad. Thanks.

Leon
Nov 5, 2007 at 11:40 AM
I believe I have found the explanation to my observation and I strongly believe that you cannot stream the exception logged materials from EHAB into the same file as that for the LAB's generated message when using any file based trace listener.

My explanation is derived mainly from code reading the Ent Lib source and experimentation. You see, the FlatFileTraceListener is derived from FormattedTextWriterTraceListener that in terms is derived from TextWriterTraceListener.

If you have a situation like this:

TraceListener[] listeners = new TraceListener[2];
listeners[0] = new TextWriterTraceListener( "trace.log", "1" );
listeners[1] = new TextWriterTraceListener( "trace.log", "2" );

listeners[0].WriteLine( "Hello World" ); // goes to trace.log
listeners[1].WriteLine( "Hello World" ); // goes to <guid>trace.log, e.g. d129d95f-6ab0-4618-96b8-03ab561d235ftrace.log

For location in EHAB source yet to be positively identified, I suspect that EHAB and LAB both creates and caches a FlatFileTraceListener using the same file when the EHAB's logging handler is using a category specified in LAB. When there is no logging handler in EHAB or when there is no Logger.Write() calls, there is only one instance of FlatFileTraceListener using that file and this explains why there is no guid prefixed file.

The moment I have logging handler in EHAB and Logger.Write() using same category I encounter this guid prefixed file. This is because that is the default behavior of the base class, the TextWriterTraceListener, as shown in my demo code above.

I am puzzled as why EHAB needs to create a instance of FlatFileTraceListener and it can't simply use the instance created in LAB, particularly when EHAB needs LAB in tandem to work. If that is used perhaps then the exception materials can be streamed into the same file to handle the Logger.Write().

I am wondering if future version of Ent Lib can handle this?

Thanks.

Leon
Nov 6, 2007 at 9:05 PM
I would like to support the "No-Prefix" option as well.. or at least be able to specify what to use for a prefix (Guid, ActivityID, custom, etc...).

In my current solution I (was) trying to get everything logged to a single file (Tracing, Logging, Exceptions) so that I could just increase the Levels listeners accepted and get more verbosity in the file (showing where exceptions occured within the tracing etc)...

Since this was not possible I have to also litter my code with Logger.Write() wherever exceptions are caught if I want the exception info put into the File I am writing Trace/Logging to. I also must record additional information to ensure the ability to track down which request caused an exception and detail related (which I have overcome by catching and wrapping uncaught exceptions at the top level with a custom exception which contains the detail).

Im sure I could leverage Entlib better if I understood better how these things should tie together but ... this was the only way I could propagate instance information without double/triple/quadruple logging everything.

Thanks for EntLib !!!!
Nov 8, 2007 at 1:05 PM
Thanks for bringing this up. I as well will need a solution to this.

The bigger problem I see is that every time the windows application that I'm logging is restarted, a new file with a new GUID prefix is created. While the application is running all exceptions get appended in the same log file...but restarting the application has even more undesirable effects. I already want to limit files (delete files 2 weeks old - which isn't possible)...now I'm going to have a bunch of exception files that don't have a time stamp. Grrrr

I'd like to know of a solution to maintain everything in one sink.

Thanks.
Nov 8, 2007 at 1:37 PM

The bigger problem I see is that every time the windows application that I'm logging is restarted, a new file with a new GUID prefix is created. While the application is running all exceptions get appended in the same log file...but restarting the application has even more undesirable effects. I already want to limit files (delete files 2 weeks old - which isn't possible)...now I'm going to have a bunch of exception files that don't have a time stamp. Grrrr

I'd like to know of a solution to maintain everything in one sink.

Thanks.

Yes, I think you are running into the same trap as I am attempting. Trying to stream everything into one log file (very natural requirement) rather than giving the EHAB its own distinct trace listener, thus its own file. It is problematic trying to reconcile the exception log with the operations trace. I am really shocked when I found this with Ent Lib as I would have thought that kind of requirement is second nature to those needing Ent Lib and to the authors of Ent Lib.

Does anyone has experience with Log4Net in this regard? Care to offer some comments?

That's one of the reasons why I raised this issue here in the hope any Ent Lib, particularly EHAB, author will jump in to offer some insight into this issue and some guidance in using this. Not everyone prefer to use the Event Log or Database log. The good old text files still being loved by many.

Leon
Nov 9, 2007 at 7:23 PM
In my project I have a many trace listeners writing to the same file so different sources can use different formatters within the file. This works well for all non-exception logging. Once an exception is written to the
"group" trace listener EntLib creates another file of the same name prefixed with a unique GUID where the exception detail gets written (an omitted from the file without the guid).

I can see the usfulness of this but without precautions of data being written with the exception (activityID, handlingInstanceID, etc) there is a disconnect between the logging chain and the exception.

One alternative is to write a Log within the catch block before calling exceptionpolicy.handleexception() with some detail about the exception. The problem is that this does not help if your not catching the exception at that point. To overcome this situation I implemented a global catch block which ignores any of my custom exceptions (which are populated with tracking data when thrown) and wraps all other exceptions with one of my custom exceptions and includes the tracking data which is then thrown up to the ExceptionPolicy.HandleException(). ***This allows me to get the tracking data for the exception to match up with the logging and I dont have to write extra log entries... plus I can just inspect the exception (in whatever tracelistener I want) and immediately know all the other custom instance data (state) when it was thrown without having to track it down in a giant log file. ****Plus I dont have to be allowing lower log levels (tracing, info, warning, etc) to get the (state) information.
Nov 27, 2007 at 11:09 AM
Edited Nov 27, 2007 at 11:15 AM
I have the same problem. I'm trying to put log and exception data into the same file. I was lucky to find this thread. I'm going to use Enliven idea. Hopefully the Entlib Team can address this issue in a future release.

P.S.
A work item has been created for this
http://www.codeplex.com/entlib/WorkItem/View.aspx?WorkItemId=10278

Orginal thread
http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=10148
Nov 28, 2007 at 4:29 AM
LoggingExceptionHandler writes to a new file with GUID prefix, when LAB writes to the same flat file, because, the LoggingExceptionHandlerAssembler creates a new LogWriter object using object builder, in its Assemble method.

LogWriter writer = (LogWriter)context.HeadOfChain.BuildUp(context, typeof(LogWriter), null, null);

Using, the Logger objects, LogWriter, will make EHAB to log to the same file (if it is configured so) as the LAB.

LogWriter wirter = Logger.Writer;

Now, if you cannot or donot want to modify EntLib code, you can always extend, a custom LoggingExceptionHandler. I tried creating a typed provider for Exceptionhandler, with the above change, and was able to get it working. To my understanding, using the Logger.Writer from with in the provider shouldnt be a problem, as provider has dependency on EHAB and LAB, and command to add the provider, will add a default LAB, if one is not already present ( just like the logging Exception handler). Not sure, why MS choose to create a new LogWriter using the object builder, when there is one readily available in Logger. Please update me if you think there is some good reasons for it. Or if you think using Logger.Writer would cause other side effects, would like hear your opinion on that as well.


Neo.

P.S: I did test my solutions with sample applications, but not in any productional applicatons. If anyone is interested in my Logging Exception Handler, post back, i will be glad to share it with you.





Nov 28, 2007 at 1:30 PM
Thanks for offering this suggestion. I am not keen on modifying anyone's code unless I absolutely have to to fix their bug. But this is not a bug. Extending the framework is a different matter.

I will consider both suggestions when I revisit the LAB/EHAB. At the moment, I have jumped camp in using Log4Net, which is a lot lighter weight than LAB but it obviously lacks the power and flexibility of LAB. But will do for me for the moment. In a way, it is quite a joy to use - one DLL.

My two main gripes with EHAB are: 1) Can't write the exception into the same log file, 2) Re-throw exception handler seems to demand the original exception to always be embedded into the new exception - something I do not always do from a DAL tier, particularly when crossing tier separation.

Thanks and look forward to see your enhancement.
Jan 9, 2008 at 3:37 PM
This is still an issue - we just hit this problem trying to log exceptions and messages into one rolling file. If you know about any new solutions or works around please help.

Thank you
Greg
Apr 10, 2008 at 10:09 PM
I just wanted to bump this thread to let the development team know that this is still something that people are looking to accomplish. Does anyone from the Patterns & Practices team care to weigh in on the issue? Has anyone else found any solutions/workarounds for this?
Mar 9, 2009 at 11:02 PM
does anyone know if the development team has addressed this issue? I have the exact same problem and would like to know if there is any solutions?
Mar 10, 2009 at 11:18 AM

Hi,

Set the UseDefaultLogger to True of your Logging Handler. In this way you’ll be avoiding two log files.
Mar 11, 2009 at 3:02 AM
The behavior to create guid-named files is defined by .net framework's tracelistener.  If you are not using LoggingHandler, refer to this thread - http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=29703


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 27, 2009 at 3:44 PM

instead of using the Distributor service, do you know if there's a way to use the CacheManager to cache the logentries and then write out to a single file?
Is it possible to just release the lock on the file once Enterprise library has finished logging? I've tried to dispose of the Logger.Writer but still there is a lock on the file and I can't even delete the file when the application is running. I have to stop the application before I could even move, delete, or rename the file.
I can not use Distributor service because we do not want to use MSMQ.

Thanks,


Phuong Nguyen
IT Professional
Colorado Integrated Criminal Justice Information System (CICJIS)
phuong.nguyen@cdps.state.co.us
720.544.2223
720.544.2230 (Fax)


AvanadeSupport <notifications@codeplex.com>

03/10/2009 09:02 PM
Please respond to entlib


To: [email removed]
cc:
Subject: Re: Help: How to log exception to the same file? [entlib:17354]



From: AvanadeSupport

The behavior to create guid-named files is defined by .net framework's tracelistener. If you are not using LoggingHandler, refer to this thread - http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=29703.


Sarah Urmeneta

Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Apr 28, 2009 at 3:00 AM
The Logger.Writer.Dispose() should allow you to modify or delete the file.  I just tried it to make sure and it works and it did.  Regarding the topic on caching the logentries, you need to implement it as there's no built-in support for this.   Just be conscious if performance will be significantly affected since you might be caching a lot.  


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

May 27, 2009 at 12:05 AM

hello,

Thank you for your replies.
When using Logger.Writer.Dispose(), I run into the error "Cannot access a closed file" very often.
Do you know how I can get around this?

Here's the exception details:


Exception type: ObjectDisposedException
Source: mscorlib
Target Site: Void FileNotOpen()
The following is a stack trace that identifies the location where the exception occured

at System.IO.__Error.FileNotOpen()
at System.IO.FileStream.Flush()
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.Stre


Is there a way to check to see if it's already closed before calling the dispose method?

thanks,


Phuong Nguyen
IT Professional
Colorado Integrated Criminal Justice Information System (CICJIS)
phuong.nguyen@cdps.state.co.us
720.544.2223
720.544.2230 (Fax)


AvanadeSupport <notifications@codeplex.com>

04/27/2009 09:00 PM
Please respond to entlib


To: [email removed]
cc:
Subject: Re: Help: How to log exception to the same file? [entlib:17354]



From: AvanadeSupport

The Logger.Writer.Dispose() should allow you to modify or delete the file. I just tried it to make sure and it works and it did. Regarding the topic on caching the logentries, you need to implement it as there's no built-in support for this. Just be conscious if performance will be significantly affected since you might be caching a lot.


Sarah Urmeneta

Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

May 27, 2009 at 8:19 AM

Hi,

After googling I found these http://www.dotnetscraps.com/dotnetscraps/post/FileInUse.aspx . Seems like its possible to check if the file is open before calling the dispose. Now, you would just need the path of the trace listener you are using (ex: Flat File). Maybe you can hardcode the path for testing purpose only, But later you would need to pull the path somewhere. You can read the settings of the logging application and get the file name to check.

            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();

            fileMap.ExeConfigFilename = "configPath";

            Configuration entLibConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);

            FlatFileTraceListenerData data = loggingSettings.TraceListeners.Get("FlatFile TraceListener") as FlatFileTraceListenerData;

            string Filename = data.FileName

            //Do the check passing the fileName

 

Valiant Dudan
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

Aug 10, 2010 at 2:26 PM
Edited Aug 10, 2010 at 2:34 PM

From: AvanadeSupport

The Logger.Writer.Dispose() should allow you to modify or delete the file. I just tried it to make sure and it works and it did. Regarding the topic on caching the logentries, you need to implement it as there's no built-in support for this. Just be conscious if performance will be significantly affected since you might be caching a lot.


Sarah Urmeneta

Global Technology & Solutions
Avanade, Inc.

 

Hi,

Same problem here, the only thing is I dont have the .Dispose in Logger.Writer, is it normal?

 

Thanks,

 

TCW

Aug 10, 2010 at 2:36 PM
TCW wrote:

From: AvanadeSupport

The Logger.Writer.Dispose() should allow you to modify or delete the file. I just tried it to make sure and it works and it did. Regarding the topic on caching the logentries, you need to implement it as there's no built-in support for this. Just be conscious if performance will be significantly affected since you might be caching a lot.


Sarah Urmeneta

Global Technology & Solutions
Avanade, Inc.

 

Hi,

Same problem here, the only thing is I dont have the .Dispose in Logger.Writer, is it normal?

 

Thanks,

 

TCW

 Import Microsoft.Practices.EntLib.Common does the trick.

Jun 25, 2014 at 9:04 PM
So what do you do if the file is in use when trying to call .Dispose? I am doing this in my class destructor. Do I just skip and exit leaving the file open/in use?
Jun 30, 2014 at 12:55 PM
@sbattagl, I'm not sure I follow. I would recommend posting a new question with your specific scenario.

Thanks,

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Jun 30, 2014 at 8:27 PM
Never mind. My bad. I am trying to call the .Dispose method of the FlatFileLog class and was getting an AggregateException/Cannot access a closed file error. I found out I needed to implement a Dispose pattern in my base and derived classes as explained at http://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.110).aspx. My app is no longer throwing the exception when calling the .Dispose method on the FlatFileLog EventListener class. Maybe this post will help someone else.