Python
error logging
debugging
logging module
programming

How do I log a Python error with debug information?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

If you want to log a Python error together with the useful debugging details, use the logging module rather than plain print. The most important feature is exception traceback logging, because without the traceback you often lose the exact failure path that explains the bug.

Use logging.exception Inside an except Block

The simplest and most idiomatic solution is logging.exception. It logs at error level and automatically includes the current exception traceback.

python
1import logging
2
3logging.basicConfig(level=logging.INFO)
4
5try:
6    result = 10 / 0
7except Exception:
8    logging.exception("Computation failed")

That produces:

  • your message
  • the exception type
  • the exception message
  • the traceback

For debugging production errors, that is usually the minimum acceptable amount of information.

Use exc_info=True When You Need Custom Log Levels

If you want the same traceback behavior with another logging call, pass exc_info=True.

python
1import logging
2
3logger = logging.getLogger(__name__)
4
5try:
6    {}["missing"]
7except Exception:
8    logger.error("Lookup failed while processing payload", exc_info=True)

This is useful when you want to keep the traceback but choose the level explicitly, such as warning, error, or critical.

Add Context, Not Just the Stack Trace

A traceback tells you where the code failed. It does not always tell you what inputs or state caused the failure. Good error logs include a small amount of structured context.

python
1import logging
2
3logger = logging.getLogger(__name__)
4
5user_id = 42
6filename = "report.csv"
7
8try:
9    raise ValueError("invalid format")
10except Exception:
11    logger.exception("Import failed for user_id=%s filename=%s", user_id, filename)

The key is to log enough context to reproduce or diagnose the issue without dumping sensitive data recklessly.

Configure the Logger for Debugging Workflows

If you want debug information, the logger configuration matters too.

python
1import logging
2
3logging.basicConfig(
4    level=logging.DEBUG,
5    format="%(asctime)s %(levelname)s %(name)s %(message)s"
6)

A better format can make logs dramatically more useful. Timestamp, level, logger name, and message are a solid baseline.

During development you may want DEBUG; in production you often keep normal operation at INFO and log failures at ERROR or above.

Choose Logger Names Deliberately

Using a module-level logger rather than the root logger makes larger applications easier to debug.

python
logger = logging.getLogger(__name__)

With named loggers, you can adjust verbosity by subsystem and quickly tell which part of the application emitted the failure. That becomes important once the codebase grows beyond a single script.

Avoid print for Real Error Reporting

print is fine for a quick local experiment, but it is a poor long-term error-reporting tool. It does not include levels, does not integrate well with handlers, and does not automatically capture tracebacks.

If the code matters enough to debug later, it matters enough to log properly.

Common Pitfalls

  • Catching an exception and logging only a custom message without the traceback.
  • Using print statements instead of the logging module for real error diagnostics.
  • Logging too little context to reproduce the failure later.
  • Logging sensitive data such as secrets or personal information while trying to add debug context.
  • Swallowing exceptions after logging when the caller still needs to know the operation failed.

Summary

  • Use logging.exception inside except blocks for the simplest full error log.
  • Use exc_info=True when you want traceback logging with a custom log level.
  • Add a small amount of useful context to the log message.
  • Configure log format and levels so the output is actually readable.
  • Good Python error logs include both the failure path and the relevant state around it.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.