On 15/03/2021 09:47, Robert Latest via Python-list wrote:
Richard Damon wrote:
On 3/8/21 4:16 AM, Robert Latest via Python-list wrote:
Joseph L. Casale wrote:
I couldn't find any information on how to implement logging in a library
that doesn't know the name of the application that uses it. How is that
done?
That's not how it works, it is the opposite. You need to know the name of
its logger, and since you imported it, you do.
[much snipping]

Last word of advice, don't fight it by hacking up or patching (somehow?),
it will simply not work right for any other case even slightly different
than the one you somehow beat into submission.
I didn't waht to hack the logging system, it's just that I wasn't sure of
its design principles. I had hoped that if I set up a logger (including
levels and formatter) in my main app, the loggers in the imported modules
would somwhow automagically follow suit. Now I understand that for each
imported module I must import its logger, too, and decide how to deal with
its messages.


Each instance of the logger inherents from a 'parent' logger, except for the
top level logger which has the name None (as in the singleton of NoneType),
and unless told otherwise will inherit it properties from its parent.

Thus, if you get the root logger with logging.getLogger() you can set
properties there, and unless a child logger has specifical been told not to
inherit or has been specifically given a different value.

General convention is that modules will use their name as the name of their
logger, as that is generally unique.


I must admit I'm still struggling with the very basics of logging. I don't
understand the behavior of the code samples below at all, see comments.
It seems that logging.debug() et al have some side effects that are required
to get a logger to notice its level in the first place.


# Example 1:
# Why does the logger "mylog" require
# a call to the root logger in order to work?

Because logging.debug() implicitly calls basicConfig() if there are no handlers yet for the root logger. You should always configure your handlers explicitly, usually by a call to logging.basicConfig().


import logging

# - set the root logger's level
# - add a handler to the root logger
logging.basicConfig(level=logging.DEBUG)

mylog = logging.getLogger('foo')

In most cases I want the same log-level for all loggers, so I'd omit the line below.

mylog.setLevel(logging.DEBUG)

mylog.debug('1 mylog.debug()')   # prints nothing
logging.debug('2 logging.debug()') # prints nothing
mylog.debug('3 mylog.debug()')   # works


# Example 2:
# Why do I have to call 'logging.debug' before the root
# logger works?

import logging

mylog = logging.getLogger() # now mylog is the root logger
mylog.setLevel(logging.DEBUG) # setting level of root logger

mylog.debug('1 mylog.debug()')   # prints nothing, why?
logging.debug('2 logging.debug()') # works
mylog.debug('3 mylog.debug()')   # works



--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to