From 649c03e2908c797664ded06ef93234312e694cb7 Mon Sep 17 00:00:00 2001 From: Jamil Date: Fri, 11 Apr 2025 19:00:06 -0700 Subject: [PATCH] chore(portal): Bump LoggerJSON to 7.0.0, fixing config (#8759) There was slight API change in the way LoggerJSON's configuration is generation, so I took the time to do a little fixing and cleanup here. Specifically, we should be using the `new/1` callback to create the Logger config which fixes the below exception due to missing config keys: ``` FORMATTER CRASH: {report,[{formatter_crashed,'Elixir.LoggerJSON.Formatters.GoogleCloud'},{config,[{metadata,{all_except,[socket,conn]}},{redactors,[{'Elixir.LoggerJSON.Redactors.RedactKeys',[<<"password">>,<<"secret">>,<<"nonce">>,<<"fragment">>,<<"state">>,<<"token">>,<<"public_key">>,<<"private_key">>,<<"preshared_key">>,<<"session">>,<<"sessions">>]}]}]},{log_event,#{meta => #{line => 15,pid => <0.308.0>,time => 1744145139650804,file => "lib/logger.ex",gl => <0.281.0>,domain => [elixir],application => libcluster,mfa => {'Elixir.Cluster.Logger',info,2}},msg => {string,<<"[libcluster:default] connected to :\"web@web.cluster.local\"">>},level => info}},{reason,{error,{badmatch,[{metadata,{all_except,[socket,conn]}},{redactors,[{'Elixir.LoggerJSON.Redactors.RedactKeys',[<<"password">>,<<"secret">>,<<"nonce">>,<<"fragment">>,<<"state">>,<<"token">>,<<"public_key">>,<<"private_key">>,<<"preshared_key">>,<<"session">>,<<"sessions">>]}]}]},[{'Elixir.LoggerJSON.Formatters.GoogleCloud',format,2,[{file,"lib/logger_json/formatters/google_cloud.ex"},{line,148}]}]}}]} ``` Supersedes #8714 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- elixir/apps/api/lib/api/application.ex | 27 ++++++++++------ elixir/apps/api/mix.exs | 1 + elixir/apps/domain/lib/domain/application.ex | 31 ++++++++++++------- .../domain/lib/domain/config/definitions.ex | 27 +--------------- elixir/apps/domain/mix.exs | 4 ++- elixir/apps/web/lib/web/application.ex | 27 ++++++++++------ elixir/apps/web/mix.exs | 1 + elixir/config/config.exs | 2 ++ elixir/config/prod.exs | 12 +++---- elixir/config/runtime.exs | 8 ----- elixir/mix.exs | 3 ++ elixir/mix.lock | 2 +- .../modules/google-cloud/apps/elixir/main.tf | 10 ++---- 13 files changed, 75 insertions(+), 80 deletions(-) diff --git a/elixir/apps/api/lib/api/application.ex b/elixir/apps/api/lib/api/application.ex index bc1bf06e9..23b221191 100644 --- a/elixir/apps/api/lib/api/application.ex +++ b/elixir/apps/api/lib/api/application.ex @@ -3,18 +3,11 @@ defmodule API.Application do @impl true def start(_type, _args) do + configure_logger() + _ = :opentelemetry_cowboy.setup() _ = OpentelemetryPhoenix.setup(adapter: :cowboy2) - # Configure Sentry to capture Logger messages - :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ - config: %{ - level: :warning, - metadata: :all, - capture_log_messages: true - } - }) - children = [ API.Endpoint, API.RateLimit @@ -29,4 +22,20 @@ defmodule API.Application do API.Endpoint.config_change(changed, removed) :ok end + + defp configure_logger do + if config = Application.get_env(:logger_json, :config) do + formatter = LoggerJSON.Formatters.GoogleCloud.new(config) + :logger.update_handler_config(:default, :formatter, formatter) + end + + # Configure Sentry to capture Logger messages + :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ + config: %{ + level: :warning, + metadata: :all, + capture_log_messages: true + } + }) + end end diff --git a/elixir/apps/api/mix.exs b/elixir/apps/api/mix.exs index d406d7784..ad1269cec 100644 --- a/elixir/apps/api/mix.exs +++ b/elixir/apps/api/mix.exs @@ -55,6 +55,7 @@ defmodule API.MixProject do {:opentelemetry_phoenix, "~> 2.0"}, {:sentry, "~> 10.0"}, {:hackney, "~> 1.19"}, + {:logger_json, "~> 7.0"}, # Other deps {:jason, "~> 1.2"}, diff --git a/elixir/apps/domain/lib/domain/application.ex b/elixir/apps/domain/lib/domain/application.ex index 77631fcaf..5f079ec32 100644 --- a/elixir/apps/domain/lib/domain/application.ex +++ b/elixir/apps/domain/lib/domain/application.ex @@ -2,21 +2,11 @@ defmodule Domain.Application do use Application def start(_type, _args) do - # Configure Logger severity at runtime - :ok = LoggerJSON.configure_log_level_from_env!("LOG_LEVEL") + configure_logger() _ = OpentelemetryLoggerMetadata.setup() _ = OpentelemetryEcto.setup([:domain, :repo]) - # Configure Sentry to capture Logger messages - :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ - config: %{ - level: :warning, - metadata: :all, - capture_log_messages: true - } - }) - # Can be uncommented when this bug is fixed: https://github.com/open-telemetry/opentelemetry-erlang-contrib/issues/327 # _ = OpentelemetryFinch.setup() @@ -50,4 +40,23 @@ defmodule Domain.Application do Domain.Telemetry ] end + + defp configure_logger do + # Configure Logger severity at runtime + :ok = LoggerJSON.configure_log_level_from_env!("LOG_LEVEL") + + if config = Application.get_env(:logger_json, :config) do + formatter = LoggerJSON.Formatters.GoogleCloud.new(config) + :logger.update_handler_config(:default, :formatter, formatter) + end + + # Configure Sentry to capture Logger messages + :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ + config: %{ + level: :warning, + metadata: :all, + capture_log_messages: true + } + }) + end end diff --git a/elixir/apps/domain/lib/domain/config/definitions.ex b/elixir/apps/domain/lib/domain/config/definitions.ex index 309965f0f..cef78e186 100644 --- a/elixir/apps/domain/lib/domain/config/definitions.ex +++ b/elixir/apps/domain/lib/domain/config/definitions.ex @@ -125,9 +125,7 @@ defmodule Domain.Config.Definitions do :instrumentation_client_logs_enabled, :instrumentation_client_logs_bucket, :telemetry_metrics_reporter, - :telemetry_metrics_reporter_opts, - :logger_formatter, - :logger_formatter_opts + :telemetry_metrics_reporter_opts ]}, {"Analytics", [ @@ -540,29 +538,6 @@ defmodule Domain.Config.Definitions do dump: &Dumper.keyword/1 ) - @doc """ - A formatter to use for the Elixir's Logger. If not set, the default formatter will be used. - """ - defconfig( - :logger_formatter, - Ecto.ParameterizedType.init(Ecto.Enum, - values: [ - Elixir.LoggerJSON.Formatters.GoogleCloud, - Elixir.LoggerJSON.Formatters.Basic, - Elixir.LoggerJSON.Formatters.Datadog - ] - ), - default: nil - ) - - @doc """ - Options for the logger formatter that is set by `logger_formatter` option. - """ - defconfig(:logger_formatter_opts, :map, - default: %{}, - dump: &Dumper.keyword/1 - ) - ############################################## ## Gateways ############################################## diff --git a/elixir/apps/domain/mix.exs b/elixir/apps/domain/mix.exs index 52b47e9b6..95ea1c2ef 100644 --- a/elixir/apps/domain/mix.exs +++ b/elixir/apps/domain/mix.exs @@ -80,7 +80,6 @@ defmodule Domain.MixProject do {:telemetry, "~> 1.0"}, {:telemetry_poller, "~> 1.0"}, {:telemetry_metrics, "~> 1.0"}, - {:logger_json, "~> 6.0"}, {:recon, "~> 2.5"}, {:observer_cli, "~> 1.7"}, {:opentelemetry, "~> 1.5"}, @@ -88,6 +87,9 @@ defmodule Domain.MixProject do {:opentelemetry_exporter, "~> 1.8"}, {:opentelemetry_ecto, "~> 1.2"}, {:opentelemetry_finch, "~> 0.2.0"}, + {:sentry, "~> 10.0"}, + {:hackney, "~> 1.19"}, + {:logger_json, "~> 7.0"}, # Other application deps {:tzdata, "~> 1.1"}, diff --git a/elixir/apps/web/lib/web/application.ex b/elixir/apps/web/lib/web/application.ex index 8240c7922..a402c6402 100644 --- a/elixir/apps/web/lib/web/application.ex +++ b/elixir/apps/web/lib/web/application.ex @@ -3,19 +3,12 @@ defmodule Web.Application do @impl true def start(_type, _args) do + configure_logger() + _ = OpentelemetryLiveView.setup() _ = :opentelemetry_cowboy.setup() _ = OpentelemetryPhoenix.setup(adapter: :cowboy2) - # Configure Sentry to capture Logger messages - :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ - config: %{ - level: :warning, - metadata: :all, - capture_log_messages: true - } - }) - children = [ Web.Endpoint ] @@ -29,4 +22,20 @@ defmodule Web.Application do Web.Endpoint.config_change(changed, removed) :ok end + + defp configure_logger do + if config = Application.get_env(:logger_json, :config) do + formatter = LoggerJSON.Formatters.GoogleCloud.new(config) + :logger.update_handler_config(:default, :formatter, formatter) + end + + # Configure Sentry to capture Logger messages + :logger.add_handler(:sentry, Sentry.LoggerHandler, %{ + config: %{ + level: :warning, + metadata: :all, + capture_log_messages: true + } + }) + end end diff --git a/elixir/apps/web/mix.exs b/elixir/apps/web/mix.exs index 2338604cb..7b2f7d291 100644 --- a/elixir/apps/web/mix.exs +++ b/elixir/apps/web/mix.exs @@ -68,6 +68,7 @@ defmodule Web.MixProject do {:nimble_options, "~> 1.0", override: true}, {:sentry, "~> 10.0"}, {:hackney, "~> 1.19"}, + {:logger_json, "~> 7.0"}, # Other deps {:jason, "~> 1.2"}, diff --git a/elixir/config/config.exs b/elixir/config/config.exs index e2b3b92c9..37a0b4b7c 100644 --- a/elixir/config/config.exs +++ b/elixir/config/config.exs @@ -285,6 +285,8 @@ config :sentry, Path.join(File.cwd!(), "apps/api") ] +config :logger_json, encoder: JSON + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/elixir/config/prod.exs b/elixir/config/prod.exs index 7c4ce7f8d..75064ae57 100644 --- a/elixir/config/prod.exs +++ b/elixir/config/prod.exs @@ -51,13 +51,11 @@ config :logger, handle_sasl_reports: false, handle_otp_reports: true -config :logger, :default_handler, - formatter: - {LoggerJSON.Formatters.GoogleCloud, - metadata: {:all_except, [:socket, :conn]}, - redactors: [ - {LoggerJSON.Redactors.RedactKeys, secret_keys} - ]} +config :logger_json, :config, + metadata: {:all_except, [:socket, :conn, :otel_trace_flags]}, + redactors: [ + {LoggerJSON.Redactors.RedactKeys, secret_keys} + ] config :logger, level: :info diff --git a/elixir/config/runtime.exs b/elixir/config/runtime.exs index ee337ae6a..582196343 100644 --- a/elixir/config/runtime.exs +++ b/elixir/config/runtime.exs @@ -209,14 +209,6 @@ if config_env() == :prod do ##### Third-party configs ##### ############################### - if logger_formatter = compile_config!(:logger_formatter) do - logger_formatter_opts = - compile_config!(:logger_formatter_opts) ++ - [metadata: {:all_except, [:socket, :conn, :otel_trace_flags]}] - - config :logger, :default_handler, formatter: {logger_formatter, logger_formatter_opts} - end - if System.get_env("OTLP_ENDPOINT") do config :opentelemetry, resource_detectors: [:otel_resource_env_var, :otel_resource_app_env] diff --git a/elixir/mix.exs b/elixir/mix.exs index 12782d631..e6b641ad7 100644 --- a/elixir/mix.exs +++ b/elixir/mix.exs @@ -36,6 +36,9 @@ defmodule Firezone.MixProject do [ # Shared deps {:jason, "~> 1.2"}, + {:sentry, "~> 10.0"}, + {:hackney, "~> 1.19"}, + {:logger_json, "~> 7.0"}, # Shared test deps {:credo, "~> 1.5", only: [:dev, :test], runtime: false}, diff --git a/elixir/mix.lock b/elixir/mix.lock index a276bbb8f..c01dd7efc 100644 --- a/elixir/mix.lock +++ b/elixir/mix.lock @@ -50,7 +50,7 @@ "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, "junit_formatter": {:hex, :junit_formatter, "3.4.0", "d0e8db6c34dab6d3c4154c3b46b21540db1109ae709d6cf99ba7e7a2ce4b1ac2", [:mix], [], "hexpm", "bb36e2ae83f1ced6ab931c4ce51dd3dbef1ef61bb4932412e173b0cfa259dacd"}, "libcluster": {:hex, :libcluster, "3.3.3", "a4f17721a19004cfc4467268e17cff8b1f951befe428975dd4f6f7b84d927fe0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7c0a2275a0bb83c07acd17dab3c3bfb4897b145106750eeccc62d302e3bdfee5"}, - "logger_json": {:hex, :logger_json, "6.2.0", "13e2e9f5f7b195865c5c3ef3d296c3ad50e7ecb038d899433702a79e979b91d7", [:mix], [{:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "98366d02bedbb56e41b25a6d248d566d4f4bc224bae2b1e982df00ed04ba9219"}, + "logger_json": {:hex, :logger_json, "7.0.0", "d644e499cf137346c58eedb5045ac06b14759881f80b9eb789009736d4da933d", [:mix], [{:decimal, ">= 0.0.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:ecto, "~> 3.11", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "91e02738ba93d39cb902ff54fcaa8ea23cd466147467b627fe35475021309b01"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, diff --git a/terraform/modules/google-cloud/apps/elixir/main.tf b/terraform/modules/google-cloud/apps/elixir/main.tf index c2f69b00d..443571493 100644 --- a/terraform/modules/google-cloud/apps/elixir/main.tf +++ b/terraform/modules/google-cloud/apps/elixir/main.tf @@ -48,14 +48,8 @@ locals { }) }, { - name = "LOGGER_FORMATTER" - value = "Elixir.LoggerJSON.Formatters.GoogleCloud" - }, - { - name = "LOGGER_FORMATTER_OPTS" - value = jsonencode({ - project_id = var.project_id - }) + name = "GOOGLE_CLOUD_PROJECT", + value = var.project_id }, { name = "PLATFORM_ADAPTER"