Good examples using java.util.logging
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
java.util.logging, usually shortened to JUL, is Java's built-in logging framework. It is not the most fashionable logging API in modern Java stacks, but it is still widely used in JDK code, smaller applications, and environments where keeping dependencies minimal matters.
Good JUL examples are not just about calling logger.info(...). They show how to choose loggers, levels, handlers, and message patterns in a way that stays maintainable.
A Clean Basic Logger
The normal starting point is a class-level logger:
This is enough for many small applications. The logger name follows the class name, which fits JUL's hierarchy model.
Use Levels Deliberately
JUL supports levels such as SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST.
A practical example:
The point is not to memorize every level. It is to use levels consistently so operators can filter noise from real incidents.
Prefer Parameterized Logging
Instead of concatenating strings eagerly, JUL supports parameterized messages:
This is cleaner for structured message templates and avoids some unnecessary string construction.
If you are on newer Java versions, supplier-based logging is also useful for expensive messages:
That message is only constructed if the FINE level is enabled.
Add a File Handler
JUL becomes much more practical once you understand handlers:
setUseParentHandlers(false) matters here. Without it, the message may go both to the custom file handler and to inherited console handlers.
Handle Exceptions Properly
When logging exceptions, log the throwable object instead of flattening it to a string:
This preserves the stack trace and makes the log useful for debugging.
Configuration Can Be External
JUL also supports external configuration through logging.properties. A small example:
This is helpful when you want logging behavior to change between environments without recompiling code.
Common Pitfalls
The biggest pitfall is mixing custom handlers with inherited parent handlers and then wondering why each message appears twice.
Another common mistake is using string concatenation everywhere for debug messages, even when the level may be disabled. Parameterized or supplier-based logging is better.
People also log exceptions as plain text and lose the stack trace. If you have the throwable, pass it to LOGGER.log(...).
Finally, JUL works best when logger names and level usage follow a consistent hierarchy. Random logger naming quickly becomes hard to manage.
Summary
- Use one logger per class with a stable class-based name.
- Choose log levels intentionally and consistently.
- Prefer parameterized or supplier-based logging over eager string concatenation.
- Add handlers deliberately and disable parent handlers when duplication is unwanted.
- Log exceptions with the throwable object so stack traces are preserved.

