← Back to Advanced Java Course | Chapter 11: Advanced & Security | Lesson 14 of 19

Java Logging (Log4j/SLF4J)

Why Logging?

Logging is the practice of recording program events as they happen during runtime. It's a far more robust alternative to scattering System.out.println() calls throughout your code, because it lets you categorize messages by severity, route them to different destinations, and turn categories on or off without editing source code.

Example: Why Logging?

java
import java.util.logging.Logger;
public class Main {
	static final Logger logger = Logger.getLogger(Main.class.getName());
	public static void main(String[] args) {
		logger.info("Categorized, routable log message"); // more robust than System.out.println
	}
}

Java Native Logger

The built-in java.util.logging package (often called JUL) provides logging features out of the box with zero external dependencies, which makes it a reasonable starting point for small applications, even though larger projects often prefer a more feature-rich third-party framework.

Example: Java Native Logger

java
import java.util.logging.Logger;
public class Main {
	public static void main(String[] args) {
		Logger logger = Logger.getLogger("com.example.app"); // java.util.logging, zero external dependencies
		logger.info("Application started");
	}
}

Log Levels

Log levels categorize messages by how important or severe they are -- INFO for routine informational events, WARNING for potential issues that aren't yet failures, and SEVERE for critical errors -- letting you filter output to just the severity level you actually care about at a given time.

Example: Log Levels

java
import java.util.logging.*;
public class Main {
	static final Logger logger = Logger.getLogger(Main.class.getName());
	public static void main(String[] args) {
		logger.info("Routine event");
		logger.warning("Potential issue");
		logger.severe("Critical error");
	}
}

File Handlers

FileHandlers redirect log output to physical files on the server's disk instead of just the console, ensuring you have a persistent, searchable history of what happened even after a console session or terminal has closed.

Example: File Handlers

java
import java.util.logging.*;
public class Main {
	public static void main(String[] args) throws Exception {
		Logger logger = Logger.getLogger(Main.class.getName());
		FileHandler fileHandler = new FileHandler("app.log"); // persists to disk, not just console
		logger.addHandler(fileHandler);
		logger.info("Written to app.log");
		fileHandler.close();
		new java.io.File("app.log").delete();
	}
}

SLF4J and Log4j Wrappers

Enterprise applications commonly use SLF4J as a logging facade -- a standardized API that decouples your code from any specific logging implementation, letting you plug in Log4j, Logback, or another backend framework later without rewriting every logging call in your codebase.

Example: SLF4J and Log4j Wrappers

java
public class Main {
	interface Logger { void info(String msg); } // a facade like SLF4J -- decoupled from any specific backend
	static class ConsoleLogger implements Logger {
		public void info(String msg) { System.out.println("[INFO] " + msg); }
	}
	public static void main(String[] args) {
		Logger logger = new ConsoleLogger(); // could be swapped for Log4j/Logback later
		logger.info("Facade decouples code from the logging backend");
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.