查看源代码 logger_formatter 行为 (内核 v10.2)

Logger 的默认格式化程序。

每个 Logger 处理程序都有一个配置的格式化程序,指定为模块和配置项。格式化程序的目的是将日志事件转换为最终可打印的字符串 (unicode:chardata()),该字符串可以写入处理程序的输出设备。有关更多信息,请参见内核用户指南中的处理程序格式化程序部分。

logger_formatter 是 Logger 使用的默认格式化程序。

另请参阅

calendarerror_loggerioio_libloggermapssasl(6)unicode

概要

类型

logger_formatter 的配置项是一个 map,以下键可以设置为配置参数

logger 格式化程序使用的模板。

回调:格式化程序回调函数

当设置或修改格式化程序配置时,Logger 会调用此函数。格式化程序必须验证给定的配置,如果正确则返回 ok,如果错误则返回 {error,Reason}

日志处理程序可以调用此函数,将日志事件项转换为可打印的字符串。例如,可以使用 io:put_chars/1,2 将返回值作为日志条目打印到控制台或文件。

函数

当设置或修改处理程序的格式化程序配置时,Logger 会调用此函数。如果配置有效,则返回 ok,如果配置错误,则返回 {error,term()}

这是从处理程序调用的格式化程序回调函数。

类型

链接到此类型

config()

查看源代码 (未导出) (自 OTP 21.0 起)
-type config() ::
          #{chars_limit => pos_integer() | unlimited,
            depth => pos_integer() | unlimited,
            legacy_header => boolean(),
            max_size => pos_integer() | unlimited,
            report_cb => logger:report_cb(),
            single_line => boolean(),
            template => template(),
            time_designator => byte(),
            time_offset => integer() | [byte()]}.

logger_formatter 的配置项是一个 map,以下键可以设置为配置参数

  • chars_limit = integer() > 0 | unlimited - 一个正整数,表示调用 io_lib:format/3 时要使用的同名选项的值。此值限制每个日志事件打印的总字符数。请注意,这是一个软限制。有关硬截断限制,请参见选项 max_size

    默认为 unlimited

  • depth = integer() > 0 | unlimited - 一个正整数,表示此格式化程序打印项的最大深度。传递给此格式化程序的格式字符串会被重写。格式控制 ~p 和 ~w 分别替换为 ~P 和 ~W,并且该值用作深度参数。有关详细信息,请参见 STDLIB 中的 io:format/2,3

    默认为 unlimited

  • legacy_header = boolean() - 如果设置为 true,则会在 Metadata 的 logger_formatter 部分添加一个标题字段。此字段的值是一个类似于旧的 error_logger 事件处理程序创建的标题的字符串。可以通过将列表 [logger_formatter,header] 添加到模板中,将其包含在日志事件中。有关更多信息,请参见 template/0 类型的描述。

    默认为 false

  • max_size = integer() > 0 | unlimited - 一个正整数,表示此格式化程序返回的字符串可以具有的绝对最大大小。如果格式化后的字符串在可能被 chars_limitdepth 限制后仍然更长,则会被截断。

    默认为 unlimited

  • report_cb = logger:report_cb/0 - 格式化程序使用报告回调函数将报告形式的日志消息转换为格式字符串和参数。可以在日志事件的元数据中指定报告回调函数。如果元数据中不存在报告回调函数,则 logger_formatter 将使用 logger:format_report/1 作为默认回调函数。

    如果设置了此配置参数,它将替换默认的报告回调函数和元数据中找到的任何报告回调函数。也就是说,所有报告都将由此配置的函数转换。

  • single_line = boolean() - 如果设置为 true,则每个日志事件都将打印为单行。为了实现这一点,logger_formatter 将格式字符串中所有 ~p~P 控制序列的字段宽度设置为 0(请参见 io:format/2),并将消息中的所有换行符替换为 ", "。换行符后面的空格将直接删除。请注意,template 参数添加的换行符不会被替换。

    默认为 true

  • template =template/0 - 模板描述如何通过组合日志事件中的不同数据值来构成格式化字符串。有关此的更多信息,请参见 template/0 类型的描述。

  • time_designator = byte() - 时间戳根据 RFC3339 格式化,时间指示符是用于分隔日期和时间的字符。

    默认为 $T

    此参数的值用作 calendar:system_time_to_rfc3339/2time_designator 选项。

  • time_offset = integer() | [byte()] - 时间偏移量,可以是字符串或整数,用于格式化时间戳。

    空字符串解释为本地时间。值 "Z""z"0 解释为协调世界时 (UTC)。

    "Z""z""" 之外的字符串必须采用 ±[hh]:[mm] 格式,例如 "-02:00""+00:00"

    整数必须以微秒为单位,这意味着偏移量 7200000000 等效于 "+02:00"

    默认为空字符串,表示时间戳以本地时间显示。但是,为了向后兼容,如果 SASL 配置参数 utc_log=true,则默认值将更改为 "Z",表示时间戳以 UTC 显示。

    此参数的值用作 calendar:system_time_to_rfc3339/2offset 选项。

链接到此类型

metakey()

查看源代码 (未导出) (自 OTP 21.0 起)
-type metakey() :: atom() | [atom()].
链接到此类型

template()

查看源代码 (未导出) (自 OTP 21.0 起)
-type template() :: [metakey() | {metakey(), template(), template()} | unicode:chardata()].

logger 格式化程序使用的模板。

模板是原子、原子列表、元组和字符串的列表。原子 levelmsg 分别被视为严重性级别和日志消息的占位符。其他原子或原子列表被解释为元数据的占位符,其中原子应匹配顶层键,原子列表表示元数据为嵌套映射时子键的路径。例如,列表 [key1,key2] 被下面嵌套映射中 key2 字段的值替换。原子 key1 本身被 key1 字段的完整值替换。这些值将转换为字符串。

#{key1 => #{key2 => my_value,
            ...}
  ...}

模板中的元组表示元数据键的 if-exist 测试。例如,以下元组表示如果元数据映射中存在 key1,则打印 "key1=Value",其中 Valuekey1 在元数据映射中关联的值。如果不存在 key1,则不打印任何内容。

{key1, ["key1=",key1], []}

模板中的字符串按字面意思打印。

template 配置参数的默认值取决于 single_linelegacy_header 配置参数的值,如下所示。

示例中使用的日志事件为

?LOG_ERROR("name: ~p~nexit_reason: ~p", [my_name, "It crashed"])
  • legacy_header = true, single_line = false - 默认模板:[[logger_formatter,header],"\n",msg,"\n"]

    示例日志条目

    =ERROR REPORT==== 17-May-2018::18:30:19.453447 ===
    name: my_name
    exit_reason: "It crashed"

    请注意,标题中可能会出现所有八个级别,而不仅仅是 error_logger 生成的 ERRORWARNINGINFO。并且微秒会添加到时间戳的末尾。

  • legacy_header = true, single_line = true - 默认模板:[[logger_formatter,header],"\n",msg,"\n"]

    请注意,这里的模板与 single_line=false 的模板相同,但生成的日志条目不同之处在于标题之后只有一行

    =ERROR REPORT==== 17-May-2018::18:31:06.952665 ===
    name: my_name, exit_reason: "It crashed"
  • legacy_header = false, single_line = true - 默认模板:[time," ",level,": ",msg,"\n"]

    示例日志条目

    2018-05-17T18:31:31.152864+02:00 error: name: my_name, exit_reason: "It crashed"
  • legacy_header = false, single_line = false - 默认模板:[time," ",level,":\n",msg,"\n"]

    示例日志条目

    2018-05-17T18:32:20.105422+02:00 error:
    name: my_name
    exit_reason: "It crashed"

回调:格式化程序回调函数

链接到此回调

check_config(Config)

查看源代码 (自 OTP 21.0 起)
-callback check_config(FConfig) -> ok | {error, Reason}
                          when FConfig :: logger:formatter_config(), Reason :: term().

当设置或修改格式化程序配置时,Logger 会调用此函数。格式化程序必须验证给定的配置,如果正确则返回 ok,如果错误则返回 {error,Reason}

以下 Logger API 函数可以触发此回调

有关示例实现,请参见 logger_formatterlogger_formatter 是 Logger 使用的默认格式化程序。

链接到此回调

format(LogEvent, Config)

查看源代码 (自 OTP 21.0 起)
-callback format(LogEvent, FConfig) -> FormattedLogEntry
                    when
                        LogEvent :: logger:log_event(),
                        FConfig :: logger:formatter_config(),
                        FormattedLogEntry :: unicode:chardata().

日志处理程序可以调用此函数,将日志事件项转换为可打印的字符串。例如,可以使用 io:put_chars/1,2 将返回值作为日志条目打印到控制台或文件。

有关示例实现,请参见 logger_formatterlogger_formatter 是 Logger 使用的默认格式化程序。

函数

链接到此函数

check_config(Config)

查看源代码 (自 OTP 21.0 起)
-spec check_config(Config) -> ok | {error, term()} when Config :: config().

当设置或修改处理程序的格式化程序配置时,Logger 会调用此函数。如果配置有效,则返回 ok,如果配置错误,则返回 {error,term()}

以下 Logger API 函数可以触发此回调

链接到此函数

format(LogEvent, Config)

查看源代码 (自 OTP 21.0 起)
-spec format(LogEvent, Config) -> unicode:chardata()
                when LogEvent :: logger:log_event(), Config :: config().

这是从处理程序调用的格式化程序回调函数。

日志事件的处理过程如下:

  • 如果消息是 report 形式,则通过调用 report 回调将其转换为 {Format,Args}。有关 report 回调和有效日志消息形式的更多信息,请参阅 Kernel 用户指南中的 日志消息 部分。
  • 消息大小受到配置参数 chars_limitdepth 的值限制。
  • 完整的日志条目根据 template 进行构建。
  • 如果最终字符串太长,则会根据配置参数 max_size 的值进行截断。