From 1133042692e2ca4fcfbabae030be24ac99e4baa4 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 15:29:42 -0700 Subject: [PATCH 01/12] TECH-19528: bump .ruby-version to 3.3.8 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 9cec716..37d02a6 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.6 +3.3.8 From 57a334cd2cfe2805020323b1db9fab1a86ad585b Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 15:38:37 -0700 Subject: [PATCH 02/12] TECH-19528: add predicate methods: debug? info? warn? error? fatal? --- lib/contextual_logger/logger_with_context.rb | 6 +++ .../logger_with_context_spec.rb | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/lib/contextual_logger/logger_with_context.rb b/lib/contextual_logger/logger_with_context.rb index 8fb3074..397a6e6 100644 --- a/lib/contextual_logger/logger_with_context.rb +++ b/lib/contextual_logger/logger_with_context.rb @@ -40,6 +40,12 @@ def level=(override_level) @override_level = (ContextualLogger.normalize_log_level(override_level) if override_level) end + LOG_LEVEL_NAMES_TO_SEVERITY.except(:unknown).each do |severity, log_level| + define_method("#{severity}?") do + log_level_enabled?(log_level) + end + end + def write_entry_to_log(severity, timestamp, progname, message, context:) merged_context = if context.any? diff --git a/spec/lib/contextual_logger/logger_with_context_spec.rb b/spec/lib/contextual_logger/logger_with_context_spec.rb index c014891..05467b8 100644 --- a/spec/lib/contextual_logger/logger_with_context_spec.rb +++ b/spec/lib/contextual_logger/logger_with_context_spec.rb @@ -126,6 +126,54 @@ end end + describe "log level predicates" do + it "delegates to DEBUG level" do + subject.level = Logger::Severity::DEBUG + expect(subject.debug?).to eq(true) + expect(subject.info?).to eq(true) + expect(subject.warn?).to eq(true) + expect(subject.error?).to eq(true) + expect(subject.fatal?).to eq(true) + end + + it "delegates to INFO level" do + subject.level = Logger::Severity::INFO + expect(subject.debug?).to eq(false) + expect(subject.info?).to eq(true) + expect(subject.warn?).to eq(true) + expect(subject.error?).to eq(true) + expect(subject.fatal?).to eq(true) + end + + it "delegates to WARN level" do + subject.level = nil + base_logger.level = Logger::Severity::WARN + expect(subject.debug?).to eq(false) + expect(subject.info?).to eq(false) + expect(subject.warn?).to eq(true) + expect(subject.error?).to eq(true) + expect(subject.fatal?).to eq(true) + end + + it "delegates to ERROR level" do + subject.level = Logger::Severity::ERROR + expect(subject.debug?).to eq(false) + expect(subject.info?).to eq(false) + expect(subject.warn?).to eq(false) + expect(subject.error?).to eq(true) + expect(subject.fatal?).to eq(true) + end + + it "delegates to FATAL level" do + subject.level = Logger::Severity::FATAL + expect(subject.debug?).to eq(false) + expect(subject.info?).to eq(false) + expect(subject.warn?).to eq(false) + expect(subject.error?).to eq(false) + expect(subject.fatal?).to eq(true) + end + end + context "when string passed as context key" do it "returns context with a symbol key" do context_with_string_key = { "log_source" => "redis_client" } From 14a76cae11c97229166ace75c96dfa400c563060 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 15:41:03 -0700 Subject: [PATCH 03/12] TECH-19528: bump to v1.5.0; update CHANGELOG --- CHANGELOG.md | 4 ++++ Gemfile.lock | 32 +++++++++++++++++++------------- lib/contextual_logger/version.rb | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 764aa96..4a8c471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.5.0] - 2025-09-11 +### Added +- Added LoggerWithContext support for `debug?`, `info?`, `warn?`, `error?`, `fatal?`. + ## [1.4.0] - 2024-07-10 ### Added - Added support for `activesupport` 7.1 by providing a mixin for extending Broadcast loggers. diff --git a/Gemfile.lock b/Gemfile.lock index 5119afd..c47db22 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,23 +1,26 @@ PATH remote: . specs: - contextual_logger (1.4.0) + contextual_logger (1.5.0) activesupport (>= 6.0) json GEM remote: https://rubygems.org/ specs: - activesupport (7.1.3.4) + activesupport (8.0.2.1) base64 + benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) appraisal (2.5.0) bundler rake @@ -25,12 +28,13 @@ GEM appraisal-matrix (0.2.0) appraisal (~> 2.2) ast (2.4.2) - base64 (0.2.0) - bigdecimal (3.1.8) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.3) bump (0.6.1) coderay (1.1.3) - concurrent-ruby (1.3.3) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) @@ -39,13 +43,13 @@ GEM tins (~> 1.6) diff-lcs (1.5.0) docile (1.4.0) - drb (2.2.1) - i18n (1.14.5) + drb (2.2.3) + i18n (1.14.7) concurrent-ruby (~> 1.0) json (2.6.3) + logger (1.7.0) method_source (1.0.0) - minitest (5.24.1) - mutex_m (0.2.0) + minitest (5.25.5) parallel (1.23.0) parser (3.2.2.3) ast (~> 2.4.1) @@ -85,6 +89,7 @@ GEM ruby-prof-flamegraph (0.3.0) ruby-prof (~> 0.13) ruby-progressbar (1.13.0) + securerandom (0.4.1) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) @@ -99,6 +104,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (1.8.0) + uri (1.0.3) PLATFORMS ruby diff --git a/lib/contextual_logger/version.rb b/lib/contextual_logger/version.rb index 2ae9eb9..f0d9f7b 100644 --- a/lib/contextual_logger/version.rb +++ b/lib/contextual_logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ContextualLogger - VERSION = '1.4.0' + VERSION = '1.5.0' end From ffb00154c25fcad30cfe2b537f4121f17e725fcf Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 15:52:03 -0700 Subject: [PATCH 04/12] TECH-19528: qualify some constants with :: --- lib/contextual_logger.rb | 12 ++++++------ lib/contextual_logger/logger_with_context.rb | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/contextual_logger.rb b/lib/contextual_logger.rb index cd867f3..d905b16 100644 --- a/lib/contextual_logger.rb +++ b/lib/contextual_logger.rb @@ -11,12 +11,12 @@ module ContextualLogger LOG_LEVEL_NAMES_TO_SEVERITY = { - debug: Logger::Severity::DEBUG, - info: Logger::Severity::INFO, - warn: Logger::Severity::WARN, - error: Logger::Severity::ERROR, - fatal: Logger::Severity::FATAL, - unknown: Logger::Severity::UNKNOWN + debug: ::Logger::Severity::DEBUG, + info: ::Logger::Severity::INFO, + warn: ::Logger::Severity::WARN, + error: ::Logger::Severity::ERROR, + fatal: ::Logger::Severity::FATAL, + unknown: ::Logger::Severity::UNKNOWN }.freeze class << self diff --git a/lib/contextual_logger/logger_with_context.rb b/lib/contextual_logger/logger_with_context.rb index 397a6e6..66a0f2d 100644 --- a/lib/contextual_logger/logger_with_context.rb +++ b/lib/contextual_logger/logger_with_context.rb @@ -40,7 +40,7 @@ def level=(override_level) @override_level = (ContextualLogger.normalize_log_level(override_level) if override_level) end - LOG_LEVEL_NAMES_TO_SEVERITY.except(:unknown).each do |severity, log_level| + ::ContextualLogger::LOG_LEVEL_NAMES_TO_SEVERITY.except(:unknown).each do |severity, log_level| define_method("#{severity}?") do log_level_enabled?(log_level) end From 83625cc75eb6982e8a8e69d7cafafa7b3328c20f Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:01:00 -0700 Subject: [PATCH 05/12] TECH-19528: drop ruby 3.1, 3.2 and add 3.3; drop Rails 6.0, 6.1 and add 7.2 and 8.0 --- .github/workflows/test.yml | 6 +++--- Appraisals | 2 +- gemfiles/activesupport_7_0.gemfile | 2 +- gemfiles/activesupport_7_1.gemfile | 2 +- gemfiles/activesupport_7_2.gemfile | 19 +++++++++++++++++++ gemfiles/activesupport_8_0.gemfile | 19 +++++++++++++++++++ 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 gemfiles/activesupport_7_2.gemfile create mode 100644 gemfiles/activesupport_8_0.gemfile diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d8a0cea..620afd7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,13 +8,13 @@ jobs: strategy: fail-fast: false matrix: - ruby: [3.1, 3.2, 3.3] + ruby: [3.3, 3.4] gemfile: - Gemfile - - gemfiles/activesupport_6_0.gemfile - - gemfiles/activesupport_6_1.gemfile - gemfiles/activesupport_7_0.gemfile - gemfiles/activesupport_7_1.gemfile + - gemfiles/activesupport_7_2.gemfile + - gemfiles/activesupport_8_0.gemfile env: BUNDLE_GEMFILE: ${{ matrix.gemfile }} steps: diff --git a/Appraisals b/Appraisals index cefb94f..6356818 100644 --- a/Appraisals +++ b/Appraisals @@ -2,4 +2,4 @@ require 'appraisal/matrix' -appraisal_matrix(activesupport: "6.0") +appraisal_matrix(activesupport: "7.0") diff --git a/gemfiles/activesupport_7_0.gemfile b/gemfiles/activesupport_7_0.gemfile index fc9f3ed..e662cf5 100644 --- a/gemfiles/activesupport_7_0.gemfile +++ b/gemfiles/activesupport_7_0.gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org" gem "coveralls", require: false gem "appraisal" -gem "appraisal-matrix", "0.1.0" +gem "appraisal-matrix" gem "bump", "~> 0.6.1" gem "pry" gem "rake" diff --git a/gemfiles/activesupport_7_1.gemfile b/gemfiles/activesupport_7_1.gemfile index 3776308..f3cb994 100644 --- a/gemfiles/activesupport_7_1.gemfile +++ b/gemfiles/activesupport_7_1.gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org" gem "coveralls", require: false gem "appraisal" -gem "appraisal-matrix", "0.1.0" +gem "appraisal-matrix" gem "bump", "~> 0.6.1" gem "pry" gem "rake" diff --git a/gemfiles/activesupport_7_2.gemfile b/gemfiles/activesupport_7_2.gemfile new file mode 100644 index 0000000..e2c4702 --- /dev/null +++ b/gemfiles/activesupport_7_2.gemfile @@ -0,0 +1,19 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "coveralls", require: false +gem "appraisal" +gem "appraisal-matrix" +gem "bump", "~> 0.6.1" +gem "pry" +gem "rake" +gem "rubocop", "0.54.0" +gem "rubocop-git" +gem "ruby-prof" +gem "ruby-prof-flamegraph" +gem "rspec" +gem "rspec_junit_formatter" +gem "activesupport", "~> 7.2.0" + +gemspec path: "../" diff --git a/gemfiles/activesupport_8_0.gemfile b/gemfiles/activesupport_8_0.gemfile new file mode 100644 index 0000000..7e95637 --- /dev/null +++ b/gemfiles/activesupport_8_0.gemfile @@ -0,0 +1,19 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "coveralls", require: false +gem "appraisal" +gem "appraisal-matrix" +gem "bump", "~> 0.6.1" +gem "pry" +gem "rake" +gem "rubocop", "0.54.0" +gem "rubocop-git" +gem "ruby-prof" +gem "ruby-prof-flamegraph" +gem "rspec" +gem "rspec_junit_formatter" +gem "activesupport", "~> 8.0.0" + +gemspec path: "../" From 2ff87dc1302ecfd94dfbca84ddc161c359f40979 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:02:34 -0700 Subject: [PATCH 06/12] TECH-19528: bundle update --conservative thor --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c47db22..643c19a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,7 +98,7 @@ GEM sync (0.5.0) term-ansicolor (1.7.1) tins (~> 1.0) - thor (1.3.1) + thor (1.4.0) tins (1.32.1) sync tzinfo (2.0.6) From 02ca606c1042a63439ce99c60c0ba361363c3a25 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:09:36 -0700 Subject: [PATCH 07/12] TECH-19528: raise ArgumentError if any context keys are strings --- CHANGELOG.md | 2 ++ lib/contextual_logger/logger_with_context.rb | 11 ++++------ .../logger_with_context_spec.rb | 20 ++++--------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a8c471..38c328b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0 ## [1.5.0] - 2025-09-11 ### Added - Added LoggerWithContext support for `debug?`, `info?`, `warn?`, `error?`, `fatal?`. +### Changed +- Raise ArgumentError if context keys are not symbols. (Was documented to start in v1.0.0 but was not implemented until now.) ## [1.4.0] - 2024-07-10 ### Added diff --git a/lib/contextual_logger/logger_with_context.rb b/lib/contextual_logger/logger_with_context.rb index 66a0f2d..2dc467a 100644 --- a/lib/contextual_logger/logger_with_context.rb +++ b/lib/contextual_logger/logger_with_context.rb @@ -60,16 +60,13 @@ def write_entry_to_log(severity, timestamp, progname, message, context:) private def normalize_context(context) - if warn_on_string_keys(context) - context.deep_symbolize_keys - else - context - end + raise_on_string_keys(context) + context end - def warn_on_string_keys(context) + def raise_on_string_keys(context) if deep_key_has_string?(context) - ActiveSupport::Deprecation.warn('Context keys must use symbols not strings. This will be asserted as of contextual_logger v1.0.0') + raise ArgumentError, "context keys must use symbols not strings: #{context.inspect}" end end diff --git a/spec/lib/contextual_logger/logger_with_context_spec.rb b/spec/lib/contextual_logger/logger_with_context_spec.rb index 05467b8..23f24d3 100644 --- a/spec/lib/contextual_logger/logger_with_context_spec.rb +++ b/spec/lib/contextual_logger/logger_with_context_spec.rb @@ -175,23 +175,11 @@ end context "when string passed as context key" do - it "returns context with a symbol key" do - context_with_string_key = { "log_source" => "redis_client" } - string_context = ContextualLogger::LoggerWithContext.new(base_logger, context_with_string_key) - expect(string_context.context).to eq(log_source: "redis_client") - end - - it "returns a deep context with symbol key" do - context_with_string_key_levels = { log_source: { level1: { level2: { "level3" => "redis_client" } } } } - string_context = ContextualLogger::LoggerWithContext.new(base_logger, context_with_string_key_levels) - expect(string_context.context) - .to eq({ log_source: { level1: { level2: { level3: "redis_client" } } } }) - end - - it "should return a deprecation warning" do + it "raises ArgumentError" do context_with_string_key = { "log_source" => "redis_client" } - expect { ContextualLogger::LoggerWithContext.new(base_logger, context_with_string_key) } - .to output(/DEPRECATION WARNING: Context keys must use symbols not strings/).to_stderr + expect do + ContextualLogger::LoggerWithContext.new(base_logger, context_with_string_key) + end.to raise_exception(ArgumentError, 'context keys must use symbols not strings: {"log_source"=>"redis_client"}') end end From cd0905aedd5dff86152ebc9728b6ad84680b0cc2 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:12:04 -0700 Subject: [PATCH 08/12] TECH-19528: require 'logger' before 'active_supprt' --- lib/contextual_logger.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/contextual_logger.rb b/lib/contextual_logger.rb index d905b16..d9b4717 100644 --- a/lib/contextual_logger.rb +++ b/lib/contextual_logger.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'logger' # required first to get ::Logger defined for ActiveSupport 7.0 require 'active_support' require 'active_support/core_ext/module/delegation' require 'json' From b2ce6a692fe58fb3691cf495b090fd68f1ddf37e Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:14:05 -0700 Subject: [PATCH 09/12] TECH-19528: tolerate spaces around => from Hash#inspect in newer ruby versions --- spec/lib/contextual_logger/logger_with_context_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/contextual_logger/logger_with_context_spec.rb b/spec/lib/contextual_logger/logger_with_context_spec.rb index 23f24d3..b7a912d 100644 --- a/spec/lib/contextual_logger/logger_with_context_spec.rb +++ b/spec/lib/contextual_logger/logger_with_context_spec.rb @@ -179,7 +179,7 @@ context_with_string_key = { "log_source" => "redis_client" } expect do ContextualLogger::LoggerWithContext.new(base_logger, context_with_string_key) - end.to raise_exception(ArgumentError, 'context keys must use symbols not strings: {"log_source"=>"redis_client"}') + end.to raise_exception(ArgumentError, /context keys must use symbols not strings: \{"log_source" ?=> ?"redis_client"\}/) end end From 4a616d18ca459408c46554c0a347f9d3e1f04d22 Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:20:49 -0700 Subject: [PATCH 10/12] TECH-19528: add mutex_m gem because of some ruby versions --- Gemfile | 1 + Gemfile.lock | 2 ++ gemfiles/activesupport_7_0.gemfile | 1 + gemfiles/activesupport_7_1.gemfile | 1 + gemfiles/activesupport_7_2.gemfile | 1 + gemfiles/activesupport_8_0.gemfile | 1 + 6 files changed, 7 insertions(+) diff --git a/Gemfile b/Gemfile index 2fc2c8a..2ba4873 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ gem 'coveralls', require: false gem 'appraisal' gem 'appraisal-matrix' gem 'bump', '~> 0.6.1' +gem 'mutex_m' gem 'pry' gem 'rake' gem 'rubocop', '0.54.0' diff --git a/Gemfile.lock b/Gemfile.lock index 643c19a..830736c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,6 +50,7 @@ GEM logger (1.7.0) method_source (1.0.0) minitest (5.25.5) + mutex_m (0.3.0) parallel (1.23.0) parser (3.2.2.3) ast (~> 2.4.1) @@ -115,6 +116,7 @@ DEPENDENCIES bump (~> 0.6.1) contextual_logger! coveralls + mutex_m pry rake rspec diff --git a/gemfiles/activesupport_7_0.gemfile b/gemfiles/activesupport_7_0.gemfile index e662cf5..71d7b6b 100644 --- a/gemfiles/activesupport_7_0.gemfile +++ b/gemfiles/activesupport_7_0.gemfile @@ -6,6 +6,7 @@ gem "coveralls", require: false gem "appraisal" gem "appraisal-matrix" gem "bump", "~> 0.6.1" +gem "mutex_m" gem "pry" gem "rake" gem "rubocop", "0.54.0" diff --git a/gemfiles/activesupport_7_1.gemfile b/gemfiles/activesupport_7_1.gemfile index f3cb994..376e67f 100644 --- a/gemfiles/activesupport_7_1.gemfile +++ b/gemfiles/activesupport_7_1.gemfile @@ -6,6 +6,7 @@ gem "coveralls", require: false gem "appraisal" gem "appraisal-matrix" gem "bump", "~> 0.6.1" +gem "mutex_m" gem "pry" gem "rake" gem "rubocop", "0.54.0" diff --git a/gemfiles/activesupport_7_2.gemfile b/gemfiles/activesupport_7_2.gemfile index e2c4702..f0417dc 100644 --- a/gemfiles/activesupport_7_2.gemfile +++ b/gemfiles/activesupport_7_2.gemfile @@ -6,6 +6,7 @@ gem "coveralls", require: false gem "appraisal" gem "appraisal-matrix" gem "bump", "~> 0.6.1" +gem "mutex_m" gem "pry" gem "rake" gem "rubocop", "0.54.0" diff --git a/gemfiles/activesupport_8_0.gemfile b/gemfiles/activesupport_8_0.gemfile index 7e95637..b7b95bc 100644 --- a/gemfiles/activesupport_8_0.gemfile +++ b/gemfiles/activesupport_8_0.gemfile @@ -6,6 +6,7 @@ gem "coveralls", require: false gem "appraisal" gem "appraisal-matrix" gem "bump", "~> 0.6.1" +gem "mutex_m" gem "pry" gem "rake" gem "rubocop", "0.54.0" From 87187b768f9923d577e824c461d985ece9bb0bfa Mon Sep 17 00:00:00 2001 From: Colin Kelley Date: Thu, 11 Sep 2025 16:26:27 -0700 Subject: [PATCH 11/12] TECH-19528: update for newer Hash#inspect format --- spec/lib/contextual_logger_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/lib/contextual_logger_spec.rb b/spec/lib/contextual_logger_spec.rb index dc54e74..3ee78e8 100644 --- a/spec/lib/contextual_logger_spec.rb +++ b/spec/lib/contextual_logger_spec.rb @@ -120,13 +120,13 @@ def expect_log_line_to_be_written(log_line) expect(log_message_levels).to eq(["error", "fatal", "unknown"]) # note: context lands in `progname` arg if ::ActiveSupport::VERSION::STRING < "7.1" - expect(console_log_stream.string.gsub(/\[[^\]]+\]/, '[]')).to eq(<<~EOS) - D, [] DEBUG -- {:service=>\"test_service\"}: debug message - I, [] INFO -- {:service=>\"test_service\"}: info message - W, [] WARN -- {:service=>\"test_service\"}: warn message - E, [] ERROR -- {:service=>\"test_service\"}: error message - F, [] FATAL -- {:service=>\"test_service\"}: fatal message - A, [] ANY -- {:service=>\"test_service\"}: unknown message + expect(console_log_stream.string.gsub(/\[[^\]]+\]/, '[]').gsub(':service=>', 'service: ')).to eq(<<~EOS) + D, [] DEBUG -- {service: \"test_service\"}: debug message + I, [] INFO -- {service: \"test_service\"}: info message + W, [] WARN -- {service: \"test_service\"}: warn message + E, [] ERROR -- {service: \"test_service\"}: error message + F, [] FATAL -- {service: \"test_service\"}: fatal message + A, [] ANY -- {service: \"test_service\"}: unknown message EOS else expect(log_stream.string.gsub(/"timestamp":"[^"]+"/, '