How can I filter info message in log

I would like to filter out info message in console:

[info] TLS :server: In state :certify received CLIENT ALERT: Fatal - Certificate Unknown

I know it is a self issued cert, but it reminds me every sec upside_down_face:

If you are using Elixir 1.10+ then you can use filters. This is not documented perfectly, but this is fully stable solution:

def filter_function(%{level: :info, msg: {:string, msg}}, _) do
  if :unicode.characters_to_binary(msg) == "TLS :server: In state :certify received CLIENT ALERT: Fatal - Certificate Unknown" do
    :stop
  else
    :ignore
  end
end

:logger.add_primary_filter(:ignore_tls_message, {&filter_function/2, []})

You can optimise the filter_function if you know what line logs that message, then you can use metadata to filter out. For description of the first argument. you can check out Erlang docs.

2 Likes

Can regex be used with this method?

I tried to put:

:logger.add_primary_filter

before

Supervisor.start_link(children, opts)

but it does not filter the info msg.

It can happen as I was too strict in filter. Check what is the logged message and you can probably figure the filter value on your own. It was just an example.

@acrolink anything you like. Just beware that it should be as quick as possible as it will be fired for all messages that is over primary level. So if you regex will be fast enough, then it should be not much of the problem.

1 Like

It seems that function is not called. Where should :logger be configured / runtime.

What library is producing that log message? And what Elixir version are you using?

1 Like

Latest version Erlang/OTP 22. Probably web server is producing the error - server.

Elixir, not Erlang. For Erlang I am aware that you use OTP 21+ otherwise you wouldn’t be able to use :logger module at all.

Elixir 1.10.2

Message probably come from Erlang SSL.

I found now: Logger - error: {removed_failing_filter,ignore_tls_message}

1 Like

Ahhh… Yeah. I forgot to add, you also need to add “catch all” case for handling all other messages:

def filter_function(%{level: :info, msg: {:string, msg}}, _) do
  if :unicode.characters_to_binary(msg) == "TLS :server: In state :certify received CLIENT ALERT: Fatal - Certificate Unknown" do
    :stop
  else
    :ignore
  end
end

def filter_function(_, _), do: :ignore
3 Likes

Ok, I got it working. Logging level is :notice. Thank you for the solution.

def filter_function(%{level: :notice, msg: {:report, msg}}, _) do
    if :unicode.characters_to_binary(msg.protocol) == "TLS" do
      :stop
    else
      :ignore
    end
  end
3 Likes

Just beware that this still can fail if report will not contain :protocol key.

2 Likes

Yes I know, it is just temporary for not annoying me during development. Will remove later.

1 Like