Python logger 问题请教

2021-09-19 09:48:43 +08:00
 zxCoder

我希望在任何一个单独的 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
2309 次点击
所在节点    Python
5 条回复
ch2
2021-09-19 10:46:12 +08:00
单例模式了解一下
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
2021-09-19 15:53:42 +08:00
也可以考虑换 `loguru`
icylogic
2021-09-19 19:54:24 +08:00
你这相当于每次 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
2021-09-19 22:56:40 +08:00
loguru

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/802892

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX