V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zxCoder
V2EX  ›  Python

Python logger 问题请教

  •  
  •   zxCoder · 2021-09-19 09:48:43 +08:00 · 2504 次点击
    这是一个创建于 1162 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我希望在任何一个单独的 py 文件里,通过文件名,就能获取到一个 logger,然后这个 logger 就能写入到这个文件里,互不影响

    我写了一个函数,但是发现每次获取到 logger,handlers 都是空的,然后每次都重新覆盖了一个文件

    def getTaskLogger(task_path: str) -> logging.Logger:
        logger = logging.getLogger(task_path)
        if logger.hasHandlers():
            return logger
        formatter = logging.Formatter("%(asctime)s | %(levelname)s | [%(filename)s:%(lineno)d] | %(message)s")
        f_handler = logging.FileHandler("{0}/task.log".format(task_path), mode="a")
        f_handler.setLevel(logging.DEBUG)
        f_handler.setFormatter(formatter)
        c_handler = logging.StreamHandler()
        c_handler.setLevel(logging.DEBUG)
        c_handler.setFormatter(formatter)
        logger.addHandler(f_handler)
        logger.addHandler(c_handler)
        logger.setLevel(logging.DEBUG)
        return logger
    
    5 条回复    2021-09-19 22:56:40 +08:00
    ch2
        1
    ch2  
       2021-09-19 10:46:12 +08:00
    单例模式了解一下
    zeroxia
        2
    zeroxia  
       2021-09-19 12:16:47 +08:00
    不确定 ·logging.getLogger· 是怎么处理参数和 logger 的对应的,但是你可以自己存下来吧。

    ```python
    def getTaskLogger(task_path: str) -> logging.Logger:
    if not hasattr(getTaskLogger, 'repo'):
    getTaskLogger.repo = {}
    if not task_path in getTaskLogger.repo:
    logger = logging.getLogger(task_path)
    formatter = logging.Formatter("%(asctime)s | %(levelname)s | [%(filename)s:%(lineno)d] | %(message)s")
    f_handler = logging.FileHandler("{0}/task.log".format(task_path), mode="a")
    f_handler.setLevel(logging.DEBUG)
    f_handler.setFormatter(formatter)
    c_handler = logging.StreamHandler()
    c_handler.setLevel(logging.DEBUG)
    c_handler.setFormatter(formatter)
    logger.addHandler(f_handler)
    logger.addHandler(c_handler)
    logger.setLevel(logging.DEBUG)
    return getTaskLogger.repo[task_path]
    ```

    这个功能也不用自己写,你可以考虑 `functools.cache`。
    RBQ2012
        3
    RBQ2012  
       2021-09-19 15:53:42 +08:00   ❤️ 2
    也可以考虑换 `loguru`
    icylogic
        4
    icylogic  
       2021-09-19 19:54:24 +08:00 via iPhone
    你这相当于每次 get 都重新 configure 了一遍,肯定不对啊。直接做成 logger per file/module 就可以了,然后提供一个通用的 configure helper 。
    参考 python logging howto

    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__)

    如果你有更高的需求,比如按照自定义的 logger 划分模式而不是 file/module,建议使用 service locator 来获取 logger,这种适合全局到处都在用又需要不同实现的服务,是相对安全和灵活的一种 pattern
    xmtpw
        5
    xmtpw  
       2021-09-19 22:56:40 +08:00 via iPhone
    loguru
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2743 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:13 · PVG 23:13 · LAX 07:13 · JFK 10:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.