cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From raj...@apache.org
Subject [1/4] git commit: updated refs/heads/master to 22c78ed
Date Tue, 01 Sep 2015 09:08:49 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/master 1bbd23e66 -> 22c78ede3


Proposal for an improved CglibThrowableRenderer

Apache license
Shame on me...

Fix test to pass on travis build


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/89bac529
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/89bac529
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/89bac529

Branch: refs/heads/master
Commit: 89bac529cc03952b0cbf5eefe3c464ca55d0d40a
Parents: cd7218e
Author: weingartner <rafaelweingartner@gmail.com>
Authored: Sat Aug 29 20:35:13 2015 -0300
Committer: weingartner <rafaelweingartner@gmail.com>
Committed: Sat Aug 29 21:49:56 2015 -0300

----------------------------------------------------------------------
 .../cloud/utils/log/CglibThrowableRenderer.java | 86 ++++++++++----------
 .../utils/log/CglibThrowableRendererTest.java   | 82 +++++++++++++++++++
 2 files changed, 124 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/89bac529/utils/src/main/java/com/cloud/utils/log/CglibThrowableRenderer.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/log/CglibThrowableRenderer.java b/utils/src/main/java/com/cloud/utils/log/CglibThrowableRenderer.java
index b102dc4..9178c80 100644
--- a/utils/src/main/java/com/cloud/utils/log/CglibThrowableRenderer.java
+++ b/utils/src/main/java/com/cloud/utils/log/CglibThrowableRenderer.java
@@ -19,16 +19,17 @@
 
 package com.cloud.utils.log;
 
-import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.spi.ThrowableRenderer;
 
 /**
- * This renderer removes all the Cglib generated methods from the call
+ * This renderer removes all the CGLib generated methods from the call
  *
- * Unfortunately, I had to copy out the EnhancedThrowableRenderer from
- * the apach libraries because EnhancedThrowableRenderer is a final class.
+ * Unfortunately, I had to copy out there-write the EnhancedThrowableRenderer from
+ * the Apache libraries because EnhancedThrowableRenderer is a final class.
  * simply override doRender. Not sure what the developers are thinking there
  * making it final.
  *
@@ -37,48 +38,45 @@ import org.apache.log4j.spi.ThrowableRenderer;
  *
  */
 public class CglibThrowableRenderer implements ThrowableRenderer {
-    /**
-     * Construct new instance.
-     */
-    public CglibThrowableRenderer() {
-        super();
-    }
 
+    private final static int MAX_NUMBER_OF_STACK_TRACES_ON_LOG_FOR_CAUSE = 3;
     @Override
-    public String[] doRender(final Throwable th) {
-        try {
-            ArrayList<String> lines = new ArrayList<String>();
-            Throwable throwable = th;
-            lines.add(throwable.toString());
-            int start = 0;
-            do {
-                StackTraceElement[] elements = throwable.getStackTrace();
-                for (int i = 0; i < elements.length - start; i++) {
-                    StackTraceElement element = elements[i];
-                    String filename = element.getFileName();
-                    String method = element.getMethodName();
-                    if ((filename != null && filename.equals("<generated>"))
|| (method != null && method.equals("invokeSuper"))) {
-                        continue;
-                    }
-                    lines.add("\tat " + element.toString());
-                }
-                if (start != 0) {
-                    lines.add("\t... " + start + " more");
-                }
-                throwable = throwable.getCause();
-                if (throwable != null) {
-                    lines.add("Caused by: " + throwable.toString());
-                    start = elements.length - 1;
-                }
-            } while (throwable != null);
-            return lines.toArray(new String[lines.size()]);
-        } catch (Exception ex) {
-            PrintWriter pw = new PrintWriter(System.err);
-            ex.printStackTrace(pw);
-            pw = new PrintWriter(System.out);
-            ex.printStackTrace(pw);
-            ex.printStackTrace();
-            return null;
+    public String[] doRender(Throwable th) {
+        List<String> lines = new ArrayList<String>();
+        lines.add(th.toString());
+        addStackTraceToList(th, lines, 0);
+        do {
+            th = th.getCause();
+            if (th != null) {
+                lines.add("Caused by: " + th.toString());
+                addStackTraceToList(th, lines, MAX_NUMBER_OF_STACK_TRACES_ON_LOG_FOR_CAUSE);
+            }
+        } while (th != null);
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    /**
+     * This method adds the stack traces retrieved from {@link Throwable#getStackTrace()}
+     * The maxNumberOfStack attribute indicates the number of stacks that will be added,
+     * if that value is 0, then all of the stack traces will be added, otherwise the stack
traces will be limited to that number
+     * @param th
+     * @param lines
+     * @param maxNumberOfStack
+     */
+    private void addStackTraceToList(Throwable th, List<String> lines, int maxNumberOfStack)
{
+        StackTraceElement[] elements = th.getStackTrace();
+        if (maxNumberOfStack == 0 || maxNumberOfStack > elements.length) {
+            maxNumberOfStack = elements.length;
+        }
+        for (int i = 0; i < maxNumberOfStack; i++) {
+            StackTraceElement element = elements[i];
+            if (StringUtils.contains(element.getClassName(), "net.sf.cglib.proxy")) {
+                continue;
+            }
+            lines.add("\tat " + element.toString());
+        }
+        if (maxNumberOfStack < elements.length) {
+            lines.add("\t... " + (elements.length - maxNumberOfStack) + " more");
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/89bac529/utils/src/test/java/com/cloud/utils/log/CglibThrowableRendererTest.java
----------------------------------------------------------------------
diff --git a/utils/src/test/java/com/cloud/utils/log/CglibThrowableRendererTest.java b/utils/src/test/java/com/cloud/utils/log/CglibThrowableRendererTest.java
new file mode 100644
index 0000000..def65c4
--- /dev/null
+++ b/utils/src/test/java/com/cloud/utils/log/CglibThrowableRendererTest.java
@@ -0,0 +1,82 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils.log;
+
+import java.lang.reflect.Method;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+public class CglibThrowableRendererTest {
+
+    CglibThrowableRenderer cglibThrowableRenderer = new CglibThrowableRenderer();
+
+    @Test
+    public void testDoRendere() {
+        SampleClass sampleClass = (SampleClass)Enhancer.create(SampleClass.class, new MyInvocationHandler());
+        try {
+            sampleClass.theFirstMethodThatCapturesAnException();
+        } catch (Exception e) {
+            String[] exceptions = cglibThrowableRenderer.doRender(e);
+            dumpExceptions(exceptions);
+            Assert.assertEquals(40, exceptions.length);
+        }
+    }
+
+    private void dumpExceptions(String[] exceptions) {
+        System.out.println("Dumping exception for debugging purposes");
+        for (String s : exceptions) {
+            System.out.println(s);
+        }
+    }
+
+    static class SampleClass {
+        public void theFirstMethodThatCapturesAnException() {
+            try {
+                methodThatCapturesAndThrowsException();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private void methodThatCapturesAndThrowsException() throws Exception {
+            try {
+                methodThatThrowsAnError();
+            } catch (Error e) {
+                throw new Exception("Throws an exception", e);
+            }
+        }
+
+        private void methodThatThrowsAnError() {
+            throw new Error("Exception to test the CglibThrowableRenderer.");
+        }
+    }
+
+    static class MyInvocationHandler implements MethodInterceptor {
+        @Override
+        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
+            return proxy.invoke(new SampleClass(), args);
+        }
+    }
+}


Mime
View raw message