下面列出了怎么用java.lang.System.Logger的API类实例代码及写法,或者点击链接到github查看源代码。
static Logger getLogger(LoggerFinder provider, String name, Module caller) {
Logger logger;
try {
logger = Logger.class.cast(lazyGetLogger.invoke(null, name, caller));
} catch (Throwable x) {
Throwable t = (x instanceof InvocationTargetException) ?
((InvocationTargetException)x).getTargetException() : x;
if (t instanceof RuntimeException) {
throw (RuntimeException)t;
} else if (t instanceof Exception) {
throw new RuntimeException(t);
} else {
throw (Error)t;
}
}
// The method above does not throw exception...
// call the provider here to verify that an exception would have
// been thrown by the provider.
if (logger != null && caller == Thread.class.getModule()) {
Logger log = provider.getLogger(name, caller);
}
return logger;
}
private void log(Logger logger) {
assert platformLevel == null && level != null;
//new Exception("logging delayed message").printStackTrace();
if (msgSupplier != null) {
if (thrown != null) {
logger.log(level, msgSupplier, thrown);
} else {
logger.log(level, msgSupplier);
}
} else {
// BootstrapLoggers are never localized so we can safely
// use the method that takes a ResourceBundle parameter
// even when that resource bundle is null.
if (thrown != null) {
logger.log(level, bundle, msg, thrown);
} else {
logger.log(level, bundle, msg, params);
}
}
}
static Logger getLogger(LazyLoggerAccessor accessor) {
if (!BootstrapLogger.isBooted()) {
return new BootstrapLogger(accessor);
} else {
if (useSurrogateLoggers()) {
// JUL is the default backend, there is no custom configuration,
// LogManager has not been used.
synchronized(BootstrapLogger.class) {
if (useSurrogateLoggers()) {
return createSurrogateLogger(accessor);
}
}
}
// Already booted. Return the real logger.
return accessor.createLogger();
}
}
synchronized Logger get(Function<String, Logger> loggerSupplier, final String name) {
Reference<? extends Logger> ref = loggers.get(name);
Logger w = ref == null ? null : ref.get();
if (w == null) {
w = loggerSupplier.apply(name);
loggers.put(name, new WeakReference<>(w, queue));
}
// Remove stale mapping...
Collection<Reference<Logger>> values = null;
while ((ref = queue.poll()) != null) {
if (values == null) values = loggers.values();
values.remove(ref);
}
return w;
}
/**
* Returns a (possibly lazy) Logger suitable for system classes.
* Whether the returned logger is lazy or not depend on the result
* returned by {@link BootstrapLogger#useLazyLoggers()}.
*
* @param name the logger name
* @param module the module on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance.
*/
public static final Logger getLazyLogger(String name, Module module) {
// BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if:
// - the VM is not yet booted
// - or, the backend is JUL and there is no configuration
// - or, the backend is a custom backend, as we don't know what
// that is going to load...
// So if for instance the VM is booted and we use JUL with a custom
// configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) {
return new JdkLazyLogger(name, module);
} else {
// Directly invoke the LoggerFinder.
return getLoggerFromFinder(name, module);
}
}
@Override
public Logger getLogger(String name, Module caller) {
// We should check the permission to obey the API contract, but
// what happens if we don't?
// This is the main difference compared with what we test in
// java/lang/System/LoggerFinder/BaseLoggerFinderTest
SecurityManager sm = System.getSecurityManager();
if (sm != null && doChecks) {
sm.checkPermission(SimplePolicy.LOGGERFINDER_PERMISSION);
}
final boolean before = allowAll.get().getAndSet(true);
final ClassLoader callerLoader;
try {
callerLoader = caller.getClassLoader();
} finally {
allowAll.get().set(before);
}
if (callerLoader == null) {
return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
} else {
return user.computeIfAbsent(name, (n) -> new LoggerImpl(n));
}
}
/**
* Returns a (possibly lazy) Logger suitable for system classes.
* Whether the returned logger is lazy or not depend on the result
* returned by {@link BootstrapLogger#useLazyLoggers()}.
*
* @param name the logger name
* @param module the module on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance.
*/
public static final Logger getLazyLogger(String name, Module module) {
// BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if:
// - the VM is not yet booted
// - or, the backend is JUL and there is no configuration
// - or, the backend is a custom backend, as we don't know what
// that is going to load...
// So if for instance the VM is booted and we use JUL with a custom
// configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) {
return new JdkLazyLogger(name, module);
} else {
// Directly invoke the LoggerFinder.
return getLoggerFromFinder(name, module);
}
}
public static void test(LoggerFinder provider, boolean hasRequiredPermissions) {
ResourceBundle loggerBundle = ResourceBundle.getBundle(MyLoggerBundle.class.getName());
final Map<Logger, String> loggerDescMap = new HashMap<>();
System.Logger sysLogger = accessSystemLogger.getLogger("foo");
loggerDescMap.put(sysLogger, "accessSystemLogger.getLogger(\"foo\")");
System.Logger localizedSysLogger = accessSystemLogger.getLogger("fox", loggerBundle);
loggerDescMap.put(localizedSysLogger, "accessSystemLogger.getLogger(\"fox\", loggerBundle)");
System.Logger appLogger = System.getLogger("bar");
loggerDescMap.put(appLogger,"System.getLogger(\"bar\")");
System.Logger localizedAppLogger = System.getLogger("baz", loggerBundle);
loggerDescMap.put(localizedAppLogger,"System.getLogger(\"baz\", loggerBundle)");
testLogger(provider, loggerDescMap, "foo", null, sysLogger);
testLogger(provider, loggerDescMap, "foo", loggerBundle, localizedSysLogger);
testLogger(provider, loggerDescMap, "foo", null, appLogger);
testLogger(provider, loggerDescMap, "foo", loggerBundle, localizedAppLogger);
}
@Override
public void log(Level level, String string, Throwable thrwbl) {
try {
invoke(System.Logger.class.getMethod(
"log", Level.class, String.class, Throwable.class),
level, string, thrwbl);
} catch (NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
static PlatformLogger.Bridge convert(Logger logger) {
boolean old = allowAccess.get().get();
allowAccess.get().set(true);
try {
return PlatformLogger.Bridge.convert(logger);
} finally {
allowAccess.get().set(old);
}
}
@Override
public void log(Level level, String string) {
try {
invoke(System.Logger.class.getMethod(
"log", Level.class, String.class),
level, string);
} catch (NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
@Override
public void log(Level level, ResourceBundle bundle, String format, Object... params) {
if (checkBootstrapping()) {
push(LogEvent.valueOf(this, level, bundle, format, params));
} else {
final Logger spi = holder.wrapped();
spi.log(level, bundle, format, params);
}
}
static Logger getLogger(String name, Module caller) {
boolean old = allowAll.get().get();
allowAccess.get().set(true);
try {
return jdk.internal.logger.LazyLoggers.getLogger(name, caller);
} finally {
allowAccess.get().set(old);
}
}
@Override
public void log(Level level, String format, Object... params) {
if (checkBootstrapping()) {
push(LogEvent.valueOf(this, level, null, format, params));
} else {
final Logger spi = holder.wrapped();
spi.log(level, format, params);
}
}
void testGetLogger(String desc, String name, Module mod, Class<? extends Throwable> thrown) {
try {
LoggerFinder finder = System.LoggerFinder.getLoggerFinder();
Logger logger = finder.getLogger(name, mod);
if (thrown != null) {
throw new AssertionError("Exception " + thrown.getName()
+ " not thrown for "
+ "LoggerFinder.getLogger"
+ " with " + desc);
}
// Make sure we don't fail if tests are run in parallel
synchronized(RecordStream.LOCK) {
LOG_STREAM.startRecording();
try {
logger.log(Level.INFO, "{0} with {1}: PASSED",
"LoggerFinder.getLogger",
desc);
} finally {
byte[] logged = LOG_STREAM.stopRecording();
check(logged, "testGetLogger", desc, null,
"LoggerFinder.getLogger");
}
}
} catch (Throwable x) {
if (thrown != null && thrown.isInstance(x)) {
System.out.printf("Got expected exception for %s with %s: %s\n",
"LoggerFinder.getLogger", desc, String.valueOf(x));
} else throw x;
}
}
@Override
public void log(Level level, String msg) {
if (checkBootstrapping()) {
push(LogEvent.valueOf(this, level, null, msg, (Object[])null));
} else {
final Logger spi = holder.wrapped();
spi.log(level, msg);
}
}
@Override
public final Logger getLogger(String name, Module module) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(module, "module");
checkPermission();
return demandLoggerFor(name, module);
}
private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories,
Module module, Void unused) {
this.name = name;
this.factories = factories;
this.moduleRef = new WeakReference<>(module);
}
private static void testLogger(String loggerMode, String loggerClassName,
String underlyingLoggerClassName) {
String name = "test.boot";
Logger logger = getLogger(name);
printLogger(logger);
final Module lm = logger.getClass().getModule();
final ClassLoader loggerCL = lm.getClassLoader();
if (loggerMode.equals("system")) {
assertTrue(lm.isNamed());
assertTrue(loggerCL == null);
} else if(loggerMode.equals("unnamed")) {
assertTrue(!lm.isNamed());
assertTrue(loggerCL != null);
} else {
throw new RuntimeException("wrong parameter");
}
assertTrue(loggerClassName.equals(logger.getClass().getName()));
if (underlyingLoggerClassName != null) {
String loggerName = logger.getName();
if (underlyingLoggerClassName.equals(
"sun.util.logging.internal.LoggingProviderImpl$JULWrapper")) {
assertTrue(loggerName.equals(name));
} else {
assertTrue(loggerName.equals(underlyingLoggerClassName));
}
}
}
/**
* Replace 'w' by the real SPI logger and flush the log messages pending
* in the temporary 'bootstrap' Logger. Called by BootstrapLogger when
* this accessor's bootstrap logger is accessed and BootstrapLogger
* notices that the VM is no longer booting.
* @param bootstrap This accessor's bootstrap logger (usually this is 'w').
*/
Logger getConcreteLogger(BootstrapLogger bootstrap) {
assert VM.isBooted();
synchronized(this) {
// another thread may have already invoked flush()
if (this.w == bootstrap) {
this.w = null; this.p = null;
}
}
return this.wrapped();
}
Logger createLogger() {
final Module module = moduleRef.get();
if (module == null) {
throw new IllegalStateException("The module for which this logger"
+ " was created has been garbage collected");
}
return this.factories.loggerSupplier.apply(name, module);
}
@Override
public void log(Level level, ResourceBundle rb, String string, Throwable thrwbl) {
try {
invoke(System.Logger.class.getMethod(
"log", Level.class, ResourceBundle.class, String.class, Throwable.class),
level, rb, string, thrwbl);
} catch (NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
/**
* Gets a logger from the LoggerFinder. Creates the actual concrete
* logger.
* @param name name of the logger
* @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder.
*/
static Logger getLoggerFromFinder(String name, Module module) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return accessLoggerFinder().getLogger(name, module);
} else {
return AccessController.doPrivileged((PrivilegedAction<Logger>)
() -> {return accessLoggerFinder().getLogger(name, module);},
null, LOGGERFINDER_PERMISSION);
}
}
@Override
public Logger getLogger(String name, Module caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader();
ClassLoader callerLoader = AccessController.doPrivileged(pa);
if (callerLoader == null) {
return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
} else {
return user.computeIfAbsent(name, (n) -> new LoggerImpl(n));
}
}
/**
* Invoke the serialization filter if non-null.
* If the filter rejects or an exception is thrown, throws InvalidClassException.
*
* @param clazz the class; may be null
* @param arrayLength the array length requested; use {@code -1} if not creating an array
* @throws InvalidClassException if it rejected by the filter or
* a {@link RuntimeException} is thrown
*/
private void filterCheck(Class<?> clazz, int arrayLength)
throws InvalidClassException {
if (serialFilter != null) {
RuntimeException ex = null;
ObjectInputFilter.Status status;
try {
status = serialFilter.checkInput(new FilterValues(clazz, arrayLength,
totalObjectRefs, depth, bin.getBytesRead()));
} catch (RuntimeException e) {
// Preventive interception of an exception to log
status = ObjectInputFilter.Status.REJECTED;
ex = e;
}
if (Logging.filterLogger != null) {
// Debug logging of filter checks that fail; Tracing for those that succeed
Logging.filterLogger.log(status == null || status == ObjectInputFilter.Status.REJECTED
? Logger.Level.DEBUG
: Logger.Level.TRACE,
"ObjectInputFilter {0}: {1}, array length: {2}, nRefs: {3}, depth: {4}, bytes: {5}, ex: {6}",
status, clazz, arrayLength, totalObjectRefs, depth, bin.getBytesRead(),
Objects.toString(ex, "n/a"));
}
if (status == null ||
status == ObjectInputFilter.Status.REJECTED) {
InvalidClassException ice = new InvalidClassException("filter status: " + status);
ice.initCause(ex);
throw ice;
}
}
}
static boolean isFilteredFrame(StackFrame st) {
// skip logging/logger infrastructure
if (System.Logger.class.isAssignableFrom(st.getDeclaringClass())) {
return true;
}
// fast escape path: all the prefixes below start with 's' or 'j' and
// have more than 12 characters.
final String cname = st.getClassName();
char c = cname.length() < 12 ? 0 : cname.charAt(0);
if (c == 's') {
// skip internal machinery classes
if (cname.startsWith("sun.util.logging.")) return true;
if (cname.startsWith("sun.rmi.runtime.Log")) return true;
} else if (c == 'j') {
// Message delayed at Bootstrap: no need to go further up.
if (cname.startsWith("jdk.internal.logger.BootstrapLogger$LogEvent")) return false;
// skip public machinery classes
if (cname.startsWith("jdk.internal.logger.")) return true;
if (cname.startsWith("java.util.logging.")) return true;
if (cname.startsWith("java.lang.invoke.MethodHandle")) return true;
if (cname.startsWith("java.security.AccessController")) return true;
}
// check additional prefixes if any are specified.
if (skips.length > 0) {
for (int i=0; i<skips.length; i++) {
if (!skips[i].isEmpty() && cname.startsWith(skips[i])) {
return true;
}
}
}
return false;
}
static void setLevel(java.util.logging.Logger sink, java.util.logging.Level loggerLevel) {
boolean before = allowAll.get().get();
try {
allowAll.get().set(true);
sink.setLevel(loggerLevel);
} finally {
allowAll.get().set(before);
}
}
@Test
public void testLogWithCallingClass() throws Exception {
final Logger log = System.getLogger("Test.CallerClass");
log.log(Logger.Level.INFO, "Calling from LoggerTest");
final List<String> messages = stringAppender.getMessages();
assertThat(messages, hasSize(1));
final String message = messages.get(0);
assertEquals(Log4jSystemLoggerTest.class.getName(), message);
}
@Override
public void log(Level level, ResourceBundle bundle, String format, Object... params) {
if (checkBootstrapping()) {
push(LogEvent.valueOf(this, level, bundle, format, params));
} else {
final Logger spi = holder.wrapped();
spi.log(level, bundle, format, params);
}
}
void testGetLocalizedLogger(String desc, String name, ResourceBundle bundle,
Module mod, Class<? extends Throwable> thrown) {
try {
LoggerFinder finder = System.LoggerFinder.getLoggerFinder();
Logger logger = finder.getLocalizedLogger(name, bundle, mod);
if (thrown != null) {
throw new AssertionError("Exception " + thrown.getName()
+ " not thrown for "
+ "LoggerFinder.getLocalizedLogger"
+ " with " + desc);
}
// Make sure we don't fail if tests are run in parallel
synchronized(RecordStream.LOCK) {
LOG_STREAM.startRecording();
try {
logger.log(Level.INFO, "{0} with {1}: PASSED",
"LoggerFinder.getLocalizedLogger",
desc);
} finally {
byte[] logged = LOG_STREAM.stopRecording();
check(logged, "testGetLocalizedLogger", desc, bundle,
"LoggerFinder.getLocalizedLogger");
}
}
} catch (Throwable x) {
if (thrown != null && thrown.isInstance(x)) {
System.out.printf("Got expected exception for %s with %s: %s\n",
"LoggerFinder.getLocalizedLogger", desc, String.valueOf(x));
} else throw x;
}
}