< prev index next >
jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java
Print this page
*** 30,48 ****
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
- import java.time.Clock;
- import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
! import jdk.internal.misc.JavaLangAccess;
! import jdk.internal.misc.SharedSecrets;
/**
* Platform logger provides an API for the JRE components to log
* messages. This enables the runtime components to eliminate the
* static dependency of the logging facility and also defers the
--- 30,46 ----
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
! import java.util.Optional;
! import java.util.function.Predicate;
/**
* Platform logger provides an API for the JRE components to log
* messages. This enables the runtime components to eliminate the
* static dependency of the logging facility and also defers the
*** 537,584 ****
level.name(),
msg,
throwable);
}
! // Returns the caller's class and method's name; best effort
! // if cannot infer, return the logger's name.
! private String getCallerInfo() {
! String sourceClassName = null;
! String sourceMethodName = null;
! JavaLangAccess access = SharedSecrets.getJavaLangAccess();
! Throwable throwable = new Throwable();
! int depth = access.getStackTraceDepth(throwable);
!
! String logClassName = "sun.util.logging.PlatformLogger";
! boolean lookingForLogger = true;
! for (int ix = 0; ix < depth; ix++) {
! // Calling getStackTraceElement directly prevents the VM
! // from paying the cost of building the entire stack frame.
! StackTraceElement frame =
! access.getStackTraceElement(throwable, ix);
! String cname = frame.getClassName();
! if (lookingForLogger) {
! // Skip all frames until we have found the first logger frame.
! if (cname.equals(logClassName)) {
! lookingForLogger = false;
}
! } else {
! if (!cname.equals(logClassName)) {
! // We've found the relevant frame.
! sourceClassName = cname;
! sourceMethodName = frame.getMethodName();
! break;
}
}
}
! if (sourceClassName != null) {
! return sourceClassName + " " + sourceMethodName;
! } else {
! return name;
! }
}
}
/**
* JavaLoggerProxy forwards all the calls to its corresponding
--- 535,594 ----
level.name(),
msg,
throwable);
}
! /*
! * CallerFinder is a stateful predicate.
! */
! static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
! static final StackWalker WALKER = StackWalker.getInstance();
! /**
! * Returns StackTraceElement of the caller's frame.
! * @return StackTraceElement of the caller's frame.
! */
! Optional<StackWalker.StackFrame> get() {
! return WALKER.walk(s -> s.filter(this).findFirst());
}
!
! private boolean lookingForLogger = true;
!
! /**
! * Returns true if we have found the caller's frame, false if the frame
! * must be skipped.
! *
! * @param t The frame info.
! * @return true if we have found the caller's frame, false if the frame
! * must be skipped.
! */
! @Override
! public boolean test(StackWalker.StackFrame t) {
! final String cname = t.getClassName();
! // We should skip all frames until we have found the logger,
! // because these frames could be frames introduced by e.g. custom
! // sub classes of Handler.
! if (lookingForLogger) {
! lookingForLogger = !cname.equals("sun.util.logging.PlatformLogger");
! return false;
}
+ // Once the logger is found - we should skip all frames that
+ // point to packages which contain artifacts that could be
+ // inserted between the logger and its caller. These could be
+ // logger wrappers from j.u.l or sun.util.logging (e.g. the
+ // PlatformLogger or artifacts between the PlatformLogger and
+ // the actual logger) or frames inserted by use of reflection
+ // and/or doPrivileged calls.
+ return !cname.startsWith("java.util.logging.")
+ && !cname.startsWith("sun.util.logging.")
+ && !cname.startsWith("java.security.AccessController");
}
}
! private String getCallerInfo() {
! Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
! return frame.map(f -> f.getClassName() + " " + f.getMethodName()).orElse(name);
}
}
/**
* JavaLoggerProxy forwards all the calls to its corresponding
< prev index next >