Logging
Logging
A school program needs reliable data and clear rules. Logging records diagnostic events through configurable levels and handlers. A school report should separate diagnostic messages from the student-facing result.
Understand
Logging records diagnostic events through configurable levels and handlers.
Apply
Trace the Java example, predict its output and explain the result before running it.
Avoid mistakes
Logger configuration controls whether an event is shown. Default timestamps and formatting are environment-dependent, so they are not fixed output guarantees.
Logging
In software development, logs are more than just lines of text — they’re your application’s black box. Java provides a powerful and flexible logging framework in the java.util.logging package, often referred to as JUL (Java Util Logging).
This tutorial introduces you to Java Logging step by step — perfect if you're just getting started. We'll look at log levels, handlers, formatters, and how to customize everything to suit your project.
Why Logging Matters
Before diving into the code, let’s ask a simple question — why log?
- To trace issues during development
- To monitor system health in production
- To audit and track user behavior
Unlike System.out.println(), logging frameworks allow you to filter messages, write them to files, or even send them over the network.
Basic Java Logging Setup
Let’s start by creating a simple logger.
import java.util.logging.Logger;
public class BasicLogger {
private static final Logger logger = Logger.getLogger(BasicLogger.class.getName());
public static void main(String[] args) {
logger.info("Application started");
logger.warning("This is a warning");
logger.severe("Something went wrong");
}
}
Mar 16, 2025 10:20:01 AM BasicLogger main
INFO: Application started
Mar 16, 2025 10:20:01 AM BasicLogger main
WARNING: This is a warning
Mar 16, 2025 10:20:01 AM BasicLogger main
SEVERE: Something went wrong
Understanding Log Levels
Java logging has built-in severity levels that determine which messages get logged. They are:
SEVERE– Critical failuresWARNING– Potential issuesINFO– General informationCONFIG– Static configuration infoFINE,FINER,FINEST– Debugging details
Setting the Logging Level
By default, only INFO and above are shown. To see debug-level logs, set a lower level on the logger:
import java.util.logging.*;
public class LevelExample {
private static final Logger logger = Logger.getLogger(LevelExample.class.getName());
public static void main(String[] args) {
logger.setLevel(Level.FINE);
ConsoleHandler handler = new ConsoleHandler();
handler.setLevel(Level.FINE);
logger.addHandler(handler);
logger.fine("This is a FINE log message");
logger.info("This is an INFO log message");
}
}
Mar 16, 2025 10:25:34 AM LevelExample main
FINE: This is a FINE log message
Mar 16, 2025 10:25:34 AM LevelExample main
INFO: This is an INFO log message
Important: You need to set both logger and handler levels — otherwise, messages won’t show.
Log Handlers: Where Logs Go
A Handler determines the destination of a log message. Common handlers include:
ConsoleHandler– prints to consoleFileHandler– writes to a file- Custom handlers for email, sockets, etc.
import java.io.IOException;
import java.util.logging.*;
public class FileLogging {
private static final Logger logger = Logger.getLogger(FileLogging.class.getName());
public static void main(String[] args) throws IOException {
FileHandler fileHandler = new FileHandler("app.log", true);
fileHandler.setLevel(Level.ALL);
logger.addHandler(fileHandler);
logger.setLevel(Level.ALL);
logger.info("Logged to file");
}
}
Log Formatters: How Logs Look
By default, logs have timestamps and class names. But you can customize the format using a Formatter.
import java.util.logging.*;
public class CustomFormat {
public static void main(String[] args) throws Exception {
Logger logger = Logger.getLogger("MyLogger");
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new SimpleFormatter());
logger.addHandler(handler);
logger.setUseParentHandlers(false);
logger.info("Formatted log");
}
}
Disabling Parent Handlers
If you don't disable parent handlers, your logs might appear twice.
logger.setUseParentHandlers(false);
Custom Formatter Example
You can go a step further and create your own format:
import java.util.logging.*;
public class MyFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return "[" + record.getLevel() + "] " + record.getMessage() + "\n";
}
public static void main(String[] args) {
Logger logger = Logger.getLogger("CustomLogger");
ConsoleHandler handler = new ConsoleHandler();
handler.setFormatter(new MyFormatter());
logger.addHandler(handler);
logger.setUseParentHandlers(false);
logger.warning("This is a custom log format!");
}
}
[WARNING] This is a custom log format!
Logging Best Practices
- Use
Logger.getLogger()with the class name - Don’t log sensitive data
- Use appropriate log levels — don’t log everything as INFO
- Use external config for log settings in production
Real-World Logging Use Case
Imagine a banking app. You could log:
INFO: User loginWARNING: Failed login attemptsSEVERE: Database unreachable
Conclusion
Logging in Java is not just for debugging — it’s for accountability, monitoring, and performance analysis. With java.util.logging, you get a solid foundation out of the box. As your application grows, consider integrating with frameworks like Log4j or SLF4J for even more power.
Important boundaries and mistakes
Logger configuration controls whether an event is shown. Default timestamps and formatting are environment-dependent, so they are not fixed output guarantees.
Try the school example
Before running this Java program, write down each line you expect to see. Identify the value, branch, object or exception responsible for each line. Then explain whether the following assumption is valid: Logger configuration controls whether an event is shown.
Java 17 · Main.java · complete practice program
public class Main {
public static void main(String[] args) {
java.util.logging.Logger log = java.util.logging.Logger.getLogger("school");
log.setUseParentHandlers(false);
System.out.println(log.getName());
}
}
Worked answer and reasoning
Java 17 · Main.java · source repeated for this answer
public class Main {
public static void main(String[] args) {
java.util.logging.Logger log = java.util.logging.Logger.getLogger("school");
log.setUseParentHandlers(false);
System.out.println(log.getName());
}
}
Expected output
schoolLogging records diagnostic events through configurable levels and handlers. A school report should separate diagnostic messages from the student-facing result.
Logger configuration controls whether an event is shown. Default timestamps and formatting are environment-dependent, so they are not fixed output guarantees.
Run with javac Main.java, then java Main. The declaration of Main names the class; main starts the example, and println writes a complete output line.
Check your understanding
What to remember
Logging records diagnostic events through configurable levels and handlers. A school report should separate diagnostic messages from the student-facing result. Logger configuration controls whether an event is shown. Default timestamps and formatting are environment-dependent, so they are not fixed output guarantees.
Related explanations: Java Variables, Java If Statement - Syntax and Examples, Java Class - Blueprint of Objects, Exceptions in Java Introduction.
Supporting documentation: Official Java learning guide and Java 17 language specification.
Reaching the recap and completing the quizzes are separate milestones.