英文:
How to implement logging in reusable packages?
问题
我越来越经常将常用任务转移到我的小型库中。然而,我还没有弄清楚记录日志的最佳实践。有很多资源解释类似的东西:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('This is a log message.')
但是在面向重用的包中如何处理呢?我应该只导入und message
,然后在导入主程序时进行一次配置吗?显然,我想在我的主应用程序中设置日志样式和级别,但不是每个单独的包。
那么如何使包“准备好记录日志”?
英文:
I'm more and more offloading frequently used tasks in small little libraries of mine. However I haven't figured out what the best practice for logging is. There are lots of resources explaining something like:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('This is a log message.')
But how to deal with that in packages intended for reuse? Should I just import und message, but do the config once in the main program importing? Obviously I want to set the logging style and level in my main app, but not every single package.
So how to make packages "ready for logging"?
答案1
得分: 1
你的翻译如下:
你的理解几乎完全正确。处理程序设计成在应用程序侧定义。只需将记录器添加到你的库中。使用根记录器可能很容易,但很快就会变得难以控制,所以让我们为它们命名与模块相关的名称:
# mylibA.py
import logging
logger = logging.getLogger(__name__)
logger.info('来自mylibA的问候')
# mylibB.py
import logging
logger = logging.getLogger(__name__)
logger.info('来自mylibB的问候')
使用basicConfig
将会向根记录器添加处理程序以捕获所有记录器。这包括我们刚刚在你的库和第三方库中定义的记录器。你可以根据需要设置格式:
# myapp.py
import logging
logging.basicConfig(filename='myapp.log', level=logging.INFO)
想象一下,mylibA已经很成熟,你只想捕获其关键日志,并且你想忽略一个正在产生日志的第三方库。因为我们使用模块名称作为记录器名称,所以很容易关注你实际需要的内容。
# myapp.py
import logging
sh = logging.StreamHandler()
sh.setLevel(logging.CRITICAL)
logging.getLogger('mylibA').addHandler(sh)
logging.getLogger('mylibB').addHandler(logging.StreamHandler())
此外,你可以毫不费力地同时运行多个应用程序,每个应用程序都以适合其自身的方式收集、处理和格式化日志,而不会出现问题。
英文:
You're pretty much spot on. Handlers were designed to be defined on the app side. Only add the logger to your libraries. Using the root logger may be easy but quickly gets out of hand so let's give them a name related to the module:
# mylibA.py
import logging
logger = logging.getLogger(__name__)
logger.info('hello from mylibA')
# mylibB.py
import logging
logger = logging.getLogger(__name__)
logger.info('hello from mylibB')
Using basicConfig
will add a handler to the root logger to capture all loggers. That includes the ones we just defined in your libraries and third party libraries. You're able to set the format as you wish:
# myapp.py
import logging
logging.basicConfig(filename='myapp.log', level=logging.INFO)
Imagine, mylibA is mature and you only want to capture critical logs for it and you want to ignore a third party library that's producing logs. Because we've used module names for logger names it's easy to focus on what you actually want.
# myapp.py
import logging
sh = logging.StreamHandler()
sh.setLevel(logging.CRITICAL)
logging.getLogger('mylibA').addHandler(sh)
logging.getLogger('mylibB').addHandler(logging.StreamHandler())
Also, you'd have no issue running multiple apps concurrently with each collecting, processing and formatting the logs in a way that's relevent for each app.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论