When a script crashes at 2 a.m. on a production server,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HotCode2025/Print-Estoy-Cansado-Jefe-TercerSemestre/llms.txt
Use this file to discover all available pages before exploring further.
print() won’t save you — its output is gone the moment the process exits. Python’s built-in logging module writes timestamped, severity-labeled messages to any combination of files and consoles, and lets you filter them by importance without changing a single line of application code.
Replacing print() with logging gives you:
- Severity levels — distinguish a debug trace from a fatal crash at a glance
- Persistent file output — inspect logs after the fact without re-running the program
- Structured format — timestamp, level, file name, and line number in every message
- Zero-cost filtering — set the level to
WARNINGin production and allDEBUG/INFOmessages are suppressed at virtually no runtime cost
Stop using
print() in production code. print() has no severity, no timestamp, no file output, and no way to silence it selectively. Treat any print() call in application code as a code smell — replace it with the appropriate log.debug(), log.info(), or log.error() call.Logging Basics
The simplest possible setup callslogging.basicConfig() before the first log statement. This configures the root logger — the default logger that all module-level logging.X() calls use.
7.2 Manejo de Logging.py
Log level reference
| Level | Numeric value | When to use |
|---|---|---|
DEBUG | 10 | Detailed diagnostic information — object states, variable values, flow tracing |
INFO | 20 | Confirmation that things are working as expected — successful connection, record inserted |
WARNING | 30 | Something unexpected happened but the program is still running — deprecated feature used, disk space low |
ERROR | 40 | A serious problem — a function failed and could not complete its task |
CRITICAL | 50 | A fatal error — the program cannot continue, or data corruption is imminent |
level=log.DEBUG means all levels are emitted. Setting level=log.WARNING silences DEBUG and INFO entirely, without touching any other code.
Production-Ready Configuration — Handlers and Format
The course’s second logging exercise (7.3) adds a custom format string, a datefmt, and two handlers — one for the console and one for a persistent log file. This is the configuration pattern used throughout the DAO classes.
7.3 Manejo de logging Parte 2.py
Format string fields
| Placeholder | Description |
|---|---|
%(asctime)s | Human-readable timestamp, formatted by datefmt |
%(levelname)s | Text severity label: DEBUG, INFO, WARNING, ERROR, CRITICAL |
%(filename)s | Source file where the log call was made |
%(lineno)s | Line number of the log call |
%(message)s | The message passed to log.debug() / log.error() etc. |
Handler breakdown
FileHandler('capa_datos.log')
FileHandler('capa_datos.log')
Writes every log record to
capa_datos.log in the current working directory. The file is created if it does not exist and appended to on subsequent runs — giving you a persistent history across multiple executions. Use mode='w' to start fresh each run: log.FileHandler('capa_datos.log', mode='w').StreamHandler()
StreamHandler()
Writes to
sys.stderr by default (i.e., the terminal). Pass stream=sys.stdout to route output to standard out instead. Having both handlers means you see logs in real time in the terminal and they are saved to disk simultaneously.Using a Named Logger with getLogger
Rather than always using the root logger, production code creates a named logger tied to the current module. The convention is logging.getLogger(__name__), which gives each module its own logger whose name matches the module’s fully-qualified path.
logger_base.py
log object rather than each configuring their own:
any other module
logger_base.py, import everywhere — is exactly what the course’s 8.2_PruebaDeLaClasePersona.py and the Clase 8 DAO files use.
Logging in Class-Based Code
The real payoff comes when you droplog calls into the DAO classes. Every database operation becomes traceable without adding any print() noise.
PersonaDAO.insertar() succeeds you’ll see a line like:
obtenerConexion() fails (wrong password, database offline), you’ll see:
Configuring the Log Level at Runtime
Setting Up Logging Step by Step
Import the logging module
Python’s
logging module is part of the standard library — no installation required. Import it with an alias for brevity.Call basicConfig() once at startup
Configure the root logger exactly once, before any log calls. The best place is the top of your entry-point script or in a dedicated
logger_base.py module.logger_base.py
Import the configured logger in every module
Rather than calling
basicConfig() again (it only works once), import the already-configured log object from logger_base.conexion.py
Replace every print() with the right log level
Match the severity to the situation — don’t log everything as
DEBUG just because it’s convenient.