Koszal
How to log to stderr?
I am trying to write log messages to stderr (rather than to stdout). However, the obvious thing (device: :standard_error) seems to have no effect. In the following one-liner the log output is still written to stdout.
$ elixir -e 'require Logger; Logger.configure_backend(:console, device: :standard_error); Logger.error("why stdout?")' 2>/dev/null
20:41:11.210 [error] why stdout?
Am I missing something obvious?
I wanted to create a script that writes something to stdout and then that something is piped into another program. Hence the logger must write to stderr (rather than stdout).
Koszal
Most Liked
dwark
There have been indeed some changes to Elixir’s Logger since v1.15.0:
[Logger] The :console configuration has been deprecated in favor of :default_formatter
[Logger] The :backends configuration has been deprecated in favor of Logger.add_handlers/1
Logger now uses :logger’s default handler and refers to the logger_std_h documentation, which states:
type = io:standard_io/0 | io:standard_error/0 | file | {device, io:device/0 } - Specifies the log destination.
The value is set when the handler is added, and it cannot be changed in runtime.
Defaults to standard_io, unless parameter file is given, in which case it defaults to file.
So once the require Logger is excuted in the one-liner, the default handler will have been added and its device cannot be changed during runtime. And looking at the actual
configuration of the default handler:
elixir -e 'require Logger; :logger.get_handler_config(:default) |> IO.inspect(); Logger.error("why stdout?")' 2>scr/delme
{:ok,
%{
id: :default,
module: :logger_std_h,
config: %{
type: :standard_io,
burst_limit_enable: true,
drop_mode_qlen: 200,
flush_qlen: 1000,
sync_mode_qlen: 10,
overload_kill_restart_after: 5000,
burst_limit_max_count: 500,
burst_limit_window_time: 1000,
overload_kill_enable: false,
overload_kill_mem_size: 3000000,
overload_kill_qlen: 20000,
filesync_repeat_interval: :no_repeat
},
level: :all,
filters: [remote_gl: {&:logger_filters.remote_gl/2, :stop}],
filter_default: :log,
formatter: {Logger.Formatter,
%Logger.Formatter{
template: ["\n", :time, " ", :metadata, "[", :level, "] ", :message, "\n"],
truncate: 8096,
metadata: [],
colors: %{
error: :red,
enabled: true,
info: :normal,
warning: :yellow,
debug: :cyan,
notice: :normal,
alert: :red,
critical: :red,
emergency: :red
},
utc_log?: false
}}
}}
08:53:01.187 [error] why stdout?
it is indeed using stdio.
hauleth
It is possible. You just need to add additional Logger backend that will filter messages to level :error or higher and output to stderr.
NobbZ
I took the freedom to edit some code fences in.
As this:
some text [ ]
renders into
some text
Where the is a clickable checkbox.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









