Logger.Formatter — Logger v1.16.3

Search documentation of Logger

# View Source Logger.Formatter (Logger v1.16.3)

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

## Types

date()
date_time_ms()
pattern()
time_ms()

## Functions

compile(pattern_or_function)

Compiles a pattern or function into a data structure that `format/5` can handle.

format(pattern_or_function, level, message, timestamp, metadata)

Formats a `pattern_or_function` returned by `compile/1`.

format_date(date_tuple)

Formats date as chardata.

format_event(log_event, truncate)

Formats the message of a log event.

format_time(time_ms_tuple)

Formats time as chardata.

new(options \\ [])

Initializes a formatter for `:logger` handlers.

prune(binary)

Prunes invalid Unicode code points from lists and invalid UTF-8 bytes.

system_time_to_date_time_ms(system_time, utc_log? \\ false)

Converts the system time (in microseconds) from metadata into a `date_time_ms` tuple.

truncate(chardata, n)

Truncates a `chardata` into `n` bytes.

# Types

Link to this type

# date()

View Source

    @type date() :: {1970..10000, 1..12, 1..31}

Link to this type

# date_time_ms()

View Source

    @type date_time_ms() :: {date(), time_ms()}

Link to this type

# pattern()

View Source

    @type pattern() :: :date | :level | :levelpad | :message | :metadata | :node | :time

Link to this type

# time_ms()

View Source

    @type time_ms() :: {0..23, 0..59, 0..59, 0..999}

# Functions

Link to this function

# compile(pattern_or_function)

View Source

    @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}

Link to this function

# format(pattern_or_function, level, message, timestamp, metadata)

View Source

    @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"

Link to this function

# format_date(date_tuple)

View Source

    @spec format_date(date()) :: IO.chardata()

Formats date as chardata.

Link to this function

# format_event(log_event, truncate)

View Source

    @spec format_event(:logger.log_event(), pos_integer() | :infinity) :: IO.chardata()

Formats the message of a log event.

Link to this function

# format_time(time_ms_tuple)

View Source

    @spec format_time(time_ms()) :: IO.chardata()

Formats time as chardata.

Link to this function

# new(options \\ [])

View Source

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 return `IO.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 the `Logger` 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` - when `true`, uses UTC in logs. By default it uses local time (as it defaults to `false`).

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.

Link to this function

# prune(binary)

View Source

    @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.

Link to this function

# system_time_to_date_time_ms(system_time, utc_log? \\ false)

View Source

    @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.

Link to this function

# truncate(chardata, n)

View Source

    @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.