Pascal Pascal - 5 months ago 33
Java Question

Limiting String length with SimpleFormatter

I'm trying to limit the length of the source parameter in a SimpleFormatter format, to use in Tomcat 8.

I've read the SimpleFormatter doc and the Formatter syntax doc and while I won't pretend I've understood all of the second one, following the argument by a number should limit its length.

Yet it doesn't in my tests: the lines output by

java.util.logging.SimpleFormatter.format = %4$s %n
and

java.util.logging.SimpleFormatter.format =%4$1s %n


are indistinguishable.

Am I missing something?

Answer

I'm trying to limit the length of the source parameter in a SimpleFormatter format, to use in Tomcat 8.

Per the java.util.Formatter JavaDocs:

The format specifiers for general, character, and numeric types have the following syntax:

   %[argument_index$][flags][width][.precision]conversion

The optional width is a positive decimal integer indicating the minimum number of characters to be written to the output.

The optional precision is a non-negative decimal integer usually used to restrict the number of characters.

Which means precision is specified using the dot character. If the minimum is zero then you have to omit it from the pattern. Since you only want the first character of the level then the syntax is %4$.1s. Here is an example test case to build your pattern:

public static void main(String[] args) {
    //This really should be set as a command argument but, it works.
    //System.setProperty("java.util.logging.SimpleFormatter.format", "%4$.7s %n"); //Max of seven chars of level.
    //System.setProperty("java.util.logging.SimpleFormatter.format", "%4$7.7s %n");  //Min and max of seven chars of level (right justified).
    //System.setProperty("java.util.logging.SimpleFormatter.format", "%4$-7.7s %n");  //Min and max of seven chars of level (left justified).
    System.setProperty("java.util.logging.SimpleFormatter.format", "%4$.1s %n");

    LogRecord r = new LogRecord(Level.SEVERE, "Message");
    r.setLoggerName("logger");
    r.setSourceClassName("class");
    r.setSourceMethodName("method");
    System.out.println(new SimpleFormatter().format(r));
}

The JavaDocs also state:

For character, integral, and date/time argument types and the percent and line separator conversions, the precision is not applicable; if a precision is provided, an exception will be thrown.

Instead of 'argument types' the documentation should really say 'argument category'. The 's' and 'S' are considered 'general' and not 'character' in the argument category table. Which is why you can use the dot precision.

Comments