From 475396435f15354f4440ab43895f600f39d15a22 Mon Sep 17 00:00:00 2001 From: Kolawole Ezekiel Date: Thu, 19 Jun 2025 00:22:22 +0100 Subject: [PATCH 1/5] implement stblib logger support --- sentry-ruby/lib/sentry-ruby.rb | 1 + sentry-ruby/lib/sentry/configuration.rb | 7 +++ sentry-ruby/lib/sentry/std_lib_logger.rb | 45 +++++++++++++++++++ .../spec/sentry/std_lib_logger_spec.rb | 43 ++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 sentry-ruby/lib/sentry/std_lib_logger.rb create mode 100644 sentry-ruby/spec/sentry/std_lib_logger_spec.rb diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index 8d3f0578e..329cfea92 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -690,3 +690,4 @@ def dependency_installed?(name) require "sentry/graphql" require "sentry/faraday" require "sentry/excon" +require "sentry/std_lib_logger" \ No newline at end of file diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index 0a0f7236d..27599ace0 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -289,6 +289,12 @@ def logger # @return [Boolean] attr_accessor :enable_logs + # Enable stdlib Logger Add commentMore actions + # If set to true, any usage of any logger instance in client's app would result in sending logs to Sentry too. + # Dependent on :enable_logs + # @return [Boolean] + attr_accessor :send_stdlib_logs + # Easier way to use performance tracing # If set to true, will set traces_sample_rate to 1.0 # @deprecated It will be removed in the next major release. @@ -479,6 +485,7 @@ def initialize self.traces_sampler = nil self.enable_tracing = nil self.enable_logs = false + self.send_stdlib_logs = false self.profiler_class = Sentry::Profiler diff --git a/sentry-ruby/lib/sentry/std_lib_logger.rb b/sentry-ruby/lib/sentry/std_lib_logger.rb new file mode 100644 index 000000000..29b513f22 --- /dev/null +++ b/sentry-ruby/lib/sentry/std_lib_logger.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Sentry + # Ruby Logger support Add commentMore actions + # intercepts any logger instance and send the log to Sentry too. + module StdLibLogger + + SEVERITY_MAP = { + 0 => :debug, + 1 => :info, + 2 => :warn, + 3 => :error, + 4 => :fatal + }.freeze + + def add(severity, message = nil, progname = nil, &block) + + return unless Sentry.initialized? && Sentry.get_current_hub + + config = Sentry.configuration + return unless config.enable_logs && config.send_stdlib_logs + + # exclude sentry SDK logs -- to prevent recursive log action, + # do not process internal logs again + if message.nil? && progname != Sentry::Logger::PROGNAME + + # handle different nature of Ruby Logger class: + # inspo from Sentry::Breadcrumb::SentryLogger + if block_given? + message = yield + else + message = progname + end + + message = message.to_s.strip + + if !message.nil? && message != Sentry::Logger::PROGNAME && method = SEVERITY_MAP[severity] + Sentry.logger.send(method, message) + end + end + end + end +end + +::Logger.send(:prepend, Sentry::StdLibLogger) \ No newline at end of file diff --git a/sentry-ruby/spec/sentry/std_lib_logger_spec.rb b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb new file mode 100644 index 000000000..d763f1546 --- /dev/null +++ b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +RSpec.describe Sentry::StdLibLogger do + let(:logger) { ::Logger.new(IO::NULL) } + + context "when enable_logs is set to true but send_stdlib_logs is not enabled" do + before do + perform_basic_setup do |config| + config.enable_logs = true + config.send_stdlib_logs = false + end + end + + it "disables stdlib logger" do + expect(Sentry.configuration.send_stdlib_logs).to be(false) + end + end + + context "when enable_logs is set to true" do + before do + perform_basic_setup do |config| + config.max_log_events = 1 + config.enable_logs = true + config.send_stdlib_logs = true + end + end + + ["info", "warn", "error", "fatal"].each do |level| + describe "##{level}" do + it "send logs using stdlib logger" do + logger.send(level, "Hello World") + + expect(sentry_logs).to_not be_empty + + log_event = sentry_logs.last + + expect(log_event[:level]).to eql(level) + expect(log_event[:body]).to eql("Hello World") + end + end + end + end +end \ No newline at end of file From 3adb8b5b657ff5be0a5852b86305034bd40e961e Mon Sep 17 00:00:00 2001 From: Kolawole Ezekiel Date: Thu, 19 Jun 2025 00:48:16 +0100 Subject: [PATCH 2/5] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 139c2be07..c71abc05b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +### Feature + +- STDLIB Logger Support - send any instance of logger to sentry. ([#2653](https://github.com/getsentry/sentry-ruby/pull/2653)) + ## 5.25.0 ### Features From 9beaafac9619c1924d67b58c8dc57773bdd0b9f1 Mon Sep 17 00:00:00 2001 From: Kolawole Ezekiel Date: Mon, 23 Jun 2025 16:33:08 +0100 Subject: [PATCH 3/5] use existing patch to register stdlib logger --- sentry-ruby/lib/sentry/configuration.rb | 7 ----- sentry-ruby/lib/sentry/std_lib_logger.rb | 29 +++++++++++++++-- .../spec/sentry/std_lib_logger_spec.rb | 31 ++++++++++--------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index 27599ace0..0a0f7236d 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -289,12 +289,6 @@ def logger # @return [Boolean] attr_accessor :enable_logs - # Enable stdlib Logger Add commentMore actions - # If set to true, any usage of any logger instance in client's app would result in sending logs to Sentry too. - # Dependent on :enable_logs - # @return [Boolean] - attr_accessor :send_stdlib_logs - # Easier way to use performance tracing # If set to true, will set traces_sample_rate to 1.0 # @deprecated It will be removed in the next major release. @@ -485,7 +479,6 @@ def initialize self.traces_sampler = nil self.enable_tracing = nil self.enable_logs = false - self.send_stdlib_logs = false self.profiler_class = Sentry::Profiler diff --git a/sentry-ruby/lib/sentry/std_lib_logger.rb b/sentry-ruby/lib/sentry/std_lib_logger.rb index 29b513f22..a95d40ac9 100644 --- a/sentry-ruby/lib/sentry/std_lib_logger.rb +++ b/sentry-ruby/lib/sentry/std_lib_logger.rb @@ -14,11 +14,12 @@ module StdLibLogger }.freeze def add(severity, message = nil, progname = nil, &block) + super return unless Sentry.initialized? && Sentry.get_current_hub - config = Sentry.configuration - return unless config.enable_logs && config.send_stdlib_logs + # config = Sentry.configuration + # return unless config.enable_logs && config.send_stdlib_logs # exclude sentry SDK logs -- to prevent recursive log action, # do not process internal logs again @@ -38,8 +39,30 @@ def add(severity, message = nil, progname = nil, &block) Sentry.logger.send(method, message) end end + + super end end end -::Logger.send(:prepend, Sentry::StdLibLogger) \ No newline at end of file +# if Sentry.initialized? +# if Sentry.configuration.enable_logs +# Sentry.register_patch(:logger, Sentry::StdLibLogger, ::Logger) +# else +# Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") +# end +# end +# Sentry.register_patch(:logger, Sentry::StdLibLogger, ::Logger) do |config| +# if config.enable_logs +# ::Logger.prepend(Sentry::StdLibLogger) +# else +# Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") +# end +# end +Sentry.register_patch(:logger) do |config| + if config.enable_logs + ::Logger.prepend(Sentry::StdLibLogger) + else + Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") + end +end \ No newline at end of file diff --git a/sentry-ruby/spec/sentry/std_lib_logger_spec.rb b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb index d763f1546..d3eae0645 100644 --- a/sentry-ruby/spec/sentry/std_lib_logger_spec.rb +++ b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb @@ -3,25 +3,26 @@ RSpec.describe Sentry::StdLibLogger do let(:logger) { ::Logger.new(IO::NULL) } - context "when enable_logs is set to true but send_stdlib_logs is not enabled" do - before do - perform_basic_setup do |config| - config.enable_logs = true - config.send_stdlib_logs = false - end - end - - it "disables stdlib logger" do - expect(Sentry.configuration.send_stdlib_logs).to be(false) - end - end - - context "when enable_logs is set to true" do + context "when enable_logs is set to true but logger patch is not enabled" do + before do + perform_basic_setup do |config| + config.enable_logs = true + end + end + + it "does not send log using stdlib logger" do + logger.send(:info, "Hello World") + + expect(sentry_logs).to be_empty + end + end + + context "when enable_logs is set to true and logger patch is set" do before do perform_basic_setup do |config| config.max_log_events = 1 config.enable_logs = true - config.send_stdlib_logs = true + config.enabled_patches = [:redis, :puma, :http, :logger] end end From 6783dfa8ece956e8c31a30c98814e7f606607447 Mon Sep 17 00:00:00 2001 From: Kolawole Ezekiel Date: Mon, 23 Jun 2025 16:36:18 +0100 Subject: [PATCH 4/5] remove unused code --- sentry-ruby/lib/sentry/std_lib_logger.rb | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sentry-ruby/lib/sentry/std_lib_logger.rb b/sentry-ruby/lib/sentry/std_lib_logger.rb index a95d40ac9..774e799de 100644 --- a/sentry-ruby/lib/sentry/std_lib_logger.rb +++ b/sentry-ruby/lib/sentry/std_lib_logger.rb @@ -18,9 +18,6 @@ def add(severity, message = nil, progname = nil, &block) return unless Sentry.initialized? && Sentry.get_current_hub - # config = Sentry.configuration - # return unless config.enable_logs && config.send_stdlib_logs - # exclude sentry SDK logs -- to prevent recursive log action, # do not process internal logs again if message.nil? && progname != Sentry::Logger::PROGNAME @@ -45,20 +42,6 @@ def add(severity, message = nil, progname = nil, &block) end end -# if Sentry.initialized? -# if Sentry.configuration.enable_logs -# Sentry.register_patch(:logger, Sentry::StdLibLogger, ::Logger) -# else -# Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") -# end -# end -# Sentry.register_patch(:logger, Sentry::StdLibLogger, ::Logger) do |config| -# if config.enable_logs -# ::Logger.prepend(Sentry::StdLibLogger) -# else -# Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") -# end -# end Sentry.register_patch(:logger) do |config| if config.enable_logs ::Logger.prepend(Sentry::StdLibLogger) From d20494e8eb4975e59f5558777a94c54c72572b90 Mon Sep 17 00:00:00 2001 From: Kolawole Ezekiel Date: Mon, 23 Jun 2025 16:47:43 +0100 Subject: [PATCH 5/5] fix rubocop lint issues --- sentry-ruby/lib/sentry-ruby.rb | 2 +- sentry-ruby/lib/sentry/std_lib_logger.rb | 79 +++++++++---------- .../spec/sentry/std_lib_logger_spec.rb | 8 +- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index 329cfea92..a2a43b4e3 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -690,4 +690,4 @@ def dependency_installed?(name) require "sentry/graphql" require "sentry/faraday" require "sentry/excon" -require "sentry/std_lib_logger" \ No newline at end of file +require "sentry/std_lib_logger" diff --git a/sentry-ruby/lib/sentry/std_lib_logger.rb b/sentry-ruby/lib/sentry/std_lib_logger.rb index 774e799de..cee197e48 100644 --- a/sentry-ruby/lib/sentry/std_lib_logger.rb +++ b/sentry-ruby/lib/sentry/std_lib_logger.rb @@ -1,45 +1,44 @@ # frozen_string_literal: true module Sentry - # Ruby Logger support Add commentMore actions - # intercepts any logger instance and send the log to Sentry too. - module StdLibLogger - - SEVERITY_MAP = { - 0 => :debug, - 1 => :info, - 2 => :warn, - 3 => :error, - 4 => :fatal - }.freeze - - def add(severity, message = nil, progname = nil, &block) - super - - return unless Sentry.initialized? && Sentry.get_current_hub - - # exclude sentry SDK logs -- to prevent recursive log action, - # do not process internal logs again - if message.nil? && progname != Sentry::Logger::PROGNAME - - # handle different nature of Ruby Logger class: - # inspo from Sentry::Breadcrumb::SentryLogger - if block_given? - message = yield - else - message = progname - end - - message = message.to_s.strip - - if !message.nil? && message != Sentry::Logger::PROGNAME && method = SEVERITY_MAP[severity] - Sentry.logger.send(method, message) - end - end - - super - end - end + # Ruby Logger support Add commentMore actions + # intercepts any logger instance and send the log to Sentry too. + module StdLibLogger + SEVERITY_MAP = { + 0 => :debug, + 1 => :info, + 2 => :warn, + 3 => :error, + 4 => :fatal + }.freeze + + def add(severity, message = nil, progname = nil, &block) + super + + return unless Sentry.initialized? && Sentry.get_current_hub + + # exclude sentry SDK logs -- to prevent recursive log action, + # do not process internal logs again + if message.nil? && progname != Sentry::Logger::PROGNAME + + # handle different nature of Ruby Logger class: + # inspo from Sentry::Breadcrumb::SentryLogger + if block_given? + message = yield + else + message = progname + end + + message = message.to_s.strip + + if !message.nil? && message != Sentry::Logger::PROGNAME && method = SEVERITY_MAP[severity] + Sentry.logger.send(method, message) + end + end + + super + end + end end Sentry.register_patch(:logger) do |config| @@ -48,4 +47,4 @@ def add(severity, message = nil, progname = nil, &block) else Sentry.sdk_logger.warn(":logger patch enabled but `enable_logs` is turned off - skipping applying patch") end -end \ No newline at end of file +end diff --git a/sentry-ruby/spec/sentry/std_lib_logger_spec.rb b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb index d3eae0645..81ed66738 100644 --- a/sentry-ruby/spec/sentry/std_lib_logger_spec.rb +++ b/sentry-ruby/spec/sentry/std_lib_logger_spec.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true RSpec.describe Sentry::StdLibLogger do - let(:logger) { ::Logger.new(IO::NULL) } + let(:logger) { ::Logger.new(IO::NULL) } - context "when enable_logs is set to true but logger patch is not enabled" do + context "when enable_logs is set to true but logger patch is not enabled" do before do perform_basic_setup do |config| config.enable_logs = true @@ -13,7 +13,7 @@ it "does not send log using stdlib logger" do logger.send(:info, "Hello World") - expect(sentry_logs).to be_empty + expect(sentry_logs).to be_empty end end @@ -41,4 +41,4 @@ end end end -end \ No newline at end of file +end