Introduction to Java Logging
\nLogging is the process of recording information about an application's operation. For beginner Java developers, this often seems like a secondary task, but in practice, properly configured logging saves hours of debugging and helps quickly find errors in production. In this article, we will cover best practices for logging in Java, review popular libraries, and write working examples.
\nBad logging is when you write System.out.println("Error here"). Good logging is structured records with severity levels, timestamps, and context. Let's learn to do it right.
Main Logging Libraries
\nIn Java, there are several standard and third-party solutions. Let's look at the three most popular options.
\n\nJava Util Logging (JUL)
\nA built-in library that comes with the JDK. The downside is limited flexibility. Usage example:
\nimport java.util.logging.Logger;\nimport java.util.logging.Level;\n\npublic class JULExample {\n private static final Logger logger = Logger.getLogger(JULExample.class.getName());\n\n public static void main(String[] args) {\n logger.info("Application started");\n logger.warning("This is a warning");\n logger.severe("Critical error");\n }\n}\n\nLog4j 2
\nOne of the most powerful and popular libraries. It supports asynchronous logging, filters, and flexible configuration. Example configuration via XML:
\n<?xml version="1.0" encoding="UTF-8"?>\n<Configuration>\n <Appenders>\n <Console name="Console" target="SYSTEM_OUT">\n <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>\n </Console>\n </Appenders>\n <Loggers>\n <Root level="info">\n <AppenderRef ref="Console"/>\n </Root>\n </Loggers>\n</Configuration>\n\nSLF4J + Logback
\nSLF4J is a facade (abstraction) for various logging systems. Logback is its native implementation. This is the modern de facto standard. Example:
\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class SLF4JExample {\n private static final Logger logger = LoggerFactory.getLogger(SLF4JExample.class);\n\n public static void main(String[] args) {\n logger.info("User {} logged in", "admin");\n try {\n int result = 10 / 0;\n } catch (ArithmeticException e) {\n logger.error("Division by zero error", e);\n }\n }\n}\n\nBest Practices for Beginners
\nFollowing these rules will make your logging professional and useful.
\n\n1. Use the Correct Logging Levels
\nIn Java, the following levels are used (from most to least important):
\n- \n
- ERROR — critical errors requiring immediate intervention (e.g., database connection loss). \n
- WARN — warnings about potential issues (e.g., using a deprecated API). \n
- INFO — important application events (startup, shutdown, successful request processing). \n
- DEBUG — detailed information for the developer (variable values, algorithm steps). \n
- TRACE — extremely detailed tracing (usually enabled only for finding specific bugs). \n
Never use System.out.println for logging — you will lose control over levels and format.
2. Always Include Contextual Information
\nA log should answer the questions: what happened, when, where, and with what data. Use parameterized messages:
\nlogger.info("Order {} for user