1

I have an Spring Boot Web app that needs to use Java Util Logging behind SLF4J. When I don't create a logging.properties file, the Console Logger works just fine, and all INFO messages & above are logged. When I do create a logging.properties file, only FATAL errors are logged. It doesn't matter what the logging.properties file contains - I've tried lots of different configurations - it only logs FATAL errors when this file exists.

Here's the jars I've imported (using Gradle)

    implementation("org.slf4j:slf4j-api")
    implementation("org.slf4j:slf4j-jdk14")

I also had to make sure logback-classic was not imported, because one of my dependencies was trying to pull it in.

configurations.all {
    exclude(group = "ch.qos.logback", module = "logback-classic")
}

Then, here's my logging.properties file. It's located at src/main/resources/logging.properties.

handlers = java.util.logging.ConsoleHandler
.level= ALL
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

This is not the only configuration I've tried to use.

Can anyone spot what I'm doing wrong? Why does it only log FATAL errors?

Mathew Alden
  • 1,458
  • 2
  • 15
  • 34
  • Please don’t gratuitously repeat the tags in the question title, there’s no need for that. – Konrad Rudolph Dec 28 '20 at 22:33
  • I appreciate the criticism, but I still feel that the way you've rewritten my title makes the title more difficult to understand. My questions is about Java Util Logging. If I'm not allowed to say "Java Util Logging" in the title, then the title is no longer relevant to my post. – Mathew Alden Dec 28 '20 at 22:37
  • The information that the question is about Java Util Logging is provided *by the tags*. That’s their purpose. Good titles are concise, and the title of your question — in combination with the tags — is easily understood – Konrad Rudolph Dec 28 '20 at 22:38
  • You're not wrong, but that's just not the way most SO users write questions. If you just look at the Top Questions page, most users include the technology in question in the title. I suspect that most users *expect* the technology in question to be in their title. I was just trying to write a title that's easy for other folks to parse. – Mathew Alden Dec 28 '20 at 22:42
  • Put a breakpoint on a logging line and step into the logger. – tgdavies Dec 28 '20 at 22:47
  • 1
    After stepping through the bowels of Logger.java, I've learned that JUL has configured itself with zero Handlers. I do not know why it has zero Handlers. – Mathew Alden Dec 28 '20 at 23:02
  • Have you tried using `.handlers = java.util.logging.ConsoleHandler` instead of `handlers = java.util.logging.ConsoleHandler`? Depending on the LogManager you might have to [specify both](https://stackoverflow.com/questions/36726431/in-a-java-util-logging-logging-properties-file-whats-the-difference-between-h/36727524#36727524). `handlers` is lazy loaded so you may not see the handlers appear until log records are published. – jmehrens Dec 29 '20 at 05:39
  • @jmehrens I have now tried each; neither is working. Thanks anyway. – Mathew Alden Dec 29 '20 at 15:47

3 Answers3

1

This works for me with your existing logging.properties file.

I think the problem is that java.util.logging doesn't look for a properties resource, just a file (or the default resource).

I can't explain why you saw different behaviour when a logging.properties resource was present.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.LogManager;

public class Example2 {
    public static void main(String... args) throws IOException {
        final InputStream inputStream = Example2.class.getResourceAsStream("/logging.properties");
        LogManager.getLogManager().readConfiguration(inputStream);
        Logger logger = LoggerFactory.getLogger(Example2.class);
        logger.debug("message 0");
        logger.info("message 1");
        logger.error("message 2");
    }
}
tgdavies
  • 10,307
  • 4
  • 35
  • 40
1

Does your java.util.logging.config.file system property point to a readable file?

import java.util.logging.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class Test {

    public static void main(String[] args) throws IOException {
        String file = System.getProperty("java.util.logging.config.file");
        if (file == null) {
            System.out.println("Configuration was not specified");
            return;
        }
        
        System.out.println(file);
        System.out.println(new File(file).getCanonicalPath());
        System.out.println(Files.isReadable(Paths.get(file)));
        System.out.println(Arrays.toString(Logger.getLogger("").getHandlers()));
    }
}

If I run this test program pointing to a file that doesn't exist I get the following:

/home/jmehrens/logging.properties
/home/jmehrens/logging.properties
false
[]

The false in the output shows that the file I specified in the configuration is not readable (because it doesn't exist at the location). The root logger handlers are empty because the log manager is unable to read my logging.properties.

From the terminal you can see the file doesn't exist at that path:

[jmehrens@localhost ~]$ pwd
/home/jmehrens
[jmehrens@localhost ~]$ ls logging.properties
ls: cannot access logging.properties: No such file or directory

There are additional debugging tips you can follow in the related answer.

Your script tells me that my "Configuration was not specified". Where do I specify it in the context of a SpringBoot app build with Gradle?

Can I define System Properties within Spring Boot configuration files? covers setting system properties in Spring Boot. How to give System property to my test via Gradle and -D covers how to pass properties via Gradle.

If that doesn't work for you then you need to specify a PostConstruct method that locates the logging configuration file and configures the LogManager.

jmehrens
  • 10,580
  • 1
  • 38
  • 47
  • Your script tells me that my "Configuration was not specified". Where do I specify it in the context of a SpringBoot app build with Gradle? – Mathew Alden Dec 29 '20 at 17:08
  • @MathewAlden I updated the answer to link to the new topic. – jmehrens Dec 29 '20 at 17:22
  • I appreciate you trying to help with this. I've now set the system property correctly. Now when I run your script, it outputs "logging.properties; C:\Users\mathewalden\Documents\myproject\mysubproject\logging.properties; false; [];". However, this has not fixed the problem unfortunately. As long is this file exists, longs are not written. If the file is deleted, INFO and higher are written but not DEBUG or TRACE. – Mathew Alden Dec 29 '20 at 17:48
  • I've just switched to log4j2. Thanks anyway. – Mathew Alden Dec 29 '20 at 18:39
  • 1
    From the script output the file is not readable. In your original question you indicate that the file is under `src/main/resources` and that is not in the path you specified. You still have the wrong path defined. Check from the command line that the file exists in the resolved canonical path. – jmehrens Dec 29 '20 at 19:35
1

I just switched from JUL to Log4j2, because I understand that documentation better.

Mathew Alden
  • 1,458
  • 2
  • 15
  • 34