14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.logger; 27 28 import java.io.PrintStream; 29 import java.io.PrintWriter; 30 import java.io.StringWriter; 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 import java.time.ZonedDateTime; 34 import java.util.ResourceBundle; 35 import java.util.function.Function; 36 import java.lang.System.Logger; 37 import java.lang.System.Logger.Level; 38 import java.util.function.Supplier; 39 import jdk.internal.misc.JavaLangAccess; 40 import jdk.internal.misc.SharedSecrets; 41 import sun.util.logging.PlatformLogger; 42 import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; 43 44 /** 45 * A simple console logger to emulate the behavior of JUL loggers when 46 * in the default configuration. SimpleConsoleLoggers are also used when 47 * JUL is not present and no DefaultLoggerFinder is installed. 48 */ 49 public class SimpleConsoleLogger extends LoggerConfiguration 50 implements Logger, PlatformLogger.Bridge, PlatformLogger.ConfigurableBridge { 51 52 static final PlatformLogger.Level DEFAULT_LEVEL = PlatformLogger.Level.INFO; 53 54 final String name; 55 volatile PlatformLogger.Level level; 56 final boolean usePlatformLevel; 57 SimpleConsoleLogger(String name, boolean usePlatformLevel) { 58 this.name = name; 59 this.usePlatformLevel = usePlatformLevel; 60 } 152 public void setPlatformLevel(PlatformLogger.Level newLevel) { 153 level = newLevel; 154 } 155 156 @Override 157 public LoggerConfiguration getLoggerConfiguration() { 158 return this; 159 } 160 161 /** 162 * Default platform logging support - output messages to System.err - 163 * equivalent to ConsoleHandler with SimpleFormatter. 164 */ 165 static PrintStream outputStream() { 166 return System.err; 167 } 168 169 // Returns the caller's class and method's name; best effort 170 // if cannot infer, return the logger's name. 171 private String getCallerInfo() { 172 String sourceClassName = null; 173 String sourceMethodName = null; 174 175 JavaLangAccess access = SharedSecrets.getJavaLangAccess(); 176 Throwable throwable = new Throwable(); 177 int depth = access.getStackTraceDepth(throwable); 178 179 String logClassName = "sun.util.logging.PlatformLogger"; 180 String simpleLoggerClassName = "jdk.internal.logger.SimpleConsoleLogger"; 181 boolean lookingForLogger = true; 182 for (int ix = 0; ix < depth; ix++) { 183 // Calling getStackTraceElement directly prevents the VM 184 // from paying the cost of building the entire stack frame. 185 final StackTraceElement frame = 186 access.getStackTraceElement(throwable, ix); 187 final String cname = frame.getClassName(); 188 if (lookingForLogger) { 189 // Skip all frames until we have found the first logger frame. 190 if (cname.equals(logClassName) || cname.equals(simpleLoggerClassName)) { 191 lookingForLogger = false; 192 } 193 } else { 194 if (skipLoggingFrame(cname)) continue; 195 if (!cname.equals(logClassName) && !cname.equals(simpleLoggerClassName)) { 196 // We've found the relevant frame. 197 sourceClassName = cname; 198 sourceMethodName = frame.getMethodName(); 199 break; 200 } 201 } 202 } 203 204 if (sourceClassName != null) { 205 return sourceClassName + " " + sourceMethodName; 206 } else { 207 return name; 208 } 209 } 210 211 private String getCallerInfo(String sourceClassName, String sourceMethodName) { 212 if (sourceClassName == null) return name; 213 if (sourceMethodName == null) return sourceClassName; 214 return sourceClassName + " " + sourceMethodName; 215 } 216 217 private String toString(Throwable thrown) { 218 String throwable = ""; 219 if (thrown != null) { 220 StringWriter sw = new StringWriter(); 221 PrintWriter pw = new PrintWriter(sw); 222 pw.println(); 223 thrown.printStackTrace(pw); 224 pw.close(); 225 throwable = sw.toString(); 226 } 227 return throwable; | 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.logger; 27 28 import java.io.PrintStream; 29 import java.io.PrintWriter; 30 import java.io.StringWriter; 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 import java.time.ZonedDateTime; 34 import java.util.Optional; 35 import java.util.ResourceBundle; 36 import java.util.function.Function; 37 import java.lang.System.Logger; 38 import java.util.function.Predicate; 39 import java.util.function.Supplier; 40 import sun.util.logging.PlatformLogger; 41 import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; 42 43 /** 44 * A simple console logger to emulate the behavior of JUL loggers when 45 * in the default configuration. SimpleConsoleLoggers are also used when 46 * JUL is not present and no DefaultLoggerFinder is installed. 47 */ 48 public class SimpleConsoleLogger extends LoggerConfiguration 49 implements Logger, PlatformLogger.Bridge, PlatformLogger.ConfigurableBridge { 50 51 static final PlatformLogger.Level DEFAULT_LEVEL = PlatformLogger.Level.INFO; 52 53 final String name; 54 volatile PlatformLogger.Level level; 55 final boolean usePlatformLevel; 56 SimpleConsoleLogger(String name, boolean usePlatformLevel) { 57 this.name = name; 58 this.usePlatformLevel = usePlatformLevel; 59 } 151 public void setPlatformLevel(PlatformLogger.Level newLevel) { 152 level = newLevel; 153 } 154 155 @Override 156 public LoggerConfiguration getLoggerConfiguration() { 157 return this; 158 } 159 160 /** 161 * Default platform logging support - output messages to System.err - 162 * equivalent to ConsoleHandler with SimpleFormatter. 163 */ 164 static PrintStream outputStream() { 165 return System.err; 166 } 167 168 // Returns the caller's class and method's name; best effort 169 // if cannot infer, return the logger's name. 170 private String getCallerInfo() { 171 Optional<StackWalker.StackFrame> frame = new CallerFinder().get(); 172 if (frame.isPresent()) { 173 return frame.get().getClassName() + " " + frame.get().getMethodName(); 174 } else { 175 return name; 176 } 177 } 178 179 /* 180 * CallerFinder is a stateful predicate. 181 */ 182 static final class CallerFinder implements Predicate<StackWalker.StackFrame> { 183 static final StackWalker WALKER = StackWalker.getInstance(); 184 185 /** 186 * Returns StackFrame of the caller's frame. 187 * @return StackFrame of the caller's frame. 188 */ 189 Optional<StackWalker.StackFrame> get() { 190 return WALKER.walk((s) -> s.filter(this).findFirst()); 191 } 192 193 private boolean lookingForLogger = true; 194 /** 195 * Returns true if we have found the caller's frame, false if the frame 196 * must be skipped. 197 * 198 * @param t The frame info. 199 * @return true if we have found the caller's frame, false if the frame 200 * must be skipped. 201 */ 202 @Override 203 public boolean test(StackWalker.StackFrame t) { 204 final String cname = t.getClassName(); 205 // We should skip all frames until we have found the logger, 206 // because these frames could be frames introduced by e.g. custom 207 // sub classes of Handler. 208 if (lookingForLogger) { 209 // Skip all frames until we have found the first logger frame. 210 lookingForLogger = !isLoggerImplFrame(cname); 211 return false; 212 } 213 // We've found the relevant frame. 214 return !skipLoggingFrame(cname) && !isLoggerImplFrame(cname); 215 } 216 217 private boolean isLoggerImplFrame(String cname) { 218 return (cname.equals("sun.util.logging.PlatformLogger") || 219 cname.equals("jdk.internal.logger.SimpleConsoleLogger")); 220 } 221 } 222 223 private String getCallerInfo(String sourceClassName, String sourceMethodName) { 224 if (sourceClassName == null) return name; 225 if (sourceMethodName == null) return sourceClassName; 226 return sourceClassName + " " + sourceMethodName; 227 } 228 229 private String toString(Throwable thrown) { 230 String throwable = ""; 231 if (thrown != null) { 232 StringWriter sw = new StringWriter(); 233 PrintWriter pw = new PrintWriter(sw); 234 pw.println(); 235 thrown.printStackTrace(pw); 236 pw.close(); 237 throwable = sw.toString(); 238 } 239 return throwable; |