logger_filters(3)

πŸ“¦
version 29.0.6 Β· 3 versions
, in ubuntu stonking

πŸ’– logger_filters β€” bestie, it's filter time πŸ’–

okay so you know how this is logger_filters from the Erlang kernel module docs? yeah. we're doing this. it's a module (not a program, bestie, don't run it in your shell, run it in your code), and it's lowkey the most useful little helper for Logger filters. let's get into it 🫢


✨ NAME ✨

logger_filters β€” filters to use with Logger. periodt. πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so, every single function exported from this module? you can use it as a primary filter or a handler filter. slay.

if you wanna know how filters actually get added to the world, go peek at logger:add_primary_filter/2 and logger:add_handler_filter/3. those are the ✨how do I even attach this thing✨ docs.

and when you're done with a filter and you want it GONE? that's logger:remove_primary_filter/1 and logger:remove_handler_filter/2. bye bestie πŸ‘‹

🌸 See Also 🌸

  • logger

πŸ”₯ FUNCTIONS πŸ”₯

πŸ’œ domain(LogEvent, Extra) -> logger:filter_return()

domain(LogEvent, Extra) -> logger:filter_return()
                when
                    LogEvent :: logger:log_event(),
                    Extra :: {Action, Compare, MatchDomain},
                    Action :: log | stop,
                    Compare ::
                        super | sub | equal | not_equal | undefined,
                    MatchDomain :: [atom()].

this one is the domain girlie ✨ it lets you filter log events by a domain field in Metadata. that field is optional btw, and the whole point of it is to group log events from β€” say β€” one specific functional area. that way a Logger handler can filter them, or give them some other specialized treatment. chef's kiss.

a domain field has to be a list of atoms, and the longer that list gets, the smaller and more specialized the domain becomes. the greatest domain is [], which literally contains all possible domains. it's the main character, fr.

for example, consider these domains:

D1 = [otp]
D2 = [otp, sasl]

D1 is the greatest one of the two, and it's said to be a super-domain of D2. D2 is a sub-domain of D1. and both D1 and D2 are sub-domains of []. the hierarchy ate, honestly.

those domains up there are the ones used for logs coming out of Erlang/OTP. D1 means the log event came from Erlang/OTP in general, and D2 means the log event is a so-called SASL report. iykyk.

the Extra parameter you pass to domain/2 gets specified when you add the filter via logger:add_primary_filter/2 or logger:add_handler_filter/3.

so the filter compares the value of the domain field in the log event's metadata (Domain) against MatchDomain. and it matches if the value of Compare is:

  • sub β€” when Domain is equal to, or a sub-domain of, MatchDomain. that is, if MatchDomain is a prefix of Domain. πŸŽ€
  • super β€” when Domain is equal to, or a super-domain of, MatchDomain. that is, if Domain is a prefix of MatchDomain. πŸ‘‘
  • equal β€” when Domain is equal to MatchDomain. ✨
  • not_equal β€” when Domain differs from MatchDomain, or if there's no domain field in the metadata. πŸ’€
  • undefined β€” when there's no domain field in the metadata. and heads up: in this case MatchDomain must be set to [].

if the filter matches and Action is log, the log event is allowed. if the filter matches and Action is stop, the log event is stopped. simple as.

and if the filter does not match, it returns ignore β€” meaning other filters, or the value of the config parameter filter_default, get to decide whether the event is allowed or not. not me being indecisive πŸ™ˆ

log events that don't contain any domain field match only when Compare is equal to undefined or not_equal. no cap.

example: stop all events with domain [otp, sasl | _]

1> logger:set_handler_config(h1, filter_default, log). % this is the default
ok
2> Filter = {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}.
3> logger:add_handler_filter(h1, no_sasl, Filter).
ok

🌈 level(LogEvent, Extra) -> logger:filter_return()

level(LogEvent, Extra) -> logger:filter_return()
                when
                    LogEvent :: logger:log_event(),
                    Extra :: {Action, Operator, MatchLevel},
                    Action :: log | stop,
                    Operator :: neq | eq | lt | gt | lteq | gteq,
                    MatchLevel :: logger:level().

this one filters log events based on the log level. it matches log events by comparing the log level against a specified MatchLevel.

the Extra parameter gets specified when you add the filter via logger:add_primary_filter/2 or logger:add_handler_filter/3. same deal as before bestie.

so the filter compares the value of the event's log level (Level) to MatchLevel by calling logger:compare_levels(Level, MatchLevel). and it matches if the value of Operator is:

  • neq β€” and the compare function returns lt or gt. πŸ“
  • eq β€” and the compare function returns eq. πŸ’–
  • lt β€” and the compare function returns lt. 🌸
  • gt β€” and the compare function returns gt. πŸ”₯
  • lteq β€” and the compare function returns lt or eq. πŸ¦‹
  • gteq β€” and the compare function returns gt or eq. ⭐

if the filter matches and Action is log, the log event is allowed. if the filter matches and Action is stop, the log event is stopped.

if the filter does not match, it returns ignore β€” meaning other filters, or the value of the config parameter filter_default, get to decide if the event is allowed or not. (the drama of delegation πŸ’…)

example: only allow debug level log events

logger:set_handler_config(h1, filter_default, stop).
Filter = {fun logger_filters:level/2, {log, eq, debug}}.
logger:add_handler_filter(h1, debug_only, Filter).
ok

🧚 progress(LogEvent, Extra) -> logger:filter_return()

progress(LogEvent, Extra) -> logger:filter_return()
                    when
                        LogEvent :: logger:log_event(),
                        Extra :: log | stop.

this filter matches all progress reports from supervisor and application_controller. that's literally all it does and honestly? iconic. focused. knows its lane.

if Extra is log, the progress reports are allowed. if Extra is stop, the progress reports are stopped.

for all other log events, the filter returns ignore. not your girl, not my problem πŸ™…β™€οΈ


πŸŽ€ remote_gl(LogEvent, Extra) -> logger:filter_return()

remote_gl(LogEvent, Extra) -> logger:filter_return()
                     when
                         LogEvent :: logger:log_event(),
                         Extra :: log | stop.

this filter matches all events originating from a process that has its group leader on a remote node. fancy, right? ✨

if Extra is log, the matching events are allowed. if Extra is stop, the matching events are stopped.

and yes, for all other log events it returns ignore. same energy as progress/2, different vibe check.


reminder bestie: filters don't do anything sitting pretty in your code. add them with logger:add_primary_filter/2 or logger:add_handler_filter/3, and yeet them with logger:remove_primary_filter/1 or logger:remove_handler_filter/2. πŸ’–

and that's the whole page!! written by Ericsson AB, this is kernel 11.0.3, and the man page is logger_filters(3). go forth and filter, you absolute queen πŸ‘‘βœ¨πŸ’…

πŸ“¦ where this page comes from