I  tried this, since the changes are small enough, and it works.  Here are
the patches for review.

Shash

----- Original Message -----
From: "Shash Chatterjee" <[EMAIL PROTECTED]>
To: "Avalon Developers List" <[EMAIL PROTECTED]>
Sent: Saturday, February 01, 2003 8:49 AM
Subject: LogKit and Excalibur Logger


Hi!

Since new releases are being discussed, I thought I'd bring this up.  There
is a known issue with the "method" formatter in LogKit's
ExtendedPatterFormatter.  The method shown is always the "caller" of
Logger.class, which when used with a facade such as Excalibur Logger is
*not* the user method, but always LogKitLogger.  A while back, Peter Donald
suggested a workaround, which works great.  The workaround is to modify
Excalibur Logger's FormatterFactory to support a custom formatter type, and
then to implement that custom formatter with a modified version of
ExtendedPatterFormatter that passes in, for instance, LogKitLogger.class
instead of Logkit.class when calling StackIntrospector.getCallerMethod(...).

The one issue with this approach is we (Keel) have to carry a modified
Logkit class, make sure it is ahead in the classpath from the rest of
Avalon, etc. etc.

I'd like to propose a backwards-compatible fix. If this sounds like an
acceptable idea, I'll go ahead and test/submit a patch.  Here goes:

LogKit changes:
- Create an ExtendedPatternFormatter constructor that takes an offset to the
stack depth.  In other words, this would specify looking for a class that is
"offset" levels away from Logger.class on the stack.
- Create a StackIntrospector.getCallerClass(Class, offset)
- Modify ExtendedPatternFormatter to get the caller-class of Logger.class
with an offset.  If new constructor mentioned above is not used, offset is 0
and behaves like it does now.
- Then use that to pass to StackIntrospector.getCallerMethod(...).

Excalibur Logger changes:
- Modify the "extended" type handling in FormatterFactory to call the new
constructor above, with offset +1.

Let me know if this is acceptable or not, before I delve into it.

Thanks,
Shash
Index: FormatterFactory.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-avalon-excalibur/logger/src/java/org/apache/avalon/excalibur/logger/factory/FormatterFactory.java,v
retrieving revision 1.2
diff -u -r1.2 FormatterFactory.java
--- FormatterFactory.java       7 Aug 2002 13:37:00 -0000       1.2
+++ FormatterFactory.java       1 Feb 2003 16:38:21 -0000
@@ -82,7 +82,12 @@
 
         if( "extended".equals( type ) )
         {
-            return new ExtendedPatternFormatter( format );
+               //Normally ExtendPatternFormatter would look for callers 
+               //of Logger.class.  But when Excalibur Logger provides a 
+               //facade, the user class/method is actually one-level depper.
+               //We therefore create the pattern-formatter with an 
+               //additional depth-offset of 1,
+            return new ExtendedPatternFormatter( format, 1 );
         }
 
         if( "raw".equals( type ) )
Index: StackIntrospector.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-avalon-logkit/src/java/org/apache/log/util/StackIntrospector.java,v
retrieving revision 1.6
diff -u -r1.6 StackIntrospector.java
--- StackIntrospector.java      20 May 2002 10:12:50 -0000      1.6
+++ StackIntrospector.java      1 Feb 2003 16:40:24 -0000
@@ -82,21 +82,36 @@
     public static final Class getCallerClass( final Class clazz )
         throws SecurityException
     {
-        final Class[] stack = getCallStack().get();
+               return getCallerClass(clazz, 0);
+    }
 
-        // Traverse the call stack in reverse order until we find clazz
-        for( int i = stack.length - 1; i >= 0; i-- )
-        {
-            if( clazz.isAssignableFrom( stack[ i ] ) )
-            {
-                // Found : the caller is the previous stack element
-                return stack[ i + 1 ];
-            }
-        }
 
-        //Unable to locate class in call stack
-        return null;
-    }
+       /**
+        * Find the caller of the passed in Class.
+        * May return null if caller not found on execution stack
+        *
+        * @param clazz the Class to search for on stack to find caller of
+        * @param stackDepthOffset Offset call-stack depth to find caller
+        * @return the Class of object that called parrameter class
+        * @exception SecurityException if an existing SecurityManager disallows 
+construction
+        *            of another SecurityManager and thus blocks method results
+        */
+       public static Class getCallerClass(final Class clazz, int stackDepthOffset) {
+               final Class[] stack = getCallStack().get();
+               
+               // Traverse the call stack in reverse order until we find clazz
+               for( int i = stack.length - 1; i >= 0; i-- )
+               {
+                   if( clazz.isAssignableFrom( stack[ i ] ) )
+                   {
+                       // Found : the caller is the previous stack element
+                       return stack[ i + 1 + stackDepthOffset];
+                   }
+               }
+               
+               //Unable to locate class in call stack
+               return null;
+       }
 
     /**
      * Get the method path name for the method from which the LogEvent was
Index: ExtendedPatternFormatter.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-avalon-logkit/src/java/org/apache/log/format/ExtendedPatternFormatter.java,v
retrieving revision 1.6
diff -u -r1.6 ExtendedPatternFormatter.java
--- ExtendedPatternFormatter.java       1 Oct 2002 00:00:35 -0000       1.6
+++ ExtendedPatternFormatter.java       1 Feb 2003 16:40:42 -0000
@@ -34,12 +34,20 @@
 
     private static final String TYPE_METHOD_STR = "method";
     private static final String TYPE_THREAD_STR = "thread";
+    
+    private int m_callStackOffset = 0;
 
     public ExtendedPatternFormatter( final String format )
     {
         super( format );
     }
 
+       public ExtendedPatternFormatter( final String format, final int 
+callStackOffset )
+       {
+               super( format );
+               m_callStackOffset = callStackOffset;
+       }
+
     /**
      * Retrieve the type-id for a particular string.
      *
@@ -100,7 +108,15 @@
             }
         }
 
-        final String result = StackIntrospector.getCallerMethod( Logger.class );
+               //Determine callee of user's class.  If offset is 0, we need to find
+               // Logger.class.  If offset is 1, We need to find caller of 
+Logger.class, etc.
+               final Class clazz = StackIntrospector.getCallerClass( Logger.class, 
+m_callStackOffset - 1);
+               if (null == clazz)
+               {
+                       return "UnknownMethod";
+               }
+               
+        final String result = StackIntrospector.getCallerMethod( clazz );
         if( null == result )
         {
             return "UnknownMethod";

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

Reply via email to