I have created simple python script:
import logging
import sys
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
print("This is a normal print statement", file=sys.stdout)
logging.debug("debug message")
logging.info("info message")
logging.warning("warning message")
I would expect that the color for the "INFO" level will be same as sysout or at least some neuetral color. But the output of the run of my script is:
I would like the "INFO" logs to be in at least same color as the one coming from "print". I have tried to add config like this:
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
But this did not help. I do not want to setup "loggers" for my project because using simple "logging" is more convienient for me.
In the real project which I am developing I have several classes where I use all the levels and many log messages, so this RED info logs makes the whole logs very unreadable.
I cannot believe that its normal for the INFO log to be red, but as you see I dont have any special configs. How I can easily configre the "logging" to have proper colouring?
Here are some examples for log config using VT100 control codes for the colors without any dependencies:
import logging
RESET = "\033[0m"
INVERSE = "\033[7m"
GREEN = "\033[32m"
RED_BG = "\033[41m"
# Set up general logging using green. you can try other colors here.
# changing colors again for all messages like this might require
# rerunning the script to take effect
logging.basicConfig(
level=logging.INFO,
format=f"{GREEN}%(asctime)s %(message)s{RESET}",
datefmt="%y-%m-%d %H:%M:%S"
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.info("This is an info message")
This will cause logs to be on red background. You can use the other VT100 codes for different effects. See Microsoft page on vt100 as a starting point for more info.
Edit: I saw your comment about avoiding loggers. Essentially what you want to do to keep things simple is to have the logging set up in your __init__.py
or such to keep it in one place. Then in the other files:
logger = logging.getLogger(__name__) # Config loaded from __init__.
logger.info("This is an info message")
The getlogger based on a given name avoids circular imports that might otherwise cause problems when attempting to import your logging from a central place.
Here is one more example that is a bit more complex. We set only the info messages to have a specific color. You can still use the above presented style for getlogger
to get the logger in other files
import logging
RESET = "\033[0m"
GREEN = "\033[32m"
# Custom formatter to apply green only to INFO messages
class InfoColorFormatter(logging.Formatter):
def format(self, record):
message = super().format(record)
if record.levelname == "INFO":
return f"{GREEN}{message}{RESET}"
return message
# Configure logging
logging.basicConfig(
level=logging.DEBUG, # Capture all log levels
format="%(asctime)s %(levelname)s: %(message)s",
datefmt="%y-%m-%d %H:%M:%S"
)
# Apply custom formatter to the root logger's handlers
handler = logging.getLogger().handlers[0]
handler.setFormatter(InfoColorFormatter("%(asctime)s %(levelname)s: %(message)s"))
# Logger usage
logger = logging.getLogger(__name__)
logger.debug("This is a debug message")
logger.info("This is an info message") # Will be green
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")