日志记录¶
Mach 配置了一个内置的日志记录功能,以便命令可以轻松地记录数据。
与您见过的多数日志记录器不同,此日志记录功能鼓励结构化日志记录。它不是记录简单的字符串,而是使用以下信息记录所有事件:
一个字符串 action(操作)
一个包含日志消息字段的字典
一个格式化字符串
从本质上讲,您不是在日志记录时组装一个人类可读的字符串,而是创建一个对象,其中包含构成已记录事件的所有数据片段。对于每种类型的已记录事件,您都会分配一个 action 名称。
根据日志记录的配置方式,已记录的事件可能会以两种不同的方式写入。
JSON 日志记录¶
当机器是日志数据的目标时,会配置一个 JSON 日志记录器。JSON 日志记录器会组装一个数组,其中包含以下元素:
自 UNIX 纪元以来的十进制挂钟时间(以秒为单位)
消息的字符串 action(操作)
包含结构化消息数据的对象
JSON 序列化后的数组将写入已配置的文件句柄。此日志记录流的使用者只需执行 readline(),然后将其提供给 JSON 反序列化器即可重建原始的已记录消息。他们可以使用 action 元素确定如何处理各个事件。无需发明解析器。很方便,不是吗?
面向人类的日志记录¶
当人类是日志消息的目标使用者时,结构化日志消息将转换为更易于人类理解的形式。这是通过利用日志记录时提供的 formatting(格式化)字符串来实现的。日志记录器只需调用格式化字符串的 format 方法,并将包含消息字段的字典传递给它。
当 mach 在支持它的终端中使用时,日志记录功能还支持终端功能(例如颜色)。这在日志记录层自动完成 - 无需在日志记录时控制它。
此外,面向人类的消息通常会在每一行前面加上自应用程序启动以来经过的时间。
日志记录指南¶
结构化日志记录利用了 Python 内置的日志记录基础设施(由 logging 包提供)。我们通过利用 logging.Logger.log() 的 extra 参数来实现这一点。我们将包含 action 和 params 字段的字典传递给此参数。它们分别是字符串 action 和消息字段的字典。格式化字符串像往常一样作为 msg 参数传递。
如果您直接记录到日志记录器,则操作如下:
logger.log(logging.INFO, 'My name is {name}',
extra={'action': 'my_name', 'params': {'name': 'Gregory'}})
JSON 日志记录将生成如下内容:
[1339985554.306338, "my_name", {"name": "Gregory"}]
面向人类的日志记录将生成如下内容:
0.52 My name is Gregory
由于直接使用 logger.log 存在很多复杂性,因此建议通过一个包装层来隐藏部分复杂性。最简单的方法是利用 LoggingMixin。
import logging
from mach.mixin.logging import LoggingMixin
class MyClass(LoggingMixin):
def foo(self):
self.log(logging.INFO, 'foo_start', {'bar': True},
'Foo performed. Bar: {bar}')