Python: How to create and use a custom logger in python use logging module?

2024/5/19 19:14:20

I am trying to create a custom logger as in the code below. However, no matter what level I pass to the function, logger only prints warning messages. For example even if I set the argument level = logging.DEBUG by default my code fails to log the debug or info messages. Can someone point out the problem here.

import boto3
import loggingdef get_logger(name=__name__, level=logging.DEBUG):# Create log handlerlogHandler = logging.StreamHandler()logHandler.setLevel(level)# Set handler formatlogFormat = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%d-%b-%y")logHandler.setFormatter(logFormat)# Create loggerlogger = logging.getLogger(name)# Add handler to loggerlogger.addHandler(logHandler)# Stop propagating the log messages to root logger# logger.propagate = Falsereturn loggerdef listBuckets():logThis = get_logger(level=logging.DEBUG)s3 = boto3.resource('s3')for bucket in s3.buckets.all():logThis.debug(msg='This message is from logger')print(bucket.name)listBuckets()
Answer

You are missing the fact that a) every logger's ultimate ancestor is the root logger (which has level WARNING by default) and b) that both, loggers and handlers have levels.

The docs state:

When a logger is created, the level is set to NOTSET (which causes allmessages to be processed when the logger is the root logger, ordelegation to the parent when the logger is a non-root logger).

So, you create a logger and a StreamHandler with their default level NOTSET. Your logger is an implicit descendant of the root logger. You set the handler to level DEBUG, but not the logger using that handler. Since the level on your logger still is NOTSET, when a log event occurs, its chain of ancestors is traversed ...

... until either an ancestor with a level other than NOTSET is found, orthe root is reached.

[...]

If the root is reached, and it has a level of NOTSET, then allmessages will be processed. Otherwise, the root’s level will be usedas the effective level.

Which means, you immediately end up at the root logger to determine the effective log level; it is set to WARNING as per the root logger's default. You can check this with the parent and level properties and the getEffectiveLevel method on the logger object:

logThis = get_logger()
print(logThis.parent)               # <RootLogger root (WARNING)>
print(logThis.level)                # 0 (= NOTSET)
print(logThis.getEffectiveLevel())  # 30 (= WARNING) from root logger

To have your logger handle the messages on and above the desired level itself, simply set it on the logger via logger.setLevel(level) in your get_logger function.

https://en.xdnf.cn/q/72769.html

Related Q&A

Flask-Mail - Sending email asynchronously, based on Flask-Cookiecutter

My flask project is based on Flask-Cookiecutter and I need to send emails asynchronously.Function for sending email was configured by Miguel’s Tutorial and sending synchronously works fine, but i don’…

Change text_factory in Django/sqlite

I have a django project that uses a sqlite database that can be written to by an external tool. The text is supposed to be UTF-8, but in some cases there will be errors in the encoding. The text is fro…

Shuffle patches in image batch

I am trying to create a transform that shuffles the patches of each image in a batch. I aim to use it in the same manner as the rest of the transformations in torchvision: trans = transforms.Compose([t…

Python looping: idiomatically comparing successive items in a list

I need to loop over a list of objects, comparing them like this: 0 vs. 1, 1 vs. 2, 2 vs. 3, etc. (Im using pysvn to extract a list of diffs.) I wound up just looping over an index, but I keep wondering…

Geodesic buffering in python

Given land polygons as a Shapely MultiPolygon, I want to find the (Multi-)Polygon that represents the e.g. 12 nautical mile buffer around the coastlines.Using the Shapely buffer method does not work si…

jinja2 variables naming - Are variables naming restrictions the same as for Python variables?

I didt find it written explicitly in the docs.Are the naming rules the same as with Python variables?(eg: {{ a_variablelike_that }} doesnt work for example)

What does t /= d mean? Python and getting errors

// t: current time, b: begInnIng value, c: change In value, d: durationdef: easeOutQuad, swing: function (x, t, b, c, d) {//alert(jQuery.easing.default);return jQuery.easing[jQuery.easing.def](x, t, b,…

Python File Read + Write

I am working on porting over a database from a custom MSSQL CMS to MYSQL - Wordpress. I am using Python to read a txt file with \t delineated columns and one row per line.I am trying to write a Python …

Uploading a file via pyCurl

I am trying to convert the following curl code into pycurl. I do not want to use requests. I need to use pycurl because requests is not fully working in my old python version.curl -X POST -H "Acce…

Speed up computation for Distance Transform on Image in Python

I would like to find the find the distance transform of a binary image in the fastest way possible without using the scipy package distance_trnsform_edt(). The image is 256 by 256. The reason I dont wa…