一个简单的兼容 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 的字符串表示形式。