From 2e43c071a98475e8ec3df16d95eff11852a46a6d Mon Sep 17 00:00:00 2001 From: Jon Carstens Date: Tue, 26 Sep 2023 10:02:47 -0600 Subject: [PATCH] Fix loading history when multiple buffers in config When starting the RingLogger backend, the `RingLogger.Server` loads any history from a persistence file during init, then configures the Server after successfully starting up. However, the configure action was destructive and would reset all the buffers which were just loaded if you happened to have buffer configuration. This fixes that to reload any existing buffer back into the newly configured ones so that history would not be lost when adjusting minor configuration --- lib/ring_logger/server.ex | 5 ++++ test/ring_logger_test.exs | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/lib/ring_logger/server.ex b/lib/ring_logger/server.ex index c3e584e..d6399c6 100644 --- a/lib/ring_logger/server.ex +++ b/lib/ring_logger/server.ex @@ -137,6 +137,8 @@ defmodule RingLogger.Server do end def handle_call({:configure, opts}, _from, state) do + logs = merge_buffers(state) + state = case Keyword.get(opts, :max_size) do nil -> @@ -155,6 +157,9 @@ defmodule RingLogger.Server do %__MODULE__{state | buffers: reset_buffers(buffers)} end + # Reinsert old buffers to let new max size filter out + state = Enum.reduce(logs, state, &insert_log(&2, &1)) + {:reply, :ok, state} end diff --git a/test/ring_logger_test.exs b/test/ring_logger_test.exs index 8ee4213..720215e 100644 --- a/test/ring_logger_test.exs +++ b/test/ring_logger_test.exs @@ -759,6 +759,60 @@ defmodule RingLoggerTest do File.rm!("test/persistence.log") end + test "loading the log with multiple buffers", %{io: io} do + Logger.remove_backend(RingLogger) + + logs = [ + %{ + level: :debug, + module: Logger, + message: "Foo", + timestamp: {{2023, 2, 8}, {13, 58, 31, 343}}, + metadata: [] + }, + %{ + level: :debug, + module: Logger, + message: "Bar", + timestamp: {{2023, 2, 8}, {13, 58, 31, 344}}, + metadata: [] + }, + %{ + level: :info, + module: Logger, + message: "Baz", + timestamp: {{2023, 2, 8}, {13, 58, 31, 345}}, + metadata: [] + } + ] + + :ok = Persistence.save("test/persistence.log", logs) + + # Start the backend with _just_ the persist_path and restore old + # config to allow other tests to run without loading a log file + old_env = Application.get_env(:logger, RingLogger) + + new_env = [ + persist_path: "test/persistence.log", + max_size: 3, + buffers: %{debug: %{levels: [:debug], max_size: 2}} + ] + + Application.put_env(:logger, RingLogger, new_env) + Logger.add_backend(RingLogger) + Application.put_env(:logger, RingLogger, old_env) + + Logger.add_backend(RingLogger) + + :ok = RingLogger.attach(io: io) + + buffer = RingLogger.get(0, 0) + + assert Enum.count(buffer) == 3 + + File.rm!("test/persistence.log") + end + test "loading a corrupted file", %{io: io} do Logger.remove_backend(RingLogger)