diff --git a/README.md b/README.md index 2187e54..3d036fc 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,16 @@ config :new_relic_agent, httpc_request_options: [connect_timeout: 5000] ``` +#### For Elixir 1.15 and higher + +Due to changes in the Elixir 1.15 Logger, additional logger configuration is needed for NewRelic to capture all errors. Update your logger configuration by setting `handle_sasl_reports` to `true` and adding `NewRelic.ErrorLogger` to your logger backends. + +```elixir +config :logger, + handle_sasl_reports: true, + backends: [:console, NewRelic.ErrorLogger] +``` + ## Telemetry-based Instrumentation Some common Elixir packages are auto-instrumented via [`telemetry`](https://github.com/beam-telemetry/telemetry) diff --git a/config/config.exs b/config/config.exs index 159012c..a978396 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,6 +1,8 @@ import Config -config :logger, handle_sasl_reports: true +config :logger, + handle_sasl_reports: true, + backends: [NewRelic.ErrorLogger] if Mix.env() == :test, do: import_config("test.exs") if File.exists?("config/secret.exs"), do: import_config("secret.exs") diff --git a/lib/new_relic/error/logger_handler.ex b/lib/new_relic/error/logger_handler.ex index f289a37..427ed5b 100644 --- a/lib/new_relic/error/logger_handler.ex +++ b/lib/new_relic/error/logger_handler.ex @@ -16,7 +16,7 @@ defmodule NewRelic.Error.LoggerHandler do NewRelic.Error.Reporter.report_error(:process, report) end - :none + :skip end def translator(_level, :error, _timestamp, {_, %{args: _, function: _}} = metadata) do diff --git a/lib/new_relic/error_logger.ex b/lib/new_relic/error_logger.ex new file mode 100644 index 0000000..80e3bc4 --- /dev/null +++ b/lib/new_relic/error_logger.ex @@ -0,0 +1,42 @@ +defmodule NewRelic.ErrorLogger do + @moduledoc """ + Handle error reporting in elixir >= 1.15 + """ + @behaviour :gen_event + + import NewRelic.ConditionalCompile + + def init(opts) do + after_elixir_version( + "1.15.0", + Logger.add_translator({__MODULE__, :translator}) + ) + + {:ok, opts} + end + + def handle_call(_opts, state), do: {:ok, :ok, state} + + def handle_event(_opts, state), do: {:ok, state} + + def handle_info(_opts, state), do: {:ok, state} + + def code_change(_old_vsn, state, _extra), do: {:ok, state} + + def terminate(_reason, _state) do + after_elixir_version( + "1.15.0", + Logger.remove_translator({__MODULE__, :translator}) + ) + + :ok + end + + # Don't log SASL progress reports + def translator(_level, _message, _timestamp, {{caller, :progress}, _}) + when caller in [:supervisor, :application_controller] do + :skip + end + + def translator(_level, _message, _timestamp, _metadata), do: :none +end