Python logging not outputting anything
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When Python's logging module produces no output, the cause is almost always one of three things: the logger's level is set higher than the message level (default is WARNING, so logging.info() and logging.debug() are silently dropped), no handler is attached to the logger, or a handler is attached but its own level filters out the message. The fix is usually a single call to logging.basicConfig(level=logging.DEBUG) at the start of your script, or properly configuring a handler with the desired level.
The Problem
The root logger's default level is WARNING. Any message below WARNING (i.e., DEBUG and INFO) is silently discarded.
Fix 1: Set the Logging Level
basicConfig(level=logging.DEBUG) sets the root logger to accept all messages at DEBUG and above, and adds a StreamHandler that prints to stderr.
Fix 2: basicConfig Called Too Late
basicConfig() does nothing if the root logger already has handlers. Move it to the very top of your entry point, before any imports that might call logging functions.
Fix 3: Force Reconfiguration
The force=True parameter (Python 3.8+) removes existing handlers before reconfiguring.
Fix 4: Configure Named Loggers Properly
Named loggers created with getLogger(__name__) start with no handlers and inherit the root logger's level. You must either configure the root logger or add handlers directly.
Fix 5: Level Hierarchy Issues
A message must pass both the logger's level and the handler's level to produce output. If either filters it out, nothing is printed.
Fix 6: Logging in Jupyter Notebooks
Jupyter notebooks configure the root logger during startup. Use a named logger with explicitly added handlers to avoid conflicts.
Complete Production Configuration
Common Pitfalls
- Default level is WARNING:
logging.info()andlogging.debug()produce no output unless you explicitly set the level toINFOorDEBUG. This catches most beginners. basicConfig()only works once: If any code (including imported libraries) calls a logging function before yourbasicConfig(), the root logger gets auto-configured with default settings and yourbasicConfig()is ignored. Useforce=True(Python 3.8+) or configure before any imports.- Duplicate log messages: Adding a handler every time a function is called (e.g., inside a loop or on every request) causes duplicate output. Check
if not logger.handlersbefore adding, or uselogger.handlers.clear(). - Logger level vs handler level confusion: Both the logger and each handler have independent levels. A message must pass both filters. Setting the logger to
DEBUGbut the handler toWARNINGstill drops debug messages. propagate=Truecausing unexpected output: Named loggers propagate messages to parent loggers by default. If both the named logger and root logger have handlers, messages appear twice. Setlogger.propagate = Falseto prevent propagation.
Summary
- Call
logging.basicConfig(level=logging.DEBUG)before any logging calls - The default level is
WARNING—DEBUGandINFOmessages are silently dropped basicConfig()only works once — useforce=True(Python 3.8+) to reconfigure- Both logger level and handler level must allow the message for it to appear
- Use named loggers (
getLogger(__name__)) with explicit handlers for production code - Set
propagate = Falseon named loggers to avoid duplicate messages

