Logging in Python
Here’s the translation of the Go logging example to Python, formatted in Markdown suitable for Hugo:
Python provides several ways to handle logging through its built-in logging
module. This module offers a flexible framework for generating log messages from Python programs.
import logging
import json
from io import StringIO
def main():
# The simplest way to log is using the basic config and logging functions
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logging.info("standard logger")
# You can set the logging level and format
logging.basicConfig(level=logging.INFO, format='%(asctime)s.%(msecs)03d - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logging.info("with milliseconds")
# Adding the filename and line number to the log output
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(filename)s:%(lineno)d - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logging.info("with file/line")
# Creating a custom logger
mylog = logging.getLogger("mylogger")
mylog.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('my:%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
handler.setFormatter(formatter)
mylog.addHandler(handler)
mylog.info("from mylog")
# Changing the prefix (name) of the logger
mylog.name = "ohmy"
mylog.info("from mylog")
# Logging to a buffer
buf = StringIO()
buflog = logging.getLogger("buflogger")
buflog.setLevel(logging.INFO)
handler = logging.StreamHandler(buf)
formatter = logging.Formatter('buf:%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
handler.setFormatter(formatter)
buflog.addHandler(handler)
buflog.info("hello")
print("from buflog:", buf.getvalue().strip())
# For structured logging, we can use the json module
class JSONFormatter(logging.Formatter):
def format(self, record):
log_record = {
"time": self.formatTime(record, self.datefmt),
"level": record.levelname,
"msg": record.getMessage()
}
return json.dumps(log_record)
json_logger = logging.getLogger("json_logger")
json_logger.setLevel(logging.INFO)
json_handler = logging.StreamHandler()
json_formatter = JSONFormatter('%(asctime)s')
json_handler.setFormatter(json_formatter)
json_logger.addHandler(json_handler)
json_logger.info("hi there")
json_logger.info("hello again", extra={"key": "val", "age": 25})
if __name__ == "__main__":
main()
This Python script demonstrates various logging techniques:
- We start with the basic logging configuration and output.
- We then show how to include milliseconds in the timestamp.
- Next, we include the filename and line number in the log output.
- We create a custom logger with a specific prefix.
- We demonstrate how to change the name (prefix) of a logger.
- We show logging to a buffer (StringIO in this case) instead of standard output.
- Finally, we create a JSON formatter for structured logging, similar to the
slog
package in Go.
To run this script, save it as logging_example.py
and execute it with Python:
$ python logging_example.py
The output will be similar to the following (timestamps will vary):
2023-08-22 10:45:16 - standard logger
2023-08-22 10:45:16.904 - with milliseconds
2023-08-22 10:45:16 - logging_example.py:20 - with file/line
my:2023-08-22 10:45:16 - from mylog
ohmy:2023-08-22 10:45:16 - from mylog
from buflog: buf:2023-08-22 10:45:16 - hello
{"time": "2023-08-22 10:45:16,904", "level": "INFO", "msg": "hi there"}
{"time": "2023-08-22 10:45:16,904", "level": "INFO", "msg": "hello again", "key": "val", "age": 25}
This example demonstrates how to use Python’s logging module to achieve similar functionality to Go’s log
and slog
packages. The logging
module in Python is highly configurable and can be adapted to various logging needs.