--- old/src/share/classes/java/util/logging/Logger.java 2012-12-20 21:36:14.270786509 -0800 +++ new/src/share/classes/java/util/logging/Logger.java 2012-12-20 21:36:14.102786507 -0800 @@ -30,6 +30,8 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.security.*; import java.lang.ref.WeakReference; +import java.util.function.Block; +import java.util.function.Supplier; /** * A Logger object is used to log messages for a specific @@ -96,6 +98,12 @@ * for example a format string "{0} {1}" would format two parameters * as strings. *

+ * Since 1.8, a set of methods alternatively take a "msgSupplier" instead of + * a "msg" argument. This version takes a {@link Supplier}{@code + * } function which is invoked to construct desired log message + * only when the message actually to be logged after checking the effective + * log level thus eliminate unnecessary message construction. + *

* When mapping ResourceBundle names to ResourceBundles, the Logger * will first try to use the Thread's ContextClassLoader. If that * is null it will try the SystemClassLoader instead. As a temporary @@ -543,6 +551,22 @@ log(lr); } + // private support method for logging. + // message and LogRecord are only constucted when it really need to + // be logged + private void doLog(Level level, Supplier msgSupplier, + Block staging) { + if (level.intValue() < levelValue || levelValue == offValue) { + return; + } + LogRecord lr = new LogRecord(level, msgSupplier.get()); + if (staging != null ) { + staging.accept(lr); + } + // Set logger name and resource bundle + doLog(lr); + } + //================================================================ // Start of convenience methods WITHOUT className and methodName @@ -567,6 +591,23 @@ } /** + * Log a message, which is only to be constructed if the logging level + * is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the given message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param level One of the message level identifiers, e.g., SEVERE + * @param msgSupplier A function, which when called, produces the + * desired log message + */ + public void log(Level level, Supplier msgSupplier) { + doLog(level, msgSupplier, null); + } + + /** * Log a message, with one object parameter. *

* If the logger is currently enabled for the given message @@ -632,6 +673,29 @@ doLog(lr); } + /** + * Log a in-time constructed message, with associated Throwable information. + *

+ * If the logger is currently enabled for the given message level then the + * message is constructed by invoking the provided supplier function. The + * message and the given {@link Throwable} are then stored in a {@link + * LogRecord} which is forwarded to all registered output handlers. + *

+ * Note that the thrown argument is stored in the LogRecord thrown + * property, rather than the LogRecord parameters property. Thus is it + * processed specially by output Formatters and is not treated + * as a formatting parameter to the LogRecord message property. + *

+ * @param level One of the message level identifiers, e.g., SEVERE + * @param msgSupplier A function, which when called, produces the + * desired log message + * @param thrown Throwable associated with log message. + * @since 1.8 + */ + public void logEx(Level level, Supplier msgSupplier, Throwable thrown) { + doLog(level, msgSupplier, lr -> lr.setThrown(thrown)); + } + //================================================================ // Start of convenience methods WITH className and methodName //================================================================ @@ -660,6 +724,30 @@ } /** + * Log a in-time constructed message, specifying source class and method, + * with no arguments. + *

+ * If the logger is currently enabled for the given message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param level One of the message level identifiers, e.g., SEVERE + * @param sourceClass name of class that issued the logging request + * @param sourceMethod name of method that issued the logging request + * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void logp(Level level, String sourceClass, String sourceMethod, + Supplier msgSupplier) { + doLog(level, msgSupplier, lr -> { + lr.setSourceClassName(sourceClass); + lr.setSourceMethodName(sourceMethod); + }); + } + + /** * Log a message, specifying source class and method, * with a single object parameter to the log message. *

@@ -732,7 +820,7 @@ * @param thrown Throwable associated with log message. */ public void logp(Level level, String sourceClass, String sourceMethod, - String msg, Throwable thrown) { + String msg, Throwable thrown) { if (level.intValue() < levelValue || levelValue == offValue) { return; } @@ -743,6 +831,37 @@ doLog(lr); } + /** + * Log a in-time constructed message, specifying source class and method, + * with associated Throwable information. + *

+ * If the logger is currently enabled for the given message level then the + * message is constructed by invoking the provided supplier function. The + * message and the given {@link Throwable} are then stored in a {@link + * LogRecord} which is forwarded to all registered output handlers. + *

+ * Note that the thrown argument is stored in the LogRecord thrown + * property, rather than the LogRecord parameters property. Thus is it + * processed specially by output Formatters and is not treated + * as a formatting parameter to the LogRecord message property. + *

+ * @param level One of the message level identifiers, e.g., SEVERE + * @param sourceClass name of class that issued the logging request + * @param sourceMethod name of method that issued the logging request + * @param msgSupplier A function, which when called, produces the + * desired log message + * @param thrown Throwable associated with log message. + * @since 1.8 + */ + public void logpEx(Level level, String sourceClass, String sourceMethod, + Supplier msgSupplier, Throwable thrown) { + doLog(level, msgSupplier, lr -> { + lr.setSourceClassName(sourceClass); + lr.setSourceMethodName(sourceMethod); + lr.setThrown(thrown); + }); + } + //========================================================================= // Start of convenience methods WITH className, methodName and bundle name. @@ -1149,6 +1268,130 @@ log(Level.FINEST, msg); } + //======================================================================= + // Start of simple convenience methods using level names as method names + // and use Supplier + //======================================================================= + + /** + * Log a SEVERE message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the SEVERE message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void severe(Supplier msgSupplier) { + log(Level.SEVERE, msgSupplier); + } + + /** + * Log a WARNING message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the WARNING message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void warning(Supplier msgSupplier) { + log(Level.WARNING, msgSupplier); + } + + /** + * Log a INFO message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the INFO message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void info(Supplier msgSupplier) { + log(Level.INFO, msgSupplier); + } + + /** + * Log a CONFIG message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the CONFIG message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void config(Supplier msgSupplier) { + log(Level.CONFIG, msgSupplier); + } + + /** + * Log a FINE message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the FINE message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void fine(Supplier msgSupplier) { + log(Level.FINE, msgSupplier); + } + + /** + * Log a FINER message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the FINER message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void finer(Supplier msgSupplier) { + log(Level.FINER, msgSupplier); + } + + /** + * Log a FINEST message, which is only to be constructed if the logging + * level is such that the message will actually be logged. + *

+ * If the logger is currently enabled for the FINEST message + * level then the message is constructed by invoking the provided + * supplier function and forwarded to all the registered output + * Handler objects. + *

+ * @param msgSupplier A function, which when called, produces the + * desired log message + * @since 1.8 + */ + public void finest(Supplier msgSupplier) { + log(Level.FINEST, msgSupplier); + } + //================================================================ // End of convenience methods //================================================================