You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2019/06/30 03:45:14 UTC

[logging-log4j2] 01/01: LOG4J2-2644 - Improve performance of getting location info

This is an automated email from the ASF dual-hosted git repository.

rgoers pushed a commit to branch LOG4J2-2644-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit c880137015623c66988faa7c11bda6f22adc66f2
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sat Jun 29 20:44:43 2019 -0700

    LOG4J2-2644 - Improve performance of getting location info
---
 .../apache/logging/log4j/util/StackLocator.java    | 43 +++++++++++++++++++---
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java
index 2cd658f..f221117 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java
+++ b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.util;
 
 import java.util.List;
 import java.util.Stack;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -31,6 +32,11 @@ public class StackLocator {
 
     private final static StackLocator INSTANCE = new StackLocator();
 
+    private final static ThreadLocal<CallerLocator> LOCATOR = new ThreadLocal<CallerLocator>() {
+        public CallerLocator initialValue() {
+            return new CallerLocator();
+        }
+    };
 
     public static StackLocator getInstance() {
         return INSTANCE;
@@ -72,15 +78,40 @@ public class StackLocator {
     }
 
     public StackTraceElement calcLocation(final String fqcnOfLogger) {
-        return stackWalker.walk(
-                s -> s.dropWhile(f -> !f.getClassName().equals(fqcnOfLogger)) // drop the top frames until we reach the logger
-                        .dropWhile(f -> f.getClassName().equals(fqcnOfLogger)) // drop the logger frames
-                        .findFirst())
-                .get()
-                .toStackTraceElement();
+        return walker.walk(s -> s.filter(LOCATOR.get().setFqcn(fqcnOfLogger)).findFirst()).get().toStackTraceElement();
     }
 
     public StackTraceElement getStackTraceElement(final int depth) {
         return stackWalker.walk(s -> s.skip(depth).findFirst()).get().toStackTraceElement();
     }
+
+    static final class CallerLocator implements Predicate<StackWalker.StackFrame> {
+
+        private String fqcn;
+
+        private boolean foundFqcn = false;
+        private boolean foundLogger = false;
+
+        public CallerLocator setFqcn(String fqcn) {
+            this.fqcn = fqcn;
+            this.foundFqcn = false;
+            this.foundLogger = false;
+            return this;
+        }
+
+        @Override
+        public boolean test(StackWalker.StackFrame t) {
+            final String className = t.getClassName();
+            if (!foundLogger) {
+                if (!foundFqcn) {
+                    foundFqcn = className.equals(fqcn);
+                    return false;
+                } else if (!className.equals(fqcn)) {
+                    foundLogger = true;
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
 }