View Source Logger.Formatter (Logger v1.16.0)
Conveniences and built-in formatter for logs.
This modules defines a suitable :logger
formatter which formats
messages and reports as Elixir terms and also provides additional
functionality, such as timezone conversion, truncation, and coloring.
This formatter is used by default by Logger
and you can configure it
using:
config :logger, :default_formatter,
format: "\n$time $metadata[$level] $message\n",
metadata: [:user_id]
See Logger.Formatter.new/1
for all configuration options.
You can also build your own instances of this formatter by calling
new/1
and setting at the formatter of any :logger
handler by
settings its :formatter
key to Logger.Formatter.new(options)
.
This module also provides several conveniences for those who wish to write their custom logger formatters.
Formatting
The log messages can be controlled by a formatting string. Here is an example:
config :logger, :default_formatter,
format: "\n$time $metadata[$level] $message\n",
metadata: [:user_id]
The above will print error messages as:
18:43:12.439 user_id=13 [error] Hello\n
The valid parameters you can use are:
$time
- the time the log message was sent$date
- the date the log message was sent$message
- the log message$level
- the log level$node
- the node that prints the message$metadata
- user controlled data presented in"key=val key2=val2 "
format
Formatting function
You can also customize the format of your log messages with
a {module, function_name}
tuple if you wish to change how messages
are formatted but keep all other features provided by Logger.Formatter
such as truncation and coloring. However, if you want to get full
control of formatting, consider writing a custom
:logger
formatter
instead, which has complete access to all events and metadata.
When using a {module, function_name}
, the function will be invoked
with the level, the message, the timestamp, and metadata, like this:
defmodule MyConsoleLogger do
@spec format(atom, chardata, Logger.Formatter.date_time_ms(), keyword()) :: IO.chardata()
def format(level, message, timestamp, metadata) do
# Custom formatting logic that must return chardata.
# ...
end
end
Metadata
Metadata to be sent to the logger can be read and written with
the Logger.metadata/0
and Logger.metadata/1
functions. For example,
you can set Logger.metadata([user_id: 13])
to add user_id metadata
to the current process. The user can configure the backend to choose
which metadata it wants to print and it will replace the $metadata
value.
Summary
Functions
Compiles a pattern or function into a data structure that format/5
can handle.
Formats a pattern_or_function
returned by compile/1
.
Formats date as chardata.
Formats the message of a log event.
Formats time as chardata.
Initializes a formatter for :logger
handlers.
Prunes invalid Unicode code points from lists and invalid UTF-8 bytes.
Converts the system time (in microseconds) from metadata into a date_time_ms
tuple.
Truncates a chardata
into n
bytes.
Types
@type date() :: {1970..10000, 1..12, 1..31}
@type pattern() :: :date | :level | :levelpad | :message | :metadata | :node | :time
@type time_ms() :: {0..23, 0..59, 0..59, 0..999}
Functions
@spec compile(binary() | nil) :: [pattern() | binary()]
@spec compile(pattern) :: pattern when pattern: {module(), function :: atom()}
Compiles a pattern or function into a data structure that format/5
can handle.
Check the module doc for documentation on the valid parameters that
will be interpolated in the pattern. If you pass nil
as the pattern,
the pattern defaults to:
"\n$time $metadata[$level] $message\n"
If you want to customize formatting with a custom function, you can
pass a {module, function_name}
tuple.
This function, alongside format/5
, is the main building block used
by Logger.Formatter.new/1
for formatting messages. It can also be used
by those interested in building custom formatters.
Examples
iex> Logger.Formatter.compile("$time $metadata [$level] $message\n")
[:time, " ", :metadata, " [", :level, "] ", :message, "\n"]
iex> Logger.Formatter.compile({MyLoggerFormatter, :format})
{MyLoggerFormatter, :format}
@spec format( mod_and_fun | [pattern() | binary()], Logger.level(), Logger.message(), date_time_ms(), keyword() ) :: IO.chardata() when mod_and_fun: {atom(), atom()}
Formats a pattern_or_function
returned by compile/1
.
It takes a compiled format and injects the level, timestamp, message, and metadata keyword list and returns a properly formatted string.
If pattern_or_function
is a {module, function_name}
tuple,
then module.function_name(level, message, timestamp, metadata)
is
invoked to get the message.
This function, alongside compile/1
, is the main building block used
by Logger.Formatter.new/1
for formatting messages. It can also be used
by those interested in building custom formatters.
Examples
iex> pattern = Logger.Formatter.compile("[$level] $message")
iex> timestamp = {{1977, 01, 28}, {13, 29, 00, 000}}
iex> formatted = Logger.Formatter.format(pattern, :info, "hello", timestamp, [])
iex> IO.chardata_to_string(formatted)
"[info] hello"
@spec format_date(date()) :: IO.chardata()
Formats date as chardata.
@spec format_event(:logger.log_event(), pos_integer() | :infinity) :: IO.chardata()
Formats the message of a log event.
@spec format_time(time_ms()) :: IO.chardata()
Formats time as chardata.
Initializes a formatter for :logger
handlers.
The supported options are:
:colors
- a keyword list of coloring options.:format
- the format message used to print logs. Defaults to:"\n$time $metadata[$level] $message\n"
. It may also be a{module, function_name}
tuple that is invoked with the log level, the message, the current timestamp and the metadata and must returnIO.chardata/0
. See the module docs for more information on:format
.:metadata
- the metadata to be printed by$metadata
. Defaults to an empty list (no metadata). Setting:metadata
to:all
prints all metadata. See the "Metadata" section in theLogger
documentation for more information.:truncate
- the maximum message size to be logged (in bytes). Defaults to 8192 bytes. Note this configuration is approximate. Truncated messages will have" (truncated)"
at the end. The atom:infinity
can be passed to disable this behavior.:utc_log
- whentrue
, uses UTC in logs. By default it uses local time (as it defaults tofalse
).
The supported keys in the :colors
keyword list are:
:enabled
- boolean value that allows for switching the coloring on and off. Defaults to:IO.ANSI.enabled?/0
:debug
- color for debug messages. Defaults to::cyan
:info
- color for info and notice messages. Defaults to::normal
:warning
- color for warning messages. Defaults to::yellow
:error
- color for error and higher messages. Defaults to::red
See the IO.ANSI
module for a list of colors and attributes.
The color of the message can also be configured per message via
the :ansi_color
metadata.
@spec prune(IO.chardata()) :: IO.chardata()
Prunes invalid Unicode code points from lists and invalid UTF-8 bytes.
Typically called after formatting when the data cannot be printed.
@spec system_time_to_date_time_ms(integer(), boolean()) :: date_time_ms()
Converts the system time (in microseconds) from metadata into a date_time_ms
tuple.
@spec truncate(IO.chardata(), non_neg_integer() | :infinity) :: IO.chardata()
Truncates a chardata
into n
bytes.
There is a chance we truncate in the middle of a grapheme cluster but we never truncate in the middle of a binary code point. For this reason, truncation is not exact.