I am deploying Phoenix v1.5.8 (Elixir 1.12.1)
on GCP and want to have my errors output to stderr
instead of stdout
.
The reason is because only then the GCP logger marks them as severity: "ERROR"
.
My config was looking as this
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id],
level: :info
This was sending all outputs to the stdout
including the crashes etc.
I added to it device: :standard_error
config :logger, :console,
format: "$time $metadata[$level] $message\n",
device: :standard_error,
metadata: [:request_id],
level: :info
However that start sending all logs to stderr
which marked everything as error in the GCP logger.
I ended up with simply having custom formatter
defmodule GCPLogFormatter do
def format(level, message, timestamp, metadata) do
format_and_log_error_to_stderr(level, message, timestamp, metadata)
rescue
_ -> "could not format: #{inspect({level, message, metadata})}"
end
defp format_and_log_error_to_stderr(:error, message, timestamp, metadata) do
str = logger_formatter(:error, message, timestamp, metadata)
log_to_stderr(str)
str
end
defp format_and_log_error_to_stderr(level, message, timestamp, metadata) do
logger_formatter(level, message, timestamp, metadata)
end
defp logger_formatter(level, message, timestamp, metadata) do
pattern = Logger.Formatter.compile("$time $metadata[$level] $message\n")
Logger.Formatter.format(
pattern,
level,
message,
timestamp,
metadata
)
|> IO.chardata_to_string()
end
defp log_to_stderr(text_payload) do
json =
%{"textPayload" => text_payload}
|> Jason.encode!()
IO.write(:stderr, json)
end
end
and using it in my config
config :logger, :console,
format: {GCPLogFormatter, :format},
metadata: [:request_id]
Is there way that I can config the logger per level
something which allow format: [info: "$time $metadata[$level] $message\n", error: {GCPLogFormatter, :format}]
?
From what I find nothing like this is possible.