5

Python logger 问题请教 - V2EX

 2 years ago
source link: https://www.v2ex.com/t/802892
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  Python

Python logger 问题请教

  zxCoder · 13 小时 44 分钟前 · 696 次点击

我希望在任何一个单独的 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

ch2   12 小时 47 分钟前

单例模式了解一下

zeroxia

zeroxia   11 小时 16 分钟前

不确定 ·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

RBQ2012   7 小时 39 分钟前   ❤️ 1

也可以考虑换 `loguru`

icylogic

icylogic   3 小时 38 分钟前 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

xmtpw   36 分钟前 via iPhone

loguru

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK