Skip to content

Commit

Permalink
Expose all logger levels (#9791)
Browse files Browse the repository at this point in the history
  • Loading branch information
hauleth authored Feb 9, 2020
1 parent 6311832 commit 1fa3c45
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 81 deletions.
139 changes: 75 additions & 64 deletions lib/logger/lib/logger.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ defmodule Logger do
The `Logger.info/2` macro emits the provided message at the `:info`
level. Note the arguments given to `info/2` will only be evaluated
if a message is logged. For instance, if the Logger level is
set to `:warn`, `:info` messages are never logged and therefore the
arguments given above won't even be executed.
set to `:warning`, `:info` messages are never logged and therefore
the arguments given above won't even be executed.
There are additional macros for other levels.
Expand All @@ -44,17 +44,22 @@ defmodule Logger do
## Levels
The supported levels, ordered by precedence, are:
The supported levels, ordered by importance, are:
* `:debug` - for debug-related messages
* `:info` - for information of any kind
* `:warn` - for warnings
* `:emergency` - when system is unusable, panics
* `:alert` - for alerts, actions that must be taken immediately,
ex. corrupted database
* `:critical` - for critical conditions
* `:error` - for errors
* `:warning` - for warnings
* `:notice` - for normal, but signifant, messages
* `:info` - for information of any kind
* `:debug` - for debug-related messages
For example, `:info` takes precedence over `:debug`. If your log
level is set to `:info`, `:info`, `:warn`, and `:error` will be
printed to the console. If your log level is set to `:warn`, only
`:warn` and `:error` will be printed.
level is set to `:info`, `:info`, `:warning`, and all above it will
be passed to backends. If your log level is set to `:alert`, only
`:alert` and `:emergency` will be printed.
## Metadata
Expand Down Expand Up @@ -188,7 +193,12 @@ defmodule Logger do
* `:level` - the logging level. Attempting to log any message
with severity less than the configured level will simply
cause the message to be ignored. Keep in mind that each backend
may have its specific level, too.
may have its specific level, too. In addition to levels mentioned
above it also support 2 "meta-levels":
- `:all` - all messages will be logged, conceptualy identical to
`:debug`
- `:none` - no messages will be logged at all
* `:utc_log` - when `true`, uses UTC in logs. By default it uses
local time (i.e., it defaults to `false`).
Expand All @@ -214,9 +224,9 @@ defmodule Logger do
Defaults to 500 messages.
* `:discard_threshold_periodic_check` - a periodic check that
checks and reports if logger is discarding messages. It logs a warn
checks and reports if logger is discarding messages. It logs a warning
message whenever the system is (or continues) in discard mode and
it logs a warn message whenever if the system was discarding messages
it logs a warning message whenever if the system was discarding messages
but stopped doing so after the previous check. By default it runs
every `30_000` milliseconds.
Expand All @@ -229,7 +239,7 @@ defmodule Logger do
`config/config.exs` file:
config :logger,
level: :warn,
level: :warning,
truncate: 4096
### Erlang/OTP integration
Expand Down Expand Up @@ -341,11 +351,11 @@ defmodule Logger do
* `:debug` - color for debug messages. Defaults to: `:cyan`
* `:info` - color for info messages. Defaults to: `:normal`
* `:info` - color for info and notice messages. Defaults to: `:normal`
* `:warn` - color for warn messages. Defaults to: `:yellow`
* `:warn` - color for warning messages. Defaults to: `:yellow`
* `:error` - color for error messages. Defaults to: `:red`
* `:error` - color for error and higher messages. Defaults to: `:red`
See the `IO.ANSI` module for a list of colors and attributes.
Expand Down Expand Up @@ -403,7 +413,7 @@ defmodule Logger do
You can read more about formatting in `Logger.Formatter`, especially
if you want to support custom formatting in a custom backend.
### Custom backends
### Elixir custom backends
Any developer can create their own `Logger` backend. Since `Logger`
is an event manager powered by `:gen_event`, writing a new backend
Expand All @@ -428,7 +438,9 @@ defmodule Logger do
* `{level, group_leader, {Logger, message, timestamp, metadata}}` where:
* `level` is one of `:debug`, `:info`, `:warn`, or `:error`, as previously
described
described (for compatibility with pre 1.10 backends the `:notice` will
be translated to `:info` and all messages above `:error` will be translated
to `:error`)
* `group_leader` is the group leader of the process which logged the message
* `{Logger, message, timestamp, metadata}` is a tuple containing information
about the logged message:
Expand Down Expand Up @@ -508,8 +520,9 @@ defmodule Logger do
Erlang/OTP handlers must be listed under your own application:
config :my_app, :logger,
[:handler, :name_of_the_handler, ACustomHandler, configuration = %{}]
config :my_app, :logger, [
{:handler, :name_of_the_handler, ACustomHandler, configuration = %{}}
]
And then explicitly attached in your `c:Application.start/2` callback:
Expand All @@ -525,11 +538,12 @@ defmodule Logger do
been started, which means the configuration above would have no effect.
"""

@type level :: :error | :warn | :info | :debug
@type level ::
:emergency | :alert | :critical | :error | :warning | :warn | :notice | :info | :debug
@type backend :: :gen_event.handler()
@type message :: IO.chardata() | String.Chars.t()
@type metadata :: keyword()
@levels [:error, :warn, :info, :debug]
@levels [:emergency, :alert, :critical, :error, :warning, :notice, :info, :debug]

@metadata :logger_enabled
@compile {:inline, enabled?: 1}
Expand Down Expand Up @@ -622,7 +636,8 @@ defmodule Logger do
@spec level() :: level()
def level() do
%{level: level} = :logger.get_primary_config()
Logger.Handler.erlang_level_to_elixir_level(level)

level
end

@doc """
Expand Down Expand Up @@ -828,7 +843,7 @@ defmodule Logger do
:logger.macro_log(%{}, level, chardata, add_elixir_domain(metadata))
end

# # TODO: Remove that in Elixir 2.0
# TODO: Remove that in Elixir 2.0
def __do_log__(level, other, metadata) do
IO.warn("passing #{inspect(other)} to Logger is deprecated, expected a binary or an iolist")
:logger.macro_log(%{}, level, to_string(other), add_elixir_domain(metadata))
Expand All @@ -840,69 +855,65 @@ defmodule Logger do

defp add_elixir_domain(metadata), do: Map.put(metadata, :domain, [:elixir])

@doc """
Logs a warning message.
Returns `:ok`.
## Examples
Logger.warn("knob turned too far to the right")
"""
# TODO: Deprecate it in favour of `warning/1-2` macro
defmacro warn(chardata_or_fun, metadata \\ []) do
maybe_log(:warn, chardata_or_fun, metadata, __CALLER__)
end
messages = [
# Airplane 2
"We are also out of coffee",
# Red Alert 2
"Kirov reporting",
# Spies like us
"Doctor? Doctor",
# 2001: Space Odyssey
"I'm sory Dave",
# Lost in Space
"Danger, Will Robinson",
# The Graduate
"Mrs. Robinson, you are trying to seduce me",
# Dr. No
"Bond. James Bond.",
# A Bug's Life
"I'm the only stick with eyeballs"
]

@doc """
Logs an info message.
for {level, message} <- Enum.zip(@levels, messages) do
@doc """
Logs a #{level} message.
Returns `:ok`.
Returns `:ok`.
## Examples
## Examples
Logger.info("mission accomplished")
Logger.#{level}("#{message}")
"""
defmacro info(chardata_or_fun, metadata \\ []) do
maybe_log(:info, chardata_or_fun, metadata, __CALLER__)
"""
defmacro unquote(level)(chardata_or_fun, metadata \\ []) do
maybe_log(unquote(level), chardata_or_fun, metadata, __CALLER__)
end
end

@doc """
Logs an error message.
Logs a warning message.
Returns `:ok`.
## Examples
Logger.error("oops")
"""
defmacro error(chardata_or_fun, metadata \\ []) do
maybe_log(:error, chardata_or_fun, metadata, __CALLER__)
end

@doc """
Logs a debug message.
Returns `:ok`.
This macro is deprecated in favour of `warning/2`.
## Examples
Logger.debug("hello?")
Logger.warn("knob turned too far to the right")
"""
defmacro debug(chardata_or_fun, metadata \\ []) do
maybe_log(:debug, chardata_or_fun, metadata, __CALLER__)
# TODO: Hard deprecate it in favour of `warning/1-2` macro
defmacro warn(chardata_or_fun, metadata \\ []) do
maybe_log(:warning, chardata_or_fun, metadata, __CALLER__)
end

@doc """
Logs a message with the given `level`.
Returns `:ok`.
The macros `debug/2`, `warn/2`, `info/2`, and `error/2` are
The macros `debug/2`, `info/2`, `notice/2`, `warning/2`,
`error/2`, `critical/2`, `alert/2`, and `emergency/2` are
preferred over this macro as they can automatically eliminate
the call to `Logger` altogether at compile time if desired
(see the documentation for the `Logger` module).
Expand Down
22 changes: 11 additions & 11 deletions lib/logger/lib/logger/handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ defmodule Logger.Handler do

## Conversions

# TODO: Remove this mapping once we support all of Erlang types
def erlang_level_to_elixir_level(:none), do: :error
def erlang_level_to_elixir_level(:emergency), do: :error
def erlang_level_to_elixir_level(:alert), do: :error
def erlang_level_to_elixir_level(:critical), do: :error
def erlang_level_to_elixir_level(:error), do: :error
def erlang_level_to_elixir_level(:warning), do: :warn
def erlang_level_to_elixir_level(:notice), do: :info
def erlang_level_to_elixir_level(:info), do: :info
def erlang_level_to_elixir_level(:debug), do: :debug
def erlang_level_to_elixir_level(:all), do: :debug
# TODO: Remove this mapping once we support all of Erlang types (2.0)
defp erlang_level_to_elixir_level(:none), do: :error
defp erlang_level_to_elixir_level(:emergency), do: :error
defp erlang_level_to_elixir_level(:alert), do: :error
defp erlang_level_to_elixir_level(:critical), do: :error
defp erlang_level_to_elixir_level(:error), do: :error
defp erlang_level_to_elixir_level(:warning), do: :warn
defp erlang_level_to_elixir_level(:notice), do: :info
defp erlang_level_to_elixir_level(:info), do: :info
defp erlang_level_to_elixir_level(:debug), do: :debug
defp erlang_level_to_elixir_level(:all), do: :debug

# TODO: Warn on deprecated level
def elixir_level_to_erlang_level(:warn), do: :warning
Expand Down
Loading

0 comments on commit 1fa3c45

Please sign in to comment.