From 5037e148fc3e72c657aa7a13146a1147ccb6f8a6 Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Tue, 6 Oct 2026 11:59:44 +0000 Subject: [PATCH] fix(transport): log directly sent envelopes in DebugTransport --- .../lib/sentry/transport/debug_transport.rb | 13 +++++++-- .../sentry/transport/debug_transport_spec.rb | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/sentry-ruby/lib/sentry/transport/debug_transport.rb b/sentry-ruby/lib/sentry/transport/debug_transport.rb index 58d3ffb3e..5771a9004 100644 --- a/sentry-ruby/lib/sentry/transport/debug_transport.rb +++ b/sentry-ruby/lib/sentry/transport/debug_transport.rb @@ -27,6 +27,11 @@ def send_event(event) backend.send_event(event) end + def send_envelope(envelope) + log_envelope(envelope) + backend.send_envelope(envelope) + end + def log_envelope(envelope) envelope_json = { timestamp: Time.now.utc.iso8601, @@ -36,13 +41,13 @@ def log_envelope(envelope) end } - File.open(log_file, "a") { |file| file << JSON.dump(envelope_json) << "\n" } + File.open(log_file, "a") { |file| file.write("#{JSON.dump(envelope_json)}\n") } end def logged_envelopes return [] unless File.exist?(log_file) - File.readlines(log_file).map do |line| + File.readlines(log_file).select { |line| fully_written?(line) }.map do |line| JSON.parse(line) end end @@ -54,6 +59,10 @@ def clear private + def fully_written?(line) + line.end_with?("\n") + end + def initialize_backend(configuration) backend = configuration.dsn.local? ? DummyTransport : HTTPTransport backend.new(configuration) diff --git a/sentry-ruby/spec/sentry/transport/debug_transport_spec.rb b/sentry-ruby/spec/sentry/transport/debug_transport_spec.rb index 90b283ff3..21f4de1c6 100644 --- a/sentry-ruby/spec/sentry/transport/debug_transport_spec.rb +++ b/sentry-ruby/spec/sentry/transport/debug_transport_spec.rb @@ -22,6 +22,12 @@ context "with local DSN for testing" do let(:dsn) { Sentry::TestHelper::DUMMY_DSN } + def build_envelope(body) + Sentry::Envelope.new(sent_at: Sentry.utc_now.iso8601).tap do |envelope| + envelope.add_item({ type: "log" }, { items: [{ body: body }] }) + end + end + describe ".capture_exception with debug transport" do it "logs envelope data and stores an event internally" do Sentry.capture_exception(error) @@ -37,6 +43,27 @@ expect(payload["exception"]["values"].first["value"]).to include("test error") end end + + describe "#send_envelope" do + it "logs the envelope and passes it on to the backend" do + transport.send_envelope(build_envelope("hello")) + + expect(transport.backend.envelopes.count).to be(1) + expect(transport.logged_envelopes.last.dig("items", 0, "payload", "items", 0, "body")).to eq("hello") + end + end + + describe "#logged_envelopes" do + it "skips a last line that is still being written" do + transport.clear + transport.send_envelope(build_envelope("complete")) + File.open(transport.log_file, "a") { |file| file.write('{"timestamp":"2026-10-06T09:08:2') } + + bodies = transport.logged_envelopes.map { |envelope| envelope.dig("items", 0, "payload", "items", 0, "body") } + + expect(bodies).to eq(["complete"]) + end + end end context "with a real DSN for testing" do