Java allows logging configuration directly in code. This gives developers full control over loggers, handlers, formatters, and levels at runtime, useful for dynamically adjusting logs or when file-based config isn’t practical.
Simple Program
import java.util.logging.*; public class SimpleProgrammaticLogging { private static final Logger logger = Logger.getLogger(SimpleProgrammaticLogging.class.getName()); public static void main(String[] args) { // Disable default console handler Logger rootLogger = Logger.getLogger(""); for (Handler h : rootLogger.getHandlers()) { rootLogger.removeHandler(h); } // Set custom ConsoleHandler ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.INFO); consoleHandler.setFormatter(new SimpleFormatter()); logger.setLevel(Level.INFO); logger.addHandler(consoleHandler); logger.fine("FINE: Hidden"); logger.info("INFO: Displayed"); logger.warning("WARNING: Displayed"); } }
Problem Statement
LotusJavaPrince wants to build a logger that logs all suspicious activity to a file for compliance purposes. Mahesh, the security officer, wants:
- Only
WARNING
andSEVERE
messages in the log file. - Console output must show everything from
FINE
and above. - All configuration must be programmatic, without
.properties
.
import java.io.IOException; import java.util.logging.*; public class BankAuditLogger { private static final Logger logger = Logger.getLogger(BankAuditLogger.class.getName()); public static void main(String[] args) throws IOException { // Disable root handlers Logger rootLogger = Logger.getLogger(""); for (Handler h : rootLogger.getHandlers()) { rootLogger.removeHandler(h); } // Console handler for detailed logs ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.FINE); consoleHandler.setFormatter(new SimpleFormatter()); // File handler for warnings and above FileHandler fileHandler = new FileHandler("security-audit.log", true); fileHandler.setLevel(Level.WARNING); fileHandler.setFormatter(new XMLFormatter()); logger.setLevel(Level.FINE); // Allow FINE logs in the logger itself logger.addHandler(consoleHandler); logger.addHandler(fileHandler); // Log simulation logger.fine("FINE: Debugging transaction processing"); logger.info("INFO: User Mahesh performed login"); logger.warning("WARNING: Suspicious transaction pattern"); logger.severe("SEVERE: Fraudulent activity detected"); } }
This will create security-audit.log
with WARNING
and SEVERE
entries in XML format, while the console shows all logs starting from FINE
.
Programmatic logging configuration is ideal when:
- Dynamic log behavior is needed.
- You want precise control over handler setup at runtime.
- Configuration files are not preferred or cannot be used.
It offers fine-grained control, is self-contained, and is suitable for embedded systems, testing, and microservices where environmental context drives logging.