Skip to content

Commit 087c021

Browse files
committed
Improve DebugTransport
1 parent 37b4261 commit 087c021

File tree

3 files changed

+74
-45
lines changed

3 files changed

+74
-45
lines changed

sentry-ruby/lib/sentry/test_helper.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ module Sentry
44
module TestHelper
55
DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42"
66

7+
# Not really real, but it will be resolved as a non-local for testing needs
8+
REAL_DSN = "https://user:pass@getsentry.io/project/42"
9+
710
# Alters the existing SDK configuration with test-suitable options. Mainly:
811
# - Sets a dummy DSN instead of `nil` or an actual DSN.
912
# - Sets the transport to DummyTransport, which allows easy access to the captured events.

sentry-ruby/lib/sentry/transport/debug_transport.rb

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,36 @@
22

33
require "json"
44
require "fileutils"
5+
require "pathname"
6+
require "delegate"
57

68
module Sentry
79
# DebugTransport is a transport that logs events to a file for debugging purposes.
810
#
911
# It can optionally also send events to Sentry via HTTP transport if a real DSN
1012
# is provided.
13+
class DebugTransport < SimpleDelegator
14+
DEFAULT_LOG_FILE_PATH = File.join("log", "sentry_debug_events.log")
1115

12-
DEFAULT_LOG_FILE_PATH = File.join("log", "sentry_debug_events.log")
16+
attr_reader :log_file, :backend
1317

14-
class DebugTransport < Transport
15-
attr_reader :log_file_path, :http_transport
18+
alias_method :__getobj, :backend
1619

1720
def initialize(configuration)
18-
super
21+
@log_file = initialize_log_file(configuration)
22+
@backend = initialize_backend(configuration)
1923

20-
@log_file_path = configuration.sdk_debug_transport_log_file || DEFAULT_LOG_FILE_PATH
21-
22-
FileUtils.mkdir_p(File.dirname(@log_file_path))
23-
24-
log_debug("DebugTransport: Initialized with log file: #{@log_file_path}")
25-
26-
if configuration.dsn && !configuration.dsn.to_s.include?("localhost")
27-
@http_transport = Sentry::HTTPTransport.new(configuration)
28-
log_debug("DebugTransport: Initialized with HTTP transport for DSN: #{configuration.dsn}")
29-
else
30-
@http_transport = nil
31-
log_debug("DebugTransport: Using local-only mode for DSN: #{configuration.dsn}")
32-
end
24+
super(@backend)
3325
end
3426

3527
def send_event(event)
36-
envelope = envelope_from_event(event)
37-
send_envelope(envelope)
38-
event
28+
backend.send_event(event)
29+
30+
send_envelope(envelope_from_event(event))
3931
end
4032

4133
def send_envelope(envelope)
42-
envelope_data = {
34+
envelope_json = {
4335
timestamp: Time.now.utc.iso8601,
4436
envelope_headers: envelope.headers,
4537
items: envelope.items.map do |item|
@@ -50,26 +42,37 @@ def send_envelope(envelope)
5042
end
5143
}
5244

53-
File.open(log_file_path, "a") do |file|
54-
file << JSON.dump(envelope_data) << "\n"
55-
end
45+
File.open(log_file, "a") { |file| file << JSON.dump(envelope_json) << "\n" }
5646

57-
if http_transport
58-
http_transport.send_envelope(envelope)
59-
end
47+
backend.send_envelope(envelope)
6048
end
6149

62-
def events
63-
return [] unless File.exist?(log_file_path)
50+
def logged_envelopes
51+
return [] unless File.exist?(log_file)
6452

65-
File.readlines(log_file_path).map do |line|
53+
File.readlines(log_file).map do |line|
6654
JSON.parse(line)
6755
end
6856
end
6957

7058
def clear
71-
File.write(log_file_path, "")
72-
log_debug("DebugTransport: Cleared events from #{log_file_path}")
59+
File.write(log_file, "")
60+
log_debug("DebugTransport: Cleared events from #{log_file}")
61+
end
62+
63+
private
64+
65+
def initialize_backend(configuration)
66+
backend = configuration.dsn.local? ? DummyTransport : HTTPTransport
67+
backend.new(configuration)
68+
end
69+
70+
def initialize_log_file(configuration)
71+
log_file = Pathname(configuration.sdk_debug_transport_log_file || DEFAULT_LOG_FILE_PATH).realpath
72+
73+
FileUtils.mkdir_p(log_file.dirname) unless log_file.dirname.exist?
74+
75+
log_file
7376
end
7477
end
7578
end
Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
# frozen_string_literal: true
22

3-
require 'contexts/with_request_mock'
4-
53
RSpec.describe Sentry do
6-
include_context "with request mock"
7-
84
let(:client) { Sentry.get_current_client }
95
let(:transport) { Sentry.get_current_client.transport }
6+
let(:error) { StandardError.new("test error") }
107

11-
before :all do
8+
before do
129
perform_basic_setup
13-
end
1410

15-
before do
1611
setup_sentry_test do |config|
12+
config.dsn = dsn
1713
config.transport.transport_class = Sentry::DebugTransport
1814
end
1915
end
@@ -22,15 +18,42 @@
2218
teardown_sentry_test
2319
end
2420

25-
describe ".send_event" do
26-
let(:event) { Sentry.get_current_client.event_from_message("test message") }
21+
context "with local DSN for testing" do
22+
let(:dsn) { Sentry::TestHelper::DUMMY_DSN }
23+
24+
describe ".capture_exception with debug transport" do
25+
it "logs envelope data and stores an event internally" do
26+
Sentry.capture_exception(error)
27+
28+
expect(transport.events.count).to be(1)
29+
30+
event = transport.logged_envelopes.last
31+
item = event["items"].first
32+
payload = item["payload"]
33+
34+
expect(payload["exception"]["values"].first["value"]).to include("test error")
35+
end
36+
end
37+
end
38+
39+
context "with a real DSN for testing" do
40+
let(:dsn) { Sentry::TestHelper::REAL_DSN }
41+
42+
describe ".capture_exception with debug transport" do
43+
it "sends an event and logs envelope" do
44+
stub_request(:post, "https://getsentry.io/project/api/42/envelope/")
45+
.to_return(status: 200, body: "", headers: {})
46+
47+
Sentry.capture_exception(error)
2748

28-
it "sends the event and logs to a file" do
29-
sentry_stub_request(build_fake_response("200"))
49+
expect(transport.logged_envelopes.count).to be(1)
3050

31-
Sentry.send_event(event)
51+
event = transport.logged_envelopes.last
52+
item = event["items"].first
53+
payload = item["payload"]
3254

33-
expect(transport.events.count).to be(1)
55+
expect(payload["exception"]["values"].first["value"]).to include("test error")
56+
end
3457
end
3558
end
3659
end

0 commit comments

Comments
 (0)