Skip to content

Commit

Permalink
KEYCLOAK-16567 Optimize StackUtil class
Browse files Browse the repository at this point in the history
  • Loading branch information
hmlnarik committed Dec 10, 2020
1 parent 8e376ae commit f053675
Showing 1 changed file with 39 additions and 15 deletions.
54 changes: 39 additions & 15 deletions common/src/main/java/org/keycloak/common/util/StackUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.keycloak.common.util;

import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import org.jboss.logging.Logger;

Expand All @@ -11,6 +12,8 @@ public class StackUtil {

private static final Logger LOG = Logger.getLogger("org.keycloak.STACK_TRACE");

private static final ConcurrentHashMap<String, Object> STACK_TRACE_OBJECTS = new ConcurrentHashMap<>();

/**
* Returns string representation of the stack trace of the current call
* without the call to the {@code getShortStackTrace} itself, and ignoring
Expand All @@ -24,11 +27,11 @@ public class StackUtil {
* @return If the logger {@code org.keycloak.STACK_TRACE} is set to trace
* level, then returns stack trace, else returns empty {@link StringBuilder}
*/
public static StringBuilder getShortStackTrace() {
public static Object getShortStackTrace() {
return getShortStackTrace("\n ");
}

private static final Pattern IGNORED = Pattern.compile("^sun\\.|java\\.lang\\.reflect\\.");
private static final Pattern IGNORED = Pattern.compile("sun\\.|java\\.(lang|util|stream)\\.|org\\.jboss\\.logging.");
private static final StringBuilder EMPTY = new StringBuilder(0);

/**
Expand All @@ -43,22 +46,43 @@ public static StringBuilder getShortStackTrace() {
* @return If the logger {@code org.keycloak.STACK_TRACE} is set to trace
* level, then returns stack trace, else returns empty {@link StringBuilder}
*/
public static StringBuilder getShortStackTrace(String prefix) {
public static Object getShortStackTrace(final String prefix) {
if (! isShortStackTraceEnabled()) return EMPTY;

StringBuilder sb = new StringBuilder();
StackTraceElement[] stackTrace = (new Throwable()).getStackTrace();
for (int endIndex = 2; endIndex < stackTrace.length; endIndex++) {
StackTraceElement st = stackTrace[endIndex];
if (IGNORED.matcher(st.getClassName()).find()) {
continue;
}
if (st.getClassName().startsWith("org.jboss.resteasy")) {
break;
}
sb.append(prefix).append(st);
Object res = STACK_TRACE_OBJECTS.get(prefix);
if (res == null) {
res = stackTraceObject(prefix);
// Do not synchronize. We don't care if the objects in the map get overridden, they are in the end the same.
STACK_TRACE_OBJECTS.put(prefix, res);
}
return sb;
return res;
}

private static Object stackTraceObject(final String prefix) {
return new Object() {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
StackTraceElement[] stackTrace = (new Throwable()).getStackTrace();
boolean stackTraceStarted = false;
for (int endIndex = 0; endIndex < stackTrace.length; endIndex++) {
StackTraceElement st = stackTrace[endIndex];
if (! stackTraceStarted) {
stackTraceStarted = (getClass().getName().equals(st.getClassName()));
endIndex++;
continue;
}
if (IGNORED.matcher(st.getClassName()).find()) {
continue;
}
if (st.getClassName().startsWith("org.jboss.resteasy")) {
break;
}
sb.append(prefix).append(st);
}
return sb.toString();
}
};
}

public static boolean isShortStackTraceEnabled() {
Expand Down

0 comments on commit f053675

Please sign in to comment.