Custom loggers allow you to define named loggers tailored to specific application modules, services, or classes. This modular approach helps in maintaining granular control over logging configuration, enabling separate log levels, handlers, and formatters for different components.
Simple Program
import java.util.logging.*; public class CustomLoggerExample { private static final Logger customLogger = Logger.getLogger("MyCustomLogger"); public static void main(String[] args) { customLogger.setUseParentHandlers(false); // Disable default console output ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.INFO); consoleHandler.setFormatter(new SimpleFormatter()); customLogger.setLevel(Level.INFO); customLogger.addHandler(consoleHandler); customLogger.fine("This is a FINE message"); // Won't appear customLogger.info("Custom Logger INFO message"); // Will appear customLogger.warning("Custom Logger WARNING"); // Will appear } }
This shows how a custom-named logger (MyCustomLogger
) is configured independently of the root logger.
Problem Statement
In a banking application built by LotusJavaPrince, Mahesh wants to maintain separate loggers for:
- TransactionModule (logs to a file in XML format)
- AuthModule (logs to the console in simple format)
Each logger must:
- Be named (
com.bank.transaction
,com.bank.auth
) - Use independent levels and handlers
- Avoid parent handler propagation
import java.io.IOException; import java.util.logging.*; public class BankingSystemLogger { private static final Logger transactionLogger = Logger.getLogger("com.bank.transaction"); private static final Logger authLogger = Logger.getLogger("com.bank.auth"); public static void main(String[] args) throws IOException { // Setup Transaction Logger transactionLogger.setUseParentHandlers(false); transactionLogger.setLevel(Level.ALL); FileHandler transactionFileHandler = new FileHandler("transaction.log"); transactionFileHandler.setFormatter(new XMLFormatter()); transactionFileHandler.setLevel(Level.INFO); transactionLogger.addHandler(transactionFileHandler); // Setup Auth Logger authLogger.setUseParentHandlers(false); authLogger.setLevel(Level.ALL); ConsoleHandler authConsoleHandler = new ConsoleHandler(); authConsoleHandler.setFormatter(new SimpleFormatter()); authConsoleHandler.setLevel(Level.WARNING); authLogger.addHandler(authConsoleHandler); // Simulate logs transactionLogger.info("Transaction started"); transactionLogger.warning("Suspicious transaction detected"); authLogger.info("User login successful"); // Won't appear on console authLogger.severe("Multiple failed login attempts"); // Will appear } }
transaction.log
will capture INFO
and WARNING
in XML, while the console will only show SEVERE
level logs from the Auth module.
Creating custom loggers enables:
- Modular and isolated logging control.
- Per-component debugging and monitoring.
- Independent formatter and handler configurations.
- Clear separation of concerns in large applications.
This is vital in enterprise systems, microservices, or layered architectures where different subsystems demand different logging behavior.