From 7de7d5fa3794db94080f9dd154a47f5bfd2bc54f Mon Sep 17 00:00:00 2001 From: Matthew Trew Date: Wed, 17 Jun 2026 13:08:44 +0200 Subject: [PATCH 1/5] Use JSON-format structured logging in production --- Gemfile | 1 + Gemfile.lock | 7 +++++++ config/environments/production.rb | 10 ++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 9c183e32c..8543d6be9 100644 --- a/Gemfile +++ b/Gemfile @@ -43,6 +43,7 @@ gem 'puma', '~> 8.0' gem 'rack_content_type_default', '~> 1.1' gem 'rack-cors' gem 'rails', '~> 8.1.3' +gem 'rails_semantic_logger', '~> 4.20' gem 'ruby-progressbar', '~> 1.13', require: false gem 'ruby-vips' gem 'sentry-rails' diff --git a/Gemfile.lock b/Gemfile.lock index a88961748..83595d64a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -403,6 +403,10 @@ GEM rails-html-sanitizer (1.7.0) loofah (~> 2.25) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + rails_semantic_logger (4.20.0) + rack + railties (>= 5.1) + semantic_logger (~> 4.16) railties (8.1.3) actionpack (= 8.1.3) activesupport (= 8.1.3) @@ -513,6 +517,8 @@ GEM childprocess (>= 0.5, < 5.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2) + semantic_logger (4.18.0) + concurrent-ruby (~> 1.0) sentry-rails (6.6.0) railties (>= 5.2.0) sentry-ruby (~> 6.6.0) @@ -618,6 +624,7 @@ DEPENDENCIES rack_content_type_default (~> 1.1) rails (~> 8.1.3) rails-erd + rails_semantic_logger (~> 4.20) rspec rspec-rails rspec_junit_formatter diff --git a/config/environments/production.rb b/config/environments/production.rb index eddc64960..0a1a2134e 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -45,10 +45,12 @@ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Log to STDOUT by default - config.logger = ActiveSupport::Logger.new($stdout) - .tap { |logger| logger.formatter = Logger::Formatter.new } - .then { |logger| ActiveSupport::TaggedLogging.new(logger) } + # Log to STDOUT on Heroku in JSON format, where this variable is set automatically. + if ENV['RAILS_LOG_TO_STDOUT'].present? + $stdout.sync = true + config.rails_semantic_logger.add_file_appender = false + config.semantic_logger.add_appender(io: $stdout, formatter: :json) + end # Prepend all log lines with the following tags. config.log_tags = [:request_id] From 642b75285bd9c6053059507179e6438b8d64f690 Mon Sep 17 00:00:00 2001 From: Matthew Trew Date: Wed, 17 Jun 2026 14:59:26 +0200 Subject: [PATCH 2/5] Ensure Semantic Logger is used in all cases This is necessary for Flipper and ActionDispatch::HostAuthorization messages to go through Semantic Logger and be correctly formatted as JSON. --- config/application.rb | 2 ++ config/initializers/logging.rb | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 config/initializers/logging.rb diff --git a/config/application.rb b/config/application.rb index 53566619a..aed8caa42 100644 --- a/config/application.rb +++ b/config/application.rb @@ -73,5 +73,7 @@ class Application < Rails::Application config.x.cloudflare_turnstile.secret_key = ENV.fetch('CLOUDFLARE_TURNSTILE_SECRET_KEY', nil) config.x.cloudflare_turnstile.enabled = ENV['CLOUDFLARE_TURNSTILE_SECRET_KEY'].present? + + config.rails_semantic_logger.format = :json end end diff --git a/config/initializers/logging.rb b/config/initializers/logging.rb new file mode 100644 index 000000000..51ffda17d --- /dev/null +++ b/config/initializers/logging.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# Ensure Semantic Logger is used in all cases by updating cached references to the standard logger. +Rails.application.config.after_initialize do + ActiveSupport::LogSubscriber.logger = Rails.logger + Rails.application.env_config['action_dispatch.logger'] = Rails.logger +end From 0e2d3e84c5ead292d2fa2694ae0304b83abb9573 Mon Sep 17 00:00:00 2001 From: Matthew Trew Date: Wed, 17 Jun 2026 15:16:55 +0200 Subject: [PATCH 3/5] Correct application name, include version in prod --- config/application.rb | 1 + config/environments/production.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/config/application.rb b/config/application.rb index aed8caa42..0475c0df9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -75,5 +75,6 @@ class Application < Rails::Application config.x.cloudflare_turnstile.enabled = ENV['CLOUDFLARE_TURNSTILE_SECRET_KEY'].present? config.rails_semantic_logger.format = :json + config.semantic_logger.application = 'editor-api' end end diff --git a/config/environments/production.rb b/config/environments/production.rb index 0a1a2134e..d1e1d4c7a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -50,6 +50,7 @@ $stdout.sync = true config.rails_semantic_logger.add_file_appender = false config.semantic_logger.add_appender(io: $stdout, formatter: :json) + config.semantic_logger.application = "editor-api@#{ENV['HEROKU_SLUG_COMMIT'] || 'unknown'}" end # Prepend all log lines with the following tags. From 0e86060902b4b14132dffa0120e7e5a6eea27131 Mon Sep 17 00:00:00 2001 From: Matthew Trew Date: Wed, 17 Jun 2026 15:28:12 +0200 Subject: [PATCH 4/5] Revert 642b752 --- config/initializers/logging.rb | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 config/initializers/logging.rb diff --git a/config/initializers/logging.rb b/config/initializers/logging.rb deleted file mode 100644 index 51ffda17d..000000000 --- a/config/initializers/logging.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -# Ensure Semantic Logger is used in all cases by updating cached references to the standard logger. -Rails.application.config.after_initialize do - ActiveSupport::LogSubscriber.logger = Rails.logger - Rails.application.env_config['action_dispatch.logger'] = Rails.logger -end From bc0e827b3e5c36400b6b44bf5c5e5632049d92e0 Mon Sep 17 00:00:00 2001 From: Matthew Trew Date: Wed, 17 Jun 2026 15:39:35 +0200 Subject: [PATCH 5/5] Disable flipper logging --- config/initializers/flipper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb index 37979057d..d6ca00c5c 100644 --- a/config/initializers/flipper.rb +++ b/config/initializers/flipper.rb @@ -18,7 +18,7 @@ # config.flipper.strict = Rails.env.development? && :warn ## Show Flipper checks in logs - # config.flipper.log = true + config.flipper.log = false ## Reconfigure Flipper to use the Memory adapter and disable Cloud in tests # config.flipper.test_help = true