Blob Blame History Raw
From: Ulf Wiger <ulf@wiger.net>
Date: Sat, 5 Jun 2021 19:36:22 +0200
Subject: [PATCH] Add test and some documentation


diff --git a/README.md b/README.md
index a66302d..0dd7d0b 100644
--- a/README.md
+++ b/README.md
@@ -786,6 +786,15 @@ a black hole; nothing is passed through.  A filter of `{null, true}` means
 *everything* passes through. No other values for the null filter are valid and
 will be rejected.
 
+### Silencing filters
+A special log level, `silence` can be used together with a filter in order
+to suppress specific log output. This can be useful if a backend has been
+configured for a particular log level, but a particular set of log messages
+clutters the log. If these come from a dependency, they might be difficult
+to remove entirely, and it might not be desireable to do so in general.
+In such situations, a trace filter with log level `silence` can turn them
+off selectively, while letting other messages through as before.
+
 ### Multiple sink support
 
 If using multiple sinks, there are limitations on tracing that you
diff --git a/test/lager_trace_test.erl b/test/lager_trace_test.erl
index 48d722d..098d574 100644
--- a/test/lager_trace_test.erl
+++ b/test/lager_trace_test.erl
@@ -13,6 +13,7 @@
 -define(SECOND_LOG_ENTRY_TIMEOUT, 1000). % 1 second
 
 -define(FNAME, "test/test1.log").
+-define(FNAME2, "test/test2.log").
 
 trace_test_() ->
     {timeout,
@@ -48,7 +49,8 @@ trace_test_() ->
                  application:unset_env(lager, async_threshold),
                  error_logger:tty(true)
          end,
-         [{"Trace combined with log_root",
+         [
+          {"Trace combined with log_root",
              fun() ->
                  lager:info([{tag, mytag}], "Test message"),
 
@@ -75,6 +77,77 @@ trace_test_() ->
              end}
           ]}}.
 
+trace_silence_test_() ->
+    {timeout,
+     10,
+     {foreach,
+         fun() ->
+                 file:write_file(?FNAME2, ""),
+                 error_logger:tty(false),
+                 application:load(lager),
+                 application:set_env(lager, log_root, "test"),
+                 application:set_env(lager, handlers,
+                                     [{lager_file_backend,
+                                       [{file, "test2.log"},
+                                        {level, info},
+                                        {formatter, lager_default_formatter},
+                                        {formatter_config, [message, "\n"]}
+                                       ]}]),
+                 application:set_env(lager, traces,
+                                     [{{lager_file_backend, "test2.log"},
+                                       [{tag, silencetag}], silence}]),
+                 application:set_env(lager, error_logger_redirect, false),
+                 application:set_env(lager, async_threshold, undefined),
+                 lager:start()
+         end,
+         fun(_) ->
+                 file:delete(?FNAME2),
+                 application:stop(lager),
+                 application:stop(goldrush),
+                 application:unset_env(lager, log_root),
+                 application:unset_env(lager, handlers),
+                 application:unset_env(lager, traces),
+                 application:unset_env(lager, error_logger_redirect),
+                 application:unset_env(lager, async_threshold),
+                 error_logger:tty(true)
+         end,
+         [
+          {"Trace filter silences output",
+             fun() ->
+                 %% One message is supposed to get through, the other not
+                 lager:info([{tag, mytag}], "Test message"),
+                 lager:info([{tag, silencetag}], "This shouldn't get logged"),
+
+                 % Wait until we have the expected log entry in the log file.
+                 case wait_until(fun() ->
+                                         count_lines(?FNAME2) >= 1
+                                 end, ?FIRST_LOG_ENTRY_TIMEOUT) of
+                     ok ->
+                         ok;
+                     {error, timeout} ->
+                         throw({file_empty, file:read_file(?FNAME)})
+                 end,
+
+                 % Let's wait a little to see that we don't get a duplicate log
+                 % entry.
+                 case wait_until(fun() ->
+                                         count_lines(?FNAME2) >= 2
+                                 end, ?SECOND_LOG_ENTRY_TIMEOUT) of
+                     ok ->
+                         throw({too_many_entries, file:read_file(?FNAME)});
+                     {error, timeout} ->
+                         ok
+                 end,
+                 {ok, Bin} = file:read_file(?FNAME2),
+                 case Bin of
+                     <<"Test message\n">> ->
+                         ok;
+                     _ ->
+                         throw({unexpected_output_in_log, Bin})
+                 end
+             end}
+          ]}}.
+
 % Wait until Fun() returns true.
 wait_until(Fun, Timeout) ->
     wait_until(Fun, Timeout, {8, 13}).