KEYCLOAK-16567 Optimize StackUtil class
This commit is contained in:
parent
8e376aef51
commit
f053675e50
1 changed files with 39 additions and 15 deletions
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.common.util;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -43,22 +46,43 @@ 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(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() {
|
||||
|
|
Loading…
Reference in a new issue