I don’t think the expectation is that existing logger backends are translated to :logger handlers. That’s exactly what the LoggerBackends library is there for – that you don’t need to do that.
You want to look at :logger handlers for any new stuff however, because it’s available OTP wide (not limited to elixir) and the primary documented path based on elixirs docs as well.
This is my mental model of current state of the loggers:
- Logger handlers is the main interface for logging
- Logger handlers are recommended to support something called “overload protection”
- The default
:logger_std_h
handler does have an overload protection
- If you want to write a custom handler, you’ll have to implement overload protection, like for example, Sentry handler does.
- LoggerBackends is a logger handler which allows you to write logger backends which is a concept unique to this package. Custom backends won’t need overload protection as they are not logger handlers.
So my rule of thumb is as follow: logger handlers that implement overload protection can be all used as handlers alongside each other:
config :my_app, :logger, [
{:handler, :file_log, :logger_std_h, ...},
{:handler, :sentry, Sentry.LoggerHandler, ...}
]
Whenever you want a custom logger but don’t want to implement overload protection, you can take advantage of LoggerBackends and write a custom logger backend instead.
In reality, I’ve yet to find myself writing a custom handler as the built-in :logger_std_h
in combination with filters and formatters is very very flexible. So flexible, in fact, that LoggerJSON
project was completely rewritten from being a logger backend to being a formatter.
5 Likes
Aaaaah, that makes sense! I could have implemented my example (file logger) using the logger_std_h
handler indeed. So, the idea here is to rather configure the existing logger_std_h
or logger_disk_log_h
implementations unless you need something special, but which doesn’t need overload protection. In that case, you can use the LoggerBackends
library. Thanks for the clarification!
Just for future reference, I managed to implement a logger_handler
myself, but it’s terrible and shouldn’t be used except for inspiration for how to use e.g. :logger_formatter
, how to convert the old format
-option to the new template
-option, or how to convert the gregorian microsecond timestamp of the new log_event
back to date and time.
It’s on GitHub here: run-elixir/assets/archived_code/file_logger.ex at main · PJUllrich/run-elixir · GitHub
And I also implemented an “old” handler, which you should now add using the LoggerBackends.add/2
function instead of the deprecated Logger.add_backend/2
function. It’s on GitHub here: run-elixir/assets/archived_code/old_file_logger.ex at main · PJUllrich/run-elixir · GitHub
5 Likes
Elixir provides with Logger.Formatter that allows to define formatter the same way as we used to do for LoggerBackends. See the section: formatting function.
In one project I’m working on there was a custom formatter used and that Logger.Formatter allowed to migrate to new :logger
without any change to the formatter.
1 Like