8153666: Optimize Formatter.formatMessage
This patch brings a small optimization that removes needless synchronization in Formatter.formatMessage. It also fixes the code that decides whether to call MessageFormat, and brings a small clarification to the API documentation on the conditions when that will happen. Reviewed-by: rriggs, martin
This commit is contained in:
parent
c5b3a7c036
commit
4c69f47805
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -101,23 +101,23 @@ public abstract class Formatter {
|
||||
* formatting.
|
||||
* <ul>
|
||||
* <li>If there are no parameters, no formatter is used.
|
||||
* <li>Otherwise, if the string contains "{0" then
|
||||
* java.text.MessageFormat is used to format the string.
|
||||
* <li>Otherwise, if the string contains "{{@literal<digit>}"
|
||||
* where {@literal <digit>} is in [0-9],
|
||||
* java.text.MessageFormat is used to format the string.
|
||||
* <li>Otherwise no formatting is performed.
|
||||
* </ul>
|
||||
*
|
||||
* @param record the log record containing the raw message
|
||||
* @return a localized and formatted message
|
||||
*/
|
||||
public synchronized String formatMessage(LogRecord record) {
|
||||
public String formatMessage(LogRecord record) {
|
||||
String format = record.getMessage();
|
||||
java.util.ResourceBundle catalog = record.getResourceBundle();
|
||||
if (catalog != null) {
|
||||
try {
|
||||
format = catalog.getString(record.getMessage());
|
||||
format = catalog.getString(format);
|
||||
} catch (java.util.MissingResourceException ex) {
|
||||
// Drop through. Use record message as format
|
||||
format = record.getMessage();
|
||||
}
|
||||
}
|
||||
// Do the formatting.
|
||||
@ -130,11 +130,16 @@ public abstract class Formatter {
|
||||
// Is it a java.text style format?
|
||||
// Ideally we could match with
|
||||
// Pattern.compile("\\{\\d").matcher(format).find())
|
||||
// However the cost is 14% higher, so we cheaply check for
|
||||
// 1 of the first 4 parameters
|
||||
if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 ||
|
||||
format.indexOf("{2") >=0|| format.indexOf("{3") >=0) {
|
||||
return java.text.MessageFormat.format(format, parameters);
|
||||
// However the cost is 14% higher, so we cheaply use indexOf
|
||||
// and charAt to look for that pattern.
|
||||
int index = -1;
|
||||
int fence = format.length() - 1;
|
||||
while ((index = format.indexOf('{', index+1)) > -1) {
|
||||
if (index >= fence) break;
|
||||
char digit = format.charAt(index+1);
|
||||
if (digit >= '0' & digit <= '9') {
|
||||
return java.text.MessageFormat.format(format, parameters);
|
||||
}
|
||||
}
|
||||
return format;
|
||||
|
||||
|
@ -153,7 +153,7 @@ public class SimpleFormatter extends Formatter {
|
||||
* @return a formatted log record
|
||||
*/
|
||||
@Override
|
||||
public synchronized String format(LogRecord record) {
|
||||
public String format(LogRecord record) {
|
||||
ZonedDateTime zdt = ZonedDateTime.ofInstant(
|
||||
record.getInstant(), ZoneId.systemDefault());
|
||||
String source;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6381464
|
||||
* @bug 6381464 8153666
|
||||
* @summary Test the custom simple formatter output
|
||||
*
|
||||
* @run main/othervm SimpleFormatterFormat
|
||||
@ -60,13 +60,19 @@ public class SimpleFormatterFormat {
|
||||
"test.foo",
|
||||
"test.foo",
|
||||
"test.bar",
|
||||
"test.bar",
|
||||
"test.bar",
|
||||
"test.bar"
|
||||
};
|
||||
private static String[] messages = new String[] {
|
||||
"severe hello world",
|
||||
"warning lost connection",
|
||||
"info welcome",
|
||||
"warning exception thrown",
|
||||
"warning beware of traps",
|
||||
"warning { {ok7} }",
|
||||
// keep exception logging as last test case to avoid having
|
||||
// to skip the exception stack trace in the output
|
||||
"warning exception thrown"
|
||||
};
|
||||
private static void writeLogRecords(PrintStream logps) throws Exception {
|
||||
try {
|
||||
@ -79,8 +85,11 @@ public class SimpleFormatterFormat {
|
||||
Logger bar = Logger.getLogger("test.bar");
|
||||
bar.finest("Dummy message");
|
||||
bar.info(messages[2]);
|
||||
bar.log(Level.WARNING, messages[3], new IllegalArgumentException());
|
||||
bar.log(Level.WARNING, "{0}", new Object[] { messages[3] });
|
||||
bar.log(Level.WARNING, "warning '{' '{'{7}} }", new Object[] {"ok", "ok1", "ok2", "ok3", "ok4", "ok5", "ok6", "ok7", "ok8", "ok9", "ok10"});
|
||||
|
||||
// Keep this one last - as it also prints the exception stack trace...
|
||||
bar.log(Level.WARNING, messages[messages.length-1], new IllegalArgumentException());
|
||||
} finally {
|
||||
logps.flush();
|
||||
logps.close();
|
||||
@ -108,7 +117,7 @@ public class SimpleFormatterFormat {
|
||||
|
||||
Matcher m = p.matcher(line);
|
||||
if (!m.matches()) {
|
||||
throw new RuntimeException("Unexpected output format");
|
||||
throw new RuntimeException("Unexpected output format: " + line);
|
||||
}
|
||||
if (m.groupCount() != 3) {
|
||||
throw new RuntimeException("Unexpected group count = " +
|
||||
|
Loading…
Reference in New Issue
Block a user