Torsten

I've recently been working on the subject of exception management and 
logging in the context of the Merlin container.  Just like Cocoon, 
Merlin tends to spit out very log stack traces that make the process of 
end-user recognition of the real problem unnecessarily difficult.  I've 
recently put in place some changes to Merlin that solve this and I 
thought it may be helpful to provide an update on this.

Firstly, there is a problem concerning the reporting of exceptions under 
JDK 1.4 and later - the log file get filled with masive stack dumps 
where the causal exception get dumped in full and the causal exceptions 
causal exception get dumped in full, etc. etc.  This results in masssive 
duplication of exeception information.  

The solution I have in place is:

  (a) coding policy

      * when an error occurs, optionally log the message, NOT the 
exception,
        rethrow the exception (typically inside another cascading 
exeception)

      * this ensures that you get a ERROR or WARNING log entry in the log
        category under which the error/warning occurs, and the causal
        exception is propergated up the chain of control

  (b) considate error reporting somewhere high up in the application
      where it makes sence to dumpt the exception to the log file

  (c) generate a considated exception report

      * for all of the exceptions in the chain, generate a string buffer
        the contains the exception messages

      * dump the stack trace of last exception in the chain into the buffer

      * take the buffer result and enter it into the log

In the Merlin case - errors reporting now makes complete sence.

An example of the error log for an exception I'm throwing is include 
below just to demonstrate the final error reporting.  The actual 
exception message is prepared using the packException method in the 
org.apache.excalibur.merlin.ExceptionHelper class in the 
excalibur/assembly project (which can easily be copied/plundered for 
Cocoon requirements if it makes sence).

Cheers, Steve.


Code example:
-------------

    try
    {
        // do top level stuff
    {
    catch( Throwable e )
    {
        ExceptionHelper.packException( "kernel startup failure", e );
    }

Result:
-------

[ERROR  ] (root.kernel): Message: kernel startup failure
===================================================================
Exception: org.apache.excalibur.merlin.container.ContainerException: 
Unexpected error during container execution.
Cause: org.apache.excalibur.merlin.resource.LifecycleException: 
Component named "/root/complex" failed to pass through the 
initialization stage.
Cause: org.apache.avalon.framework.service.ServiceException: Service 
resolution failure for role: simple
Cause: org.apache.excalibur.merlin.resource.ResourceException: 
Unexpected exception while resolving the service from 
service:/root/simple#17984263 for the role: simple
Cause: org.apache.excalibur.merlin.resource.LifecycleException: 
Component named "/root/simple#17984263" failed to pass through the 
startup stage.
Cause: java.lang.RuntimeException: Steve's demo exception just for Cocoon
===================================================================
java.lang.RuntimeException: Steve's demo exception just for Cocoon
        at org.apache.excalibur.playground.SimpleComponent.start(Unknown 
Source)
        at 
org.apache.avalon.framework.container.ContainerUtil.start(ContainerUtil.java:251)
        at 
org.apache.excalibur.merlin.resource.LifecycleHelper.startup(Unknown Source)
        at 
org.apache.excalibur.merlin.resource.AbstractLifestyleHandler.createInstance(Unknown 
Source)
        at 
org.apache.excalibur.merlin.resource.SingletonLifestyleHandler.get(Unknown 
Source)
        at 
org.apache.excalibur.merlin.resource.DefaultResource.access(Unknown Source)
        at 
org.apache.excalibur.merlin.resource.DefaultManager.get(Unknown Source)
        at 
org.apache.excalibur.merlin.resource.DefaultServiceManager.lookup(Unknown 
Source)
        at 
org.apache.excalibur.playground.ComplexComponent.initialize(Unknown Source)
        at 
org.apache.avalon.framework.container.ContainerUtil.initialize(ContainerUtil.java:235)
        at 
org.apache.excalibur.merlin.resource.LifecycleHelper.startup(Unknown Source)
        at 
org.apache.excalibur.merlin.resource.AbstractLifestyleHandler.createInstance(Unknown 
Source)
        at 
org.apache.excalibur.merlin.resource.SingletonLifestyleHandler.get(Unknown 
Source)
        at 
org.apache.excalibur.merlin.resource.DefaultResource.access(Unknown Source)
        at 
org.apache.excalibur.merlin.assembly.ContainerManager.start(Unknown Source)
        at 
org.apache.excalibur.merlin.assembly.ContainerManager.start(Unknown Source)
        at 
org.apache.excalibur.merlin.container.DefaultContainer.start(Unknown Source)
        at 
org.apache.excalibur.merlin.container.ContainerResource.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:536)
===================================================================


[EMAIL PROTECTED] wrote:

><snip/>
>
>  
>
>>Is this buffer size only related to development ? I don't think so. 
>>    
>>
>
>Well, of course not necessarily... but at least I wouldn't want this burden 
>that will definitly mean a drop of performance and worse scaleability for our 
>deployed system.
>
>The question is: for what type of user do we create those nice error messages?
>
>Actually from our clients I can tell - they don't have the slightest idea what 
>a specific exception could mean. And I bet same goes for most of the web users 
>out there. If there is an error they will call anyway and I have to look into 
>the logs. (Of course a nice page "Sorry, unavailable" is much nicer - but we 
>need to see what is the price to pay.
>
>But where it can definitly help to speed things up is at the development 
>stage... No more: "wait I need to turn this category on - do it again" or "wait 
>I need only 10.000 more lines to go through"
>
>But of course people may see this differently... ;)
>
>  
>
>>Error-handlers can also be used in production to handle 
>>exceptional-but-foreseen conditions (access denied, unavailable 
>>resource, etc). So the buffer size isn't only a matter of running mode.
>>    
>>
>
>Well, of course... but I would model such conditions within the sitemap and 
>don't use Exceptions ;) ...if they are foreseen...
>
>  
>
>>However, running mode is a great idea, which could be used for many more 
>>things than buffer size :
>>- central configuration for automatic reload of XSPs and sitemap in dev 
>>mode (and no reload in production mode),
>>- display the Cocoon "blue screen of death" to the browser in dev mode 
>>and a gentle "system currently unavailable" in production mode,
>>- other ideas ?
>>    
>>
>
>Hey, I didn't thought about all that... sounds cool:)
>
>- provide different logkit configurations?
>--
>Torsten
>
>-------------------------------------------------
>This mail sent through IMP: http://horde.org/imp/
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: [EMAIL PROTECTED]
>For additional commands, email: [EMAIL PROTECTED]
>
>  
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:[EMAIL PROTECTED]
http://www.osm.net




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to