SourceForge.net Logo

Welcome to pformat ...

(small but good!)

Pformat icon

pformat stands for printf-format and is Java library that comes with a small but powerful formatter for the java.util.logging framework.

Standard formatter of java.util.logging framework are fixed in their behaviour and do not offer much control to user without any programming. The formatter provided by this library uses the printf formatting style of the Java API in order to format log records.

1 Usage

To use the printf-formatter download the archive from here and extract it. Simply add the formatter to the handlers in the logging properties file after that. An example is given below

handlers=java.util.logging.FileHandler
.level=FINEST
java.util.logging.FileHandler.formatter=de.softquadrat.logging.PrintfFormatter
java.util.logging.FileHandler.pattern=log%g.log
java.util.logging.FileHandler.count=5
de.softquadrat.logging.PrintfFormatter.stripLineBreaks=false
de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te%2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s
de.softquadrat.logging.PrintfFormatter.appendStackTrace=true

In this example only one file handler is used, that will create 5 log files at maximum. The file handler will use the PrintfFormatter writing the log records according to the format string given. The resulting output might look like

 SEVERE|2011.06.13 21:39:47.973|1307993987973|    10|Severe message
WARNING|2011.06.13 21:39:48.782|1307993988782| 10|Warning message
INFO|2011.06.13 21:39:48.783|1307993988783| 10|Info message
FINE|2011.06.13 21:39:48.783|1307993988783| 10|Fine message
FINER|2011.06.13 21:39:48.784|1307993988784| 10|Finer message
FINEST|2011.06.13 21:39:48.785|1307993988785| 10|Finest message
SEVERE|2011.06.13 21:39:48.785|1307993988785| 10|Test exception
java.lang.Exception: Test exception
at de.softquadrat.logging.Test.test(Test.java:16)
at de.softquadrat.logging.Test.main(Test.java:27)

The library must be added to the classpath of a Java application to make use of its printf-style formatter.

1.1 Standalone Java applications

For a standalone Java application simply add pformat.jar file to the classpath, create or edit a logging properties file and start the application with the logging config file system property. For example

Windows syntax: java -Djava-util.logging.config.file=logging.properties -cp pformat.jar;<list of your jars> MyMainClass
Unix syntax: java -Djava-util.logging.config.file=logging.properties -cp pformat.jar:<list of your jars> MyMainClass

where <list of your jars> is a list of your application jar files.

1.2 Tomcat

´For Tomcat java.util.logging is usually the standard logging implementation. In order to use the formatter edit the logging properties under

    $TOMCAT_HOME/conf/logging.properties

Often ConsoleHandler and JuliFileHandler are used, to which the PrintfFormatter can be applied (note the bold lines):

handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.
1catalina.org.apache.juli.FileHandler.formatter=de.softquadrat.logging.PrintfFormatter
1catalina.de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

2localhost.org.apache.juli.FileHandler.level = FINE
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.
2localhost.org.apache.juli.FileHandler.formatter=de.softquadrat.logging.PrintfFormatter
2localhost.de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

3manager.org.apache.juli.FileHandler.level = FINE
3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
3manager.org.apache.juli.FileHandler.prefix = manager.
3manager.org.apache.juli.FileHandler.formatter=de.softquadrat.logging.PrintfFormatter
3manager.de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

4host-manager.org.apache.juli.FileHandler.level = FINE
4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
4host-manager.org.apache.juli.FileHandler.formatter=de.softquadrat.logging.PrintfFormatter
4host-managerde.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.formatter=de.softquadrat.logging.PrintfFormatter
de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

To add the library to the classpath create an  environment file and add a corresponding entry with the classpath

Windows Unix
$TOMCAT_HOME/bin/setenv.bat
set CLASSPATH=pformat.jar
$TOMCAT_HOME/bin/setenv.sh
CLASSPATH=pformat.jar

If there is already an environment file with a classpath entry extend this and add pformat.jar. Restart Tomcat after that and the formatter should come into place.

2 Details

The fine tuning of the format and the options of the printf formatter are given in this section. Find below explanations and examples for the formatter properties

2.1 Format

The log message format is given by the property de.softquadrat.logging.PrintfFormatter.format. It defines the string conversion of the log entries using java formatter string syntax, for details see here. Easily spoken formatting is done for each log record and its parameter as follows:

A format instruction consists of a starting '%' followed by a parameter number and a format string (for instance %1$7s advices the formatter to take parameter 1 (1$) and formats it as a string with 7 characters (7s)). Find below a list of available log record parameters, their index number and their datatypes 

  1. log level - String
  2. time stamp in milli seconds - long
  3. thread id - int
  4. source class name - String
  5. source method name - String
  6. logger name - String
  7. sequence number - long
  8. throwable (if an exception or error is logged) - Throwable
  9. log parameters (converted from array to string) - String
  10. log message - String

Some examples of formats with their corresponding output are given below:

Format: de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s
Description: Small format with level, time stamp, thread id, thread name and log message.
Output:

 SEVERE|2011.06.14 12:33:00.607|    10|Severe message
WARNING|2011.06.14 12:33:01.038| 10|Warning message
INFO|2011.06.14 12:33:01.038| 10|Info message
FINE|2011.06.14 12:33:01.039| 10|Fine message
FINER|2011.06.14 12:33:01.039| 10|Finer message
FINEST|2011.06.14 12:33:01.040| 10|Finest message
SEVERE|2011.06.14 12:33:01.040| 10|Test exception
java.lang.Exception: Test exception
at de.softquadrat.logging.Test.test(Test.java:16)
at de.softquadrat.logging.Test.main(Test.java:27)

Format: de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%2$13d|%3$6d|%4$s#%5$s|%6$s|%7$d|%8$s|%9$s|%10$s
Description: Full format with all possible parameters.
Output:

 SEVERE|2011.06.14 14:35:21.728|1308054921728|    10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|0|null|null|Severe message
WARNING|2011.06.14 14:35:22.121|1308054922121| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|1|null|null|Warning message
INFO|2011.06.14 14:35:22.122|1308054922122| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|2|null|null|Info message
FINE|2011.06.14 14:35:22.123|1308054922123| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|3|null|null|Fine message
FINER|2011.06.14 14:35:22.124|1308054922124| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|4|null|null|Finer message
FINEST|2011.06.14 14:35:22.124|1308054922124| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|5|null|null|Finest message
SEVERE|2011.06.14 14:35:22.125|1308054922125| 10|de.softquadrat.logging.Test#test|de.softquadrat.logging.Test|6|java.lang.Exception: Test exception|null|Test exception
java.lang.Exception: Test exception
at de.softquadrat.logging.Test.test(Test.java:16)
at de.softquadrat.logging.Test.main(Test.java:27)

If no format is provided in the logging properties file the default given below is used

de.softquadrat.logging.PrintfFormatter.format=%1$7.7s|%2$tY.%2$tm.%2$te %2$tH:%2$tM:%2$tS.%2$tL|%3$6d|%10$s

2.2 Linebreak Handling

The boolean property

de.softquadrat.logging.PrintfFormatter.stripLineBreaks

if set to true will escape all line terminators in the log message thus keeping the log message in one line (defaults to false). Example

de.softquadrat.logging.PrintfFormatter.stripLineBreaks=false

   INFO|2011.06.14 14:50:14.885|    10|Long message
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.

de.softquadrat.logging.PrintfFormatter.stripLineBreaks=true

   INFO|2011.06.14 14:55:45.661|    10|Long message\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt\nut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi\nut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore\neu fugiat nulla pariatur.

Note the '\n' in the line instead of the line terminator.

2.3 Stacktrace Handling

The boolean property

de.softquadrat.logging.PrintfFormatter.appendStackTrace

is used to control logging of exception stacktraces. If set to 'true' full stacktraces will be appended to the log, if set to 'false' they will be suppressed. The default value of this property is 'true' thus logging all stacktraces.

2.4 Formatting using Regular Expressions

There are three properties available to control searching and replacing using regular expressions in order to change the resulting format of the log messages:

Several regular expressions can be defined with numbering starting from 1 (replace # by the number) like

Evaluation of regular expressions will contine until the first missing pattern is encountered.

The property regexpPattern.# can be used to define a regular search expression. For every match of the pattern against the log message a replacement will be done using the string defined by property regexpReplacement.#. The search process can be fine controlled using the (optional) property regexpFlags.#.

The regular expression pattern syntax can be found in the Java API here. The replacement string can use groups from the pattern by group numbers or group names. Have a look to the section called "Groups and capturing" at the same location in the Java API.

The flags regexpFlags allows control over the regular expression process. These flags and there values can also be found in the Java API as well.

Examples:
1. Remove leading zeros from all numbers

Example: result1=012345, result2=00009747.033, result3=000.0 -> result1=12345, result2=9747.033, result3=0.0

2. Anonymize all urls in log messages starting with "http://www" and ending with a space and replace them by 'http://www.*':

Example: The url http://www.softquadrat.de/datasqill is cool. -> The url http://www.* is cool.

3. Replace all '.' by ',' and all '$' by '€' (text replacement without regular expression syntax in literal mode)

Example: 3124.24 $ -> 3124,24 €

3 License

The library is distributed as public domain, feel free to use it, modify it, sell it, whatever you like.

4 Source

The Source code can be found inside the Jar archive together with the compiled classes.

5 FAQ

5.1 Question

I have set the config file system property programmatically but it is not used. Instead the Java default logging properties is read and all output is going to console. What might be wrong?
Answer
This is often caused by the problem, that an attempt is made to set the property after (!) setup of java.util.logging has been completed. For example in the class below

package de.softquadrat.logging;

import java.util.logging.Logger;

public class Main {
  private static final Logger LOGGER = Logger.getLogger(Main.class.getName());

  public static void main(String[] args) {
    System.setProperty("java.util.logging.config.file""test/logging.properties");
    LOGGER.severe("Severe message");
  }
}
Java2html

the main method will be reached after the java.util.logging framework has been initialized. The reason lies in the constant LOGGER, that is instantiated when the class is loaded and before (!) main is called. In absence of the system property for the logging config file in that moment the default config file is read from jre/lib directory instead. Set the logging config file property from command line with "-Djava.util.logging.config.file=..." to solve this problem.

5.2 Question

Why are there no thread names available to be logged?

Answer
This is a restriction of the java.util.logging framework. The thread id available in the log records is unique id generated inside the logging framework that has no relations to the thread ids inside the JVM. By this there is no way to map the thread ids to thread name.

5.3 Question

What is the performance impact of the formatter and did you do any performance optimization.

Answer
Currently we did not investigate on performance figures and no optimization was done. If you think you can provide valuable experience please let us know and joins us.


Version 0.7, 23.06.2016, SoftQuadrat GmbH
SourceForge.net Logo