一个简单的兼容 swift-log 的日志记录器,以 JSON 格式记录日志,每行一条记录。
在创建任何 logger 之前,使用 JSONLogger 引导 LoggingSystem
LoggingSystem.bootstrap(JSONLogger.init, metadataProvider: nil/* or whatever you want */)
要流式传输 JSONSeq (RFC 7464),您可以使用便捷的初始化器
LoggingSystem.bootstrap(JSONLogger.initForJSONSeq, metadataProvider: nil/* or whatever you want */)
JSONLogger 生成的 JSON 具有以下字段
level: 日志级别。值是 Logger.Level (trace, debug, info, notice, warning, error 或 critical)。message: 日志消息 (String 值)。metadata: 日志的结构化元数据 (JSON 对象值)。元数据值的结构尽可能保持不变。date 或 date-1970: 日志的日期。如果日志可以使用 JSONEncoder 正确编码,则会显示 date 字段,并且该值来自 encoder。如果编码日志时出现错误,则使用 date-1970 后备字段,其值为 Double,表示自 1970 年 1 月 1 日 (UNIX 时间) 以来的时间间隔。label: logger 的标签 (String 值)。source: 日志的来源 (String 值)。file: 生成日志的文件 (String 值)。function: 生成日志的函数 (String 值)。line: 生成日志的行号 (UInt 值)。JSON 应该不包含任何换行符,但是 JSONEncoder 不提供任何实际保证。 特别是,您可以配置 encoder 以漂亮地打印 JSON...
默认情况下,JSONLogger 将日志记录到 stdout。您可以在初始化时使用 fileHandle 参数将其配置为记录到任何文件描述符。
JSONLogger 允许您选择
[0x0a],即单个 UNIX 换行符);[]);[])。消息间分隔符在 JSON 消息之后记录,但仅在新消息到达时记录,而不是在每个 JSON 消息之后记录的后缀。
例如,如果您记录两条消息,您将获得以下输出
prefix JSON1 suffix separator prefix JSON2 suffix
一个有趣的配置是将前缀设置为 [0x1e],后缀设置为 [0x0a],这将生成 JSONSeq 流。
另一个有趣的配置是将 JSON 间分隔符设置为 [0xff] 或 [0xfe](或两者),并将前缀和后缀设置为空数组。0xff 和 0xfe 字节永远不应出现在有效的 UTF-8 字符串中,并且可以用于分隔 JSON 有效负载(JSON 需要 UTF-8 编码)。
我不确定 JSONSeq 为什么不这样做,但肯定有充分的理由(可能是因为生成的输出将不再是有效的 UTF-8)。
为了记录消息,JSONLogger 将为每条消息创建一个 LogLine 结构体,然后使用 JSONEncoder 对此结构体进行编码。
此 encoder 是可自定义的。
JSONLogger 生成的所有 JSON 消息都应该可以被与 encoder 配置匹配的 JSONDecoder 解码。
当编码日志行出现问题时(例如,日期格式化程序失败),JSONLogger 将回退到手动编码日志消息。
手动编码的 JSON 与正常输出略有不同
{
"JSONLogger.LogInfo": "Original metadata removed (see JSONLogger doc)",
"JSONLogger.LogError": ERROR_MESSAGE
}
MANGLED LOG MESSAGE (see JSONLogger doc) -- 为前缀;date 字段,而是有一个 date-1970 字段,其值是消息日期的 timeIntervalSince1970。这确保了消息的编码不会失败。修改后的日志消息仍然应该可以被 JSONEncoder 解析为 LogLine。
元数据条目的值的类型可以是 String、Array、Dictionary 或 any StringConvertible。
String、Array 和 Dictionary 类型可以直接在 JSON 消息中编码。
对于 string convertibles,如果存在 JSONEncoder/JSONDecoder 对,JSONLogger 将使用它们。encoder 将用于编码给定的对象,decoder 将用于将生成的 JSON 解码为通用的 JSON 对象,然后将其放入 LogLine 结构体中。
如果 encoder/decoder 对设置为 nil,则使用 string convertible 的字符串表示形式。