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.

  1. Understand

    Logging records diagnostic events through configurable levels and handlers.

  2. Apply

    Trace the Java example, predict its output and explain the result before running it.

  3. 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 failures
  • WARNING – Potential issues
  • INFO – General information
  • CONFIG – Static configuration info
  • FINE, 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 console
  • FileHandler – 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 login
  • WARNING: Failed login attempts
  • SEVERE: 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

school

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.

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

For the complete practice program in this lesson, which output is expected on Java 17?
Choose one answer. You can try again.

Answer and explanation

school

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.

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.

    Next lesson: Assertions →