日志记录与打印()+记录最佳实践的优点

时间:2012-05-20 22:21:09

标签: python logging

我目前正致力于pyftpdlib模块的1.0.0版本。 这个新版本将引入一些向后不兼容的变化 某些API将不再接受字节而是unicode。 虽然我在这里,作为这个包装的一部分,我正在考虑 摆脱目前使用的日志功能的可能性 print语句,改为使用日志记录模块。

截至目前,pyftpdlib将日志记录委托给3个函数:

def log(s):
   """Log messages intended for the end user."""
   print s

def logline(s):
   """Log commands and responses passing through the command channel."""
   print s

def logerror(s):
   """Log traceback outputs occurring in case of errors."""
   print >> sys.stderr, s

愿意自定义日志的用户(例如将其写入文件)是 应该只是覆盖这三个函数:

>>> from pyftpdlib import ftpserver
>>>
>>> def log2file(s):
...        open('ftpd.log', 'a').write(s)
...
>>> ftpserver.log = ftpserver.logline = ftpserver.logerror = log2file

现在我想知道:摆脱这种方法意味着什么好处 而是使用日志模块? 从模块供应商的角度来看,我应该如何 在我的模块中公开日志功能? 我应该这样做:

import logging
logger = logging.getLogger("pyftpdlib")

...并在我的文档中说明"记录器"是所谓的对象 用于用户想要自定义日志行为的方式? 故意设置预定义的格式输出是合法的,如下所示:

FORMAT = '[%(asctime)] %(message)s'
logging.basicConfig(format=FORMAT)
logger = logging.getLogger('pyftpdlib')

...

你能想到第三方模块我可以从日志功能作为公共API的一部分公开和整合的地方获取线索吗?

提前致谢。

4 个答案:

答案 0 :(得分:3)

库(ftp服务器或客户端库)永远不应该初始化日志记录系统。 所以可以实例化一个记录器对象并指向中的logging.basicConfig 文档(或提供与basicConfig相关的函数和更高级的输出 并让用户在他的日志配置策略中选择plain basicConfig或 库提供的配置)

框架(例如django)或服务器(ftp服务器守护程序) 应该将日志系统初始化为合理的 默认并允许自定义日志记录系统配置。

答案 1 :(得分:2)

通常,库应该只创建一个NullHandler处理程序,它只是一个什么都不做的处理程序。然后,使用您的库的最终用户或应用程序开发人员可以配置日志记录系统。有关详细信息,请参阅logging文档中的Configuring Logging for a Library部分。特别是,请参阅开头的说明

  

强烈建议您不要将NullHandler以外的任何处理程序添加到图书馆的记录器中。

在您的情况下,我只是根据日志记录文档创建一个日志处理程序,

import logging
logging.getLogger('pyftpdlib').addHandler(logging.NullHandler())

编辑问题中勾勒出的日志记录实现似乎非常合理。在您的文档中,只需提及logger并讨论或指向用户使用logging.setLevellogging.setFormatter方法来自定义库中的输出。您可以考虑使用logging.config.fileConfig管理输出设置并在文档中的某处记录配置文件,而不是使用logging.basicConfig(format=FORMAT),再次将用户指向日志模块文档,以获取此文件中预期的格式

答案 2 :(得分:0)

以下是我用于制作可自定义logger的资源。我没有太大变化,我只是添加了一个if语句,并传入我是否要记录到文件或只是控制台。

检查this Colorer。将输出着色非常好,因此DEBUG看起来与看起来与INFO不同的WARN不同。

Logging模块捆绑了许多不错的功能,例如SMTP日志记录,文件轮换日志记录(因此您可以保存几个旧的日志文件,但每次出错时都不能生成100个日志文件。)

如果您想迁移到Python 3,使用日志记录模块将无需更改打印语句。

根据您正在做的事情,记录非常棒,我之前只是轻松地使用它来查看我在程序中的位置(如果您正在运行此功能,请按照这种方式着色),但它具有更强大的功能而不是常规的印刷声明。

答案 3 :(得分:0)

你可以看看Django(只是创建一个示例项目)并看看它如何初始化logger子系统。

我前面还写了一个contextual logger helper - 这个记录器自动取名模块/类/函数的名称是从中初始化的。这对于调试消息非常有用,您可以在其中看到该模块直接发出消息以及调用流的方式。