SimpleFormatter ignoring the java.util.logging.SimpleFormatter.format property
Asked Answered
E

4

2

I'm using java.util.logging on GlassFish 4.

I'm defining my own class to initialize the LogManager by defining the System property: -Djava.util.logging.config.class.

My class loads the logging.properties file, merges it with some other property file and does some custom replacement.

The following is the relevant part of my logging.properties file:

java.util.logging.FileHandler.pattern=C:/Work/server/glassfish/domains/domain1/logs/JMSFileHandler%g.log
java.util.logging.FileHandler.limit=2000000
java.util.logging.FileHandler.count=20
java.util.logging.FileHandler.append=true
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%1$tY:%1$tm:%1$td %1$tH:%1$tM:%1$tS|%4$s: %2$s%n%5$s%n%6$s%n

I'm using the standard FileHandler and configuring it to use the SimpleFormatter as the formatter.

But the java.util.logging.SimpleFormatter.format String is being totally ignored. Instead SimpleFormatter uses its default format.

Where did I go wrong?

Eupatrid answered 27/8, 2014 at 16:15 Comment(0)
E
1

I was assuming that the System Property java.util.logging.config.file is set by GF from the beginning. This is not the case.

After some investigation I realized that the LogManager is initialized two times. In the first time that property doesn't exist, the second time it does.

I was getting an error on the first initialization because I was counting on that property, therefore I didn't initialize the LogManager properly, causing the SimpleFormatter to use the default format.

I fixed this by changing my code and no longer counting on that System property. This solved the issue.

GF still sets the System property java.util.logging.config.file later.

Eupatrid answered 28/8, 2014 at 9:58 Comment(1)
If it was set after it was loaded that would be a problem. You might be able to install a security manager and trace where it is being set.Care
C
2

From the SimpleFormatter docs you have to test for the following conditions:

  1. If this property is not defined or the given format string is illegal, the default format is implementation-specific.
  2. If this property is set in both the logging properties and system properties, the format string specified in the system property will be used.
  3. This property can be defined in the logging properties configuration file.

Here is a sample test case that you can convert and run under GlassFish.

public static void main(String[] args) throws Exception {
    final String format = "%1$tY:%1$tm:%1$td %1$tH:%1$tM:%1$tS|%4$s: %2$s%n%5$s%n%6$s%n";
    final String key = "java.util.logging.SimpleFormatter.format";
    test(format);
    test(System.getProperty(key, format));
    test(LogManager.getLogManager().getProperty(key));
    FileHandler f = new FileHandler();
    System.out.println(f.getFormatter());
    f.close();
}

private static void test(String format) {
    LogRecord record = new LogRecord(Level.INFO, "");
    System.out.println(String.format(format,
                         new java.util.Date(record.getMillis()),
                         record.getSourceClassName(),
                         record.getLoggerName(),
                         record.getLevel().getLocalizedName(),
                         record.getMessage(),
                         String.valueOf(record.getThrown())));
}

You also need to check if GlassFish replaced your SimpleFormatter with the 'com.sun.enterprise.server.logging.UniformLogFormatter'.

private static void findFormatters() {
    final ArrayList<Handler> handlers = new ArrayList<>();
    final LogManager manager = LogManager.getLogManager();
    synchronized (manager) {
        final Enumeration<String> e = manager.getLoggerNames();
        while (e.hasMoreElements()) {
            final Logger l = manager.getLogger(e.nextElement());
            if (l != null) {
                Collections.addAll(handlers, l.getHandlers());
            }
        }
    }

    for (Handler h : handlers) {
        Formatter f = h.getFormatter();
        System.out.println(h.getClass().getName() + "=" + (f == null ? "" : f.getClass().getName()));
    }
}

If you need to check access when the system properties are set you can install a security manager with the -Djava.security.debug=access,stack options to trace when the property is set.

Care answered 27/8, 2014 at 19:8 Comment(4)
> You also need to check if GlassFish replaced your SimpleFormatter with the 'com.sun.enterprise.server.logging.UniformLogFormatter'. No, that is not the caseEupatrid
No System property called "java.util.logging.SimpleFormatter.format"Eupatrid
LogManager property "java.util.logging.SimpleFormatter.format" is exactly the format I specified. Yet the static java.util.logging.SimpleFormatter.format is the default format String and not the one I specified.Eupatrid
SimpleFormatter.format is a static property that is set at Class loading time. Maybe something is using/referencing this class in Code before the LogManager has been loaded?Eupatrid
E
1

I was assuming that the System Property java.util.logging.config.file is set by GF from the beginning. This is not the case.

After some investigation I realized that the LogManager is initialized two times. In the first time that property doesn't exist, the second time it does.

I was getting an error on the first initialization because I was counting on that property, therefore I didn't initialize the LogManager properly, causing the SimpleFormatter to use the default format.

I fixed this by changing my code and no longer counting on that System property. This solved the issue.

GF still sets the System property java.util.logging.config.file later.

Eupatrid answered 28/8, 2014 at 9:58 Comment(1)
If it was set after it was loaded that would be a problem. You might be able to install a security manager and trace where it is being set.Care
K
0

I had a similar problem, but it is fixed. I was running my code from an Ant build.xml, and my java.util.logging.FileHandler.formatter.format property was not being applied from my myLogging.properties file, although other properties were read and applied.

Are you using a JRE version < 1.6.32? Java Bug 55052 indicates that the java.util.logging.FileHandler.formatter.format property is not properly read from the properties file and applied for earlier versions of the JRE.

See: https://issues.apache.org/bugzilla/show_bug.cgi?id=55052

I still compile that project with JDK 1.6.24, but run it with JDK 1.7.0.6, and the formatting is properly read and applied to my logger.

Kissable answered 11/12, 2014 at 18:32 Comment(0)
G
0

As I can see this post is very old, but I had the same problem and I made some discovery regarding this issue.

SimpleFormatter class stores the format property in a static field, so it initialized only once while calling log(…) method. If you call log(…) method before read the configuration, SimpleFormatter class format field is initialized with default values.

The code below works fine:

LogManager.getLogManager().readConfiguration(configurationStream);

Logger.getLogger(“logger name”).info(“message”);

But code below uses a default formatting (ignores the configuration):

Logger.getLogger(“logger name”).info(“message”);

LogManager.getLogManager().readConfiguration(configurationStream);

Logger.getLogger(“logger name”).info(“message”);

Logger.getLogger(“logger name”).info(“message”);
Grecian answered 26/10, 2022 at 11:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.