Python难以理解GetLogger(__名称__)

发布于 2025-02-13 05:23:39 字数 2338 浏览 1 评论 0原文

我对登录文档对getlogger(__名称__)的解释感到非常困惑。

会解释我的整个思维过程,随时随时发表评论,我犯了一个错误,

登录文档

当命名登录器使用模块级时使用的好惯例 Logger,在使用日志记录的每个模块中,命名为如下:logger = logging.getLogger(__ name __)

Logger,在使用日志记录的

main_module.py
cookbook_example
---auxiliary_module.py

import logging
from cookbook_example import auxiliary_module
# Creates a new logger instance
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# Create file handler that logs debug messages
fh = logging.FileHandler('spam.log', mode='w')
fh.setLevel(logging.DEBUG)
# Create a formatter
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.info('Creating instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
logger.info('Calling auxiliary_module.do_something')
a.do_something()
auxiliary_module.some_function()

每个模块中

import logging

# create logger
module_logger = logging.getLogger(f'__main__.{__name__}')


def some_function():
    module_logger.info('received a call to "some_function"')

__ href =“ https://stackoverflow.com/questions/50714316/50714316/how-to-so-use-logging-getlogger-name-name-in-multiple-modules”> so thread ,我推断出该getlogger(__ name name name __ name __ name __ )实际上不应在使用日志记录的每个模块中使用,而应在配置记录器的模块中使用,在这种情况下,这将是main_module.py,

例如在辅助模块中,尝试通过getLogger(__ name __)将返回根记录器,而getLogger(f'__ main __。{__ __ name __}'。那个自定义记录仪。

对我来说,这种格式getLogger(f'__ main __。{__ name __}')似乎比explicit getlogger('main_module.auxiliary_module' 。此外,在日志文件中,它logs __ main __。auxiliary_module而不是main_module.auxiliary_module,失去了一些精度。

最后,我先前曾说过,据我了解,getLogger(__ name __)仅应将其放置在配置记录器的模块中。但是,配置应放置在配置文件或dict中。

因此,我似乎不了解getlogger(__ name __)的任何合理用法,以及它的最佳用法。有人可以解释这一点,也许可以链接使用我可以参考的适当组织的记录仪的存储库?谢谢

Im quite confused on the logging docs' explanation of getLogger(__name__) as a best practice.

Gonna be explaining my entire thought process, feel free to leave a comment any time I make a mistake

The logging docs says

A good convention to use when naming loggers is to use a module-level
logger, in each module which uses logging, named as follows: logger = logging.getLogger(__name__)

Say I have a project structure:

main_module.py
cookbook_example
---auxiliary_module.py

main_module.py

import logging
from cookbook_example import auxiliary_module
# Creates a new logger instance
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# Create file handler that logs debug messages
fh = logging.FileHandler('spam.log', mode='w')
fh.setLevel(logging.DEBUG)
# Create a formatter
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.info('Creating instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
logger.info('Calling auxiliary_module.do_something')
a.do_something()
auxiliary_module.some_function()

auxiliary_module.py

import logging

# create logger
module_logger = logging.getLogger(f'__main__.{__name__}')


def some_function():
    module_logger.info('received a call to "some_function"')

Now, from this SO thread, I infer that getLogger(__name__) should not actually be used in EVERY module that uses logging but instead in the module where a logger is configured, which in this case would be main_module.py

e.g. In the auxiliary module, trying to get the custom logger through getLogger(__name__) will return the root logger, whereas getLogger(f'__main__.{__name__}') will return that custom logger.

To me, this formatting of getLogger(f'__main__.{__name__}') doesn't seem much easier to write than the explicit getLogger('main_module.auxiliary_module'). Furthermore, in the log files it logs __main__.auxiliary_module rather than main_module.auxiliary_module, losing a bit of accuracy.

Lastly, I previously stated that to my understanding, getLogger(__name__) should only be placed in the module where the logger is configured. However, configuration should be placed in a config file or dict anyways.

Thus, I don't seem to understand any reasonable usage of getLogger(__name__) and how it is, according to the docs, a best practice. Could someone explain this and maybe link a repo that uses loggers with proper organisation that I could refer to? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

攒眉千度 2025-02-20 05:23:39

假设这个简单的项目:

project/
├── app.py
├── core
│   ├── engine.py
│   └── __init__.py
├── __init__.py
└── utils
    ├── db.py
    └── __init__.py

其中app.py is:

import logging
import sys

from utils import db
from core import engine

logger = logging.getLogger()
logger.setLevel(logging.INFO)
stdout = logging.StreamHandler(sys.stdout)
stdout.setFormatter(logging.Formatter("%(name)s: %(message)s"))
logger.addHandler(stdout)


def run():
    db.start()
    engine.start()


run()

and utils/db.py and code> core> core/Engine.py.py.py is:

from logging import getLogger

print(__name__)  # will print utils.db or core.engine
logger = getLogger(__name__)
print(id(logger))  # different object for each module; child of root though


def start():
    logger.info("started")

如果您运行此操作使用Python App.py,您会发现它需要为您打印适当的命名空间。

utils.db: started
core.engine: started

如果您的代码井井有条,则您的模块名称本身就是可用的最佳记录器名称。如果您必须重新发明这些名称,通常意味着您的模块结构不好(或一些特殊的模块结构,
非标准用例)。但是,出于大多数目的,这应该可以正常工作(因此是stdlib的一部分)。

这就是其中的全部。请记住,您并没有真正设置处理程序 ;那留给消费者。

Assume this simple project:

project/
├── app.py
├── core
│   ├── engine.py
│   └── __init__.py
├── __init__.py
└── utils
    ├── db.py
    └── __init__.py

Where app.py is:

import logging
import sys

from utils import db
from core import engine

logger = logging.getLogger()
logger.setLevel(logging.INFO)
stdout = logging.StreamHandler(sys.stdout)
stdout.setFormatter(logging.Formatter("%(name)s: %(message)s"))
logger.addHandler(stdout)


def run():
    db.start()
    engine.start()


run()

and utils/db.py and core/engine.py is:

from logging import getLogger

print(__name__)  # will print utils.db or core.engine
logger = getLogger(__name__)
print(id(logger))  # different object for each module; child of root though


def start():
    logger.info("started")

If you run this using python app.py, you will see that it takes care of printing the proper namespaces for you.

utils.db: started
core.engine: started

If your code is well organised, your module name itself is the best logger name available. If you had to reinvent those names, it usually means that you have a bad module structure (or some special,
non-standard use case). For most purposes though, this should work fine (hence part of stdlib).

That is all there is to it. Remember, you don't really set handlers for libraries; that is left to the consumer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文