How can I color Python logging output?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Python's logging module outputs plain text by default. To add color, you create a custom Formatter that wraps log messages with ANSI escape codes based on the log level. ANSI codes like \033[31m (red) and \033[0m (reset) are interpreted by most modern terminals. For a simpler approach, the colorlog package provides a drop-in colored formatter without writing custom code.
ANSI Escape Codes Basics
Terminals interpret special character sequences to change text color:
The \033[0m reset code is essential — without it, all subsequent output stays colored.
Custom Colored Formatter
Coloring Only the Level Name
For a cleaner look, color just the level name instead of the entire line:
Using the colorlog Package
colorlog handles terminal detection, Windows compatibility, and provides named colors instead of raw ANSI codes.
Using the rich Library
rich provides syntax-highlighted tracebacks, automatic markup, and works on all platforms.
Disabling Colors for File Output
Colors should only apply to terminal output, not log files:
Or auto-detect whether output is a terminal:
Windows Support
ANSI codes work natively in Windows Terminal and PowerShell (Windows 10+). For older Windows consoles:
Common Pitfalls
- ANSI codes in log files: If your logger writes to both console and file, the file contains raw escape sequences like
\033[31mthat look like garbage. Use separate formatters — colored forStreamHandler, plain forFileHandler. - Broken padding with colored level names: ANSI escape codes are invisible characters that are counted in string width.
"%(levelname)-8s"pads to 8 characters, but the ANSI codes add 9+ invisible characters, misaligning columns. Increase the pad width to compensate (e.g.,-18s). - Colors not appearing in some terminals: CI/CD environments, Docker containers, and some IDEs do not support ANSI codes. Check
sys.stderr.isatty()before adding colors, or use libraries likecolorlogthat handle this automatically. - Forgetting the reset code
\033[0m: Without the reset code at the end, all subsequent terminal output stays colored. This can affect other programs or shell prompts. - Using
colorama.init(autoreset=True)with logging:autoreset=Trueresets color after everyprint()call, but it does not work withloggingbecause the logger writes through a different code path. Use explicit reset codes in your formatter instead.
Summary
- Create a custom
logging.Formatterthat wraps messages with ANSI escape codes per log level - Use
\033[31mfor red (ERROR),\033[33mfor yellow (WARNING),\033[32mfor green (INFO) - Always append
\033[0mto reset formatting after each message - Use
colorlogorrichpackages for cross-platform colored logging without custom code - Apply colors only to terminal output (
StreamHandler), not file output (FileHandler) - Check
sys.stderr.isatty()to auto-detect terminal vs pipe/redirect
Related reading
- How can I configure Logback to log different levels for a logger to different destinations?
- How can I count the number of requests in the last second, minute and hour?
- How can I create a Route 53 Record to an ALB? AWS
- How can I create an image from a container running in Kubernetes?
- How can I compare two lists in python and return matches
- How can I connect to MySQL in Python 3 on Windows?
- How can I delete Docker's images?
- How can I delete environment variable with kustomize?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack 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.