diff --git a/lib/logger_json.ex b/lib/logger_json.ex index 1eee956..31b1e0f 100644 --- a/lib/logger_json.ex +++ b/lib/logger_json.ex @@ -56,6 +56,10 @@ defmodule LoggerJSON do Some formatters require additional configuration options. Here are the options that are common for each formatter: + * `:encoder_opts` - options to be passed directly to the JSON encoder. This allows you to customize the behavior of the JSON + encoder. See the [documentation for Jason](https://hexdocs.pm/jason/Jason.html#encode/2-options) for available options. By + default, no options are passed to the encoder. + * `:metadata` - a list of metadata keys to include in the log entry. By default, no metadata is included. If `:all`is given, all metadata is included. If `{:all_except, keys}` is given, all metadata except the specified keys is included. diff --git a/lib/logger_json/formatter.ex b/lib/logger_json/formatter.ex index cdf1048..ca3a5fc 100644 --- a/lib/logger_json/formatter.ex +++ b/lib/logger_json/formatter.ex @@ -1,6 +1,7 @@ defmodule LoggerJSON.Formatter do @type opts :: [ - {:metadata, :all | {:all_except, [atom()]} | [atom()]} + {:encoder_opts, [Jason.encode_opt()]} + | {:metadata, :all | {:all_except, [atom()]} | [atom()]} | {:redactors, [{module(), term()}]} | {atom(), term()} ] diff --git a/lib/logger_json/formatters/basic.ex b/lib/logger_json/formatters/basic.ex index 76d433a..f14faf7 100644 --- a/lib/logger_json/formatters/basic.ex +++ b/lib/logger_json/formatters/basic.ex @@ -27,6 +27,7 @@ defmodule LoggerJSON.Formatters.Basic do @impl true def format(%{level: level, meta: meta, msg: msg}, opts) do opts = Keyword.new(opts) + encoder_opts = Keyword.get(opts, :encoder_opts, []) metadata_keys_or_selector = Keyword.get(opts, :metadata, []) metadata_selector = update_metadata_selector(metadata_keys_or_selector, @processed_metadata_keys) redactors = Keyword.get(opts, :redactors, []) @@ -48,7 +49,7 @@ defmodule LoggerJSON.Formatters.Basic do |> maybe_put(:request, format_http_request(meta)) |> maybe_put(:span, format_span(meta)) |> maybe_put(:trace, format_trace(meta)) - |> Jason.encode_to_iodata!() + |> Jason.encode_to_iodata!(encoder_opts) [line, "\n"] end diff --git a/lib/logger_json/formatters/datadog.ex b/lib/logger_json/formatters/datadog.ex index 87aa843..8b5bf98 100644 --- a/lib/logger_json/formatters/datadog.ex +++ b/lib/logger_json/formatters/datadog.ex @@ -51,6 +51,7 @@ defmodule LoggerJSON.Formatters.Datadog do @impl true def format(%{level: level, meta: meta, msg: msg}, opts) do opts = Keyword.new(opts) + encoder_opts = Keyword.get(opts, :encoder_opts, []) redactors = Keyword.get(opts, :redactors, []) hostname = Keyword.get(opts, :hostname, :system) @@ -77,7 +78,7 @@ defmodule LoggerJSON.Formatters.Datadog do |> maybe_merge(format_http_request(meta)) |> maybe_merge(encode(metadata, redactors)) |> maybe_merge(encode(message, redactors)) - |> Jason.encode_to_iodata!() + |> Jason.encode_to_iodata!(encoder_opts) [line, "\n"] end diff --git a/lib/logger_json/formatters/elastic.ex b/lib/logger_json/formatters/elastic.ex index 24ec3d4..0397942 100644 --- a/lib/logger_json/formatters/elastic.ex +++ b/lib/logger_json/formatters/elastic.ex @@ -144,6 +144,7 @@ defmodule LoggerJSON.Formatters.Elastic do @impl LoggerJSON.Formatter def format(%{level: level, meta: meta, msg: msg}, opts) do opts = Keyword.new(opts) + encoder_opts = Keyword.get(opts, :encoder_opts, []) metadata_keys_or_selector = Keyword.get(opts, :metadata, []) metadata_selector = update_metadata_selector(metadata_keys_or_selector, @processed_metadata_keys) redactors = Keyword.get(opts, :redactors, []) @@ -167,7 +168,7 @@ defmodule LoggerJSON.Formatters.Elastic do |> maybe_merge(format_http_request(meta)) |> maybe_put(:"span.id", format_span_id(meta)) |> maybe_put(:"trace.id", format_trace_id(meta)) - |> Jason.encode_to_iodata!() + |> Jason.encode_to_iodata!(encoder_opts) [line, "\n"] end diff --git a/lib/logger_json/formatters/google_cloud.ex b/lib/logger_json/formatters/google_cloud.ex index c4bae58..025c200 100644 --- a/lib/logger_json/formatters/google_cloud.ex +++ b/lib/logger_json/formatters/google_cloud.ex @@ -101,6 +101,7 @@ defmodule LoggerJSON.Formatters.GoogleCloud do @impl true def format(%{level: level, meta: meta, msg: msg}, opts) do opts = Keyword.new(opts) + encoder_opts = Keyword.get(opts, :encoder_opts, []) redactors = Keyword.get(opts, :redactors, []) service_context = Keyword.get_lazy(opts, :service_context, fn -> %{service: to_string(node())} end) project_id = Keyword.get(opts, :project_id) @@ -129,7 +130,7 @@ defmodule LoggerJSON.Formatters.GoogleCloud do |> maybe_put(:httpRequest, format_http_request(meta)) |> maybe_merge(encode(message, redactors)) |> maybe_merge(encode(metadata, redactors)) - |> Jason.encode_to_iodata!() + |> Jason.encode_to_iodata!(encoder_opts) [line, "\n"] end diff --git a/test/logger_json/formatters/basic_test.exs b/test/logger_json/formatters/basic_test.exs index d07f13c..520bd61 100644 --- a/test/logger_json/formatters/basic_test.exs +++ b/test/logger_json/formatters/basic_test.exs @@ -241,4 +241,14 @@ defmodule LoggerJSON.Formatters.BasicTest do } } end + + test "passing options to encoder" do + formatter = {Basic, encoder_opts: [pretty: true]} + :logger.update_handler_config(:default, :formatter, formatter) + + assert capture_log(fn -> + Logger.debug("Hello") + end) =~ + ~r/\n\s{2}"message": "Hello"/ + end end diff --git a/test/logger_json/formatters/datadog_test.exs b/test/logger_json/formatters/datadog_test.exs index 020e7e0..b59abff 100644 --- a/test/logger_json/formatters/datadog_test.exs +++ b/test/logger_json/formatters/datadog_test.exs @@ -413,4 +413,14 @@ defmodule LoggerJSON.Formatters.DatadogTest do } } = log_entry end + + test "passing options to encoder" do + formatter = {Datadog, encoder_opts: [pretty: true]} + :logger.update_handler_config(:default, :formatter, formatter) + + assert capture_log(fn -> + Logger.debug("Hello") + end) =~ + ~r/\n\s{2}"message": "Hello"/ + end end diff --git a/test/logger_json/formatters/elastic_test.exs b/test/logger_json/formatters/elastic_test.exs index 9d14720..15e5f34 100644 --- a/test/logger_json/formatters/elastic_test.exs +++ b/test/logger_json/formatters/elastic_test.exs @@ -444,4 +444,14 @@ defmodule LoggerJSON.Formatters.ElasticTest do assert String.starts_with?(origin_function, "test logs caught errors/1") assert String.starts_with?(stacktrace, "** (RuntimeError) oops") end + + test "passing options to encoder" do + formatter = {Elastic, encoder_opts: [pretty: true]} + :logger.update_handler_config(:default, :formatter, formatter) + + assert capture_log(fn -> + Logger.debug("Hello") + end) =~ + ~r/\n\s{2}"message": "Hello"/ + end end diff --git a/test/logger_json/formatters/google_cloud_test.exs b/test/logger_json/formatters/google_cloud_test.exs index f809480..0269b0e 100644 --- a/test/logger_json/formatters/google_cloud_test.exs +++ b/test/logger_json/formatters/google_cloud_test.exs @@ -450,4 +450,14 @@ defmodule LoggerJSON.Formatters.GoogleCloudTest do "serviceContext" => %{"service" => "nonode@nohost"} } = log_entry end + + test "passing options to encoder" do + formatter = {GoogleCloud, encoder_opts: [pretty: true]} + :logger.update_handler_config(:default, :formatter, formatter) + + assert capture_log(fn -> + Logger.debug("Hello") + end) =~ + ~r/\n\s{2}"message": "Hello"/ + end end