-
-
Notifications
You must be signed in to change notification settings - Fork 516
Add Sentry::DebugTransport for testing/debugging #2664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# frozen_string_literal: true | ||
|
||
require "json" | ||
require "fileutils" | ||
require "pathname" | ||
require "delegate" | ||
|
||
module Sentry | ||
# DebugTransport is a transport that logs events to a file for debugging purposes. | ||
# | ||
# It can optionally also send events to Sentry via HTTP transport if a real DSN | ||
# is provided. | ||
class DebugTransport < SimpleDelegator | ||
DEFAULT_LOG_FILE_PATH = File.join("log", "sentry_debug_events.log") | ||
|
||
attr_reader :log_file, :backend | ||
|
||
def initialize(configuration) | ||
@log_file = initialize_log_file(configuration) | ||
@backend = initialize_backend(configuration) | ||
|
||
super(@backend) | ||
end | ||
|
||
def send_event(event) | ||
log_envelope(envelope_from_event(event)) | ||
backend.send_event(event) | ||
end | ||
solnic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def log_envelope(envelope) | ||
envelope_json = { | ||
timestamp: Time.now.utc.iso8601, | ||
envelope_headers: envelope.headers, | ||
items: envelope.items.map do |item| | ||
{ headers: item.headers, payload: item.payload } | ||
end | ||
} | ||
|
||
File.open(log_file, "a") { |file| file << JSON.dump(envelope_json) << "\n" } | ||
end | ||
|
||
def logged_envelopes | ||
return [] unless File.exist?(log_file) | ||
|
||
File.readlines(log_file).map do |line| | ||
JSON.parse(line) | ||
end | ||
end | ||
|
||
def clear | ||
File.write(log_file, "") | ||
log_debug("DebugTransport: Cleared events from #{log_file}") | ||
end | ||
|
||
private | ||
|
||
def initialize_backend(configuration) | ||
backend = configuration.dsn.local? ? DummyTransport : HTTPTransport | ||
backend.new(configuration) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
end | ||
|
||
def initialize_log_file(configuration) | ||
log_file = Pathname(configuration.sdk_debug_transport_log_file || DEFAULT_LOG_FILE_PATH) | ||
|
||
FileUtils.mkdir_p(log_file.dirname) unless log_file.dirname.exist? | ||
solnic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
log_file | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ def initialize(*) | |
|
||
def send_event(event) | ||
@events << event | ||
super | ||
end | ||
|
||
def send_envelope(envelope) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -667,11 +667,15 @@ def will_be_sampled_by_sdk | |
|
||
Sentry.session_flusher.flush | ||
|
||
expect(sentry_envelopes.count).to eq(1) | ||
envelope = sentry_envelopes.first | ||
expect(sentry_envelopes.count).to eq(3) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why did these values change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sl0thentr0py because the test actually sends 2 errors and flushes session which sends another event, so total is 3 envelopes, previously dummy transport wouldn't catch 2 other envelopes |
||
|
||
expect(envelope.items.length).to eq(1) | ||
item = envelope.items.first | ||
session_envelope = sentry_envelopes.find do |envelope| | ||
envelope.items.any? { |item| item.type == 'sessions' } | ||
end | ||
|
||
expect(session_envelope).not_to be_nil | ||
expect(session_envelope.items.length).to eq(1) | ||
item = session_envelope.items.first | ||
expect(item.type).to eq('sessions') | ||
expect(item.payload[:attrs]).to eq({ release: 'test-release', environment: 'test' }) | ||
expect(item.payload[:aggregates].first).to eq({ exited: 10, errored: 2, started: now_bucket.iso8601 }) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe Sentry do | ||
let(:client) { Sentry.get_current_client } | ||
let(:transport) { Sentry.get_current_client.transport } | ||
let(:error) { StandardError.new("test error") } | ||
|
||
before do | ||
perform_basic_setup | ||
|
||
setup_sentry_test do |config| | ||
config.dsn = dsn | ||
config.transport.transport_class = Sentry::DebugTransport | ||
config.debug = true | ||
end | ||
end | ||
|
||
after do | ||
teardown_sentry_test | ||
end | ||
|
||
context "with local DSN for testing" do | ||
let(:dsn) { Sentry::TestHelper::DUMMY_DSN } | ||
|
||
describe ".capture_exception with debug transport" do | ||
it "logs envelope data and stores an event internally" do | ||
Sentry.capture_exception(error) | ||
|
||
expect(transport.events.count).to be(1) | ||
expect(transport.backend.events.count).to be(1) | ||
expect(transport.backend.envelopes.count).to be(1) | ||
|
||
event = transport.logged_envelopes.last | ||
item = event["items"].first | ||
payload = item["payload"] | ||
|
||
expect(payload["exception"]["values"].first["value"]).to include("test error") | ||
end | ||
end | ||
end | ||
|
||
context "with a real DSN for testing" do | ||
let(:dsn) { Sentry::TestHelper::REAL_DSN } | ||
|
||
describe ".capture_exception with debug transport" do | ||
it "sends an event and logs envelope" do | ||
stub_request(:post, "https://getsentry.io/project/api/42/envelope/") | ||
.to_return(status: 200, body: "", headers: {}) | ||
|
||
Sentry.capture_exception(error) | ||
|
||
expect(transport.logged_envelopes.count).to be(1) | ||
|
||
event = transport.logged_envelopes.last | ||
item = event["items"].first | ||
payload = item["payload"] | ||
|
||
expect(payload["exception"]["values"].first["value"]).to include("test error") | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -390,7 +390,8 @@ | |
|
||
Sentry.get_current_client.flush | ||
|
||
expect(sentry_envelopes.size).to be(2) | ||
# 3 envelopes: log, transaction, and client_report about dropped profile | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we actually shouldn't be sending the dropped profile client report here since we don't have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sl0thentr0py yeah it seemed suspicious, I reported an issue about this #2669 |
||
expect(sentry_envelopes.size).to be(3) | ||
|
||
log_event = sentry_logs.first | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,6 +79,14 @@ | |
end | ||
|
||
config.after(:each) do | ||
if Sentry.initialized? | ||
transport = Sentry.get_current_client&.transport | ||
|
||
if transport.is_a?(Sentry::DebugTransport) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we aren't actually using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sl0thentr0py another PR will actually use this in a couple of e2e test |
||
transport.clear | ||
end | ||
end | ||
|
||
reset_sentry_globals! | ||
end | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.