Skip to content

Commit 998b591

Browse files
committed
Compress event payload by default
Rules: - If `config.transport.encoding == "gzip"` and the event envelope's size is larger than 30kb, the envelope will be compressed. - If `config.transport.encoding == "gzip"` but the event envelope's size is smaller than 30kb, the envelope won't be compressed. - If `config.transport.encoding != "gzip"`, the event won't be compressed regardless how but it is.
1 parent f24fa95 commit 998b591

3 files changed

Lines changed: 90 additions & 20 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
module Sentry
22
class Transport
33
class Configuration
4-
attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :http_adapter, :faraday_builder, :transport_class
4+
attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :http_adapter, :faraday_builder,
5+
:transport_class, :encoding
56

67
def initialize
78
@ssl_verification = true
89
@open_timeout = 1
910
@timeout = 2
11+
@encoding = HTTPTransport::GZIP_ENCODING
1012
end
1113

1214
def transport_class=(klass)

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
require 'faraday'
2+
require 'zlib'
23

34
module Sentry
45
class HTTPTransport < Transport
5-
CONTENT_TYPE = 'application/json'
6+
GZIP_ENCODING = "gzip"
7+
GZIP_THRESHOLD = 1024 * 30
8+
CONTENT_TYPE = 'application/x-sentry-envelope'
9+
610
attr_reader :conn, :adapter
711

812
def initialize(*args)
@@ -13,8 +17,16 @@ def initialize(*args)
1317
end
1418

1519
def send_data(data)
20+
encoding = ""
21+
22+
if should_compress?(data)
23+
data = Zlib.gzip(data)
24+
encoding = GZIP_ENCODING
25+
end
26+
1627
conn.post @endpoint do |req|
1728
req.headers['Content-Type'] = CONTENT_TYPE
29+
req.headers['Content-Encoding'] = encoding
1830
req.headers['X-Sentry-Auth'] = generate_auth_header
1931
req.body = data
2032
end
@@ -31,6 +43,10 @@ def send_data(data)
3143

3244
private
3345

46+
def should_compress?(data)
47+
@transport_configuration.encoding == GZIP_ENCODING && data.bytesize >= GZIP_THRESHOLD
48+
end
49+
3450
def set_conn
3551
server = @dsn.server
3652

sentry-ruby/spec/sentry/transport/http_transport_spec.rb

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,92 @@
11
require 'spec_helper'
22

33
RSpec.describe Sentry::HTTPTransport do
4-
let(:client) { Sentry::Client.new(Sentry.configuration) }
5-
let(:event) { client.event_from_message("test") }
6-
subject { described_class.new(Sentry.configuration) }
7-
8-
describe "customizations" do
9-
before do
10-
Sentry.init do |c|
11-
c.dsn = 'http://12345@sentry.localdomain/sentry/42'
12-
end
4+
let(:configuration) do
5+
Sentry::Configuration.new.tap do |config|
6+
config.dsn = 'http://12345@sentry.localdomain/sentry/42'
137
end
8+
end
9+
let(:client) { Sentry::Client.new(configuration) }
10+
let(:event) { client.event_from_message("foobarbaz") }
11+
let(:data) do
12+
subject.encode(event.to_hash)
13+
end
1414

15+
subject { described_class.new(configuration) }
16+
17+
describe "customizations" do
1518
it 'sets a custom User-Agent' do
1619
expect(subject.conn.headers[:user_agent]).to eq("sentry-ruby/#{Sentry::VERSION}")
1720
end
1821

1922
it 'allows to customise faraday' do
2023
builder = spy('faraday_builder')
2124
expect(Faraday).to receive(:new).and_yield(builder)
22-
Sentry.configuration.transport.faraday_builder = proc { |b| b.request :instrumentation }
25+
configuration.transport.faraday_builder = proc { |b| b.request :instrumentation }
2326

2427
subject
2528

2629
expect(builder).to have_received(:request).with(:instrumentation)
2730
end
2831
end
2932

33+
describe "request payload" do
34+
let(:compressed_stubs) do
35+
Faraday::Adapter::Test::Stubs.new do |stub|
36+
stub.post('sentry/api/42/envelope/') do |env|
37+
expect(env.request_headers["Content-Type"]).to eq("application/x-sentry-envelope")
38+
expect(env.request_headers["Content-Encoding"]).to eq("gzip")
39+
40+
envelope = Zlib.gunzip(env.body)
41+
expect(envelope).to include(event.event_id)
42+
expect(envelope).to include("foobarbaz")
43+
end
44+
end
45+
end
46+
47+
let(:uncompressed_stubs) do
48+
Faraday::Adapter::Test::Stubs.new do |stub|
49+
stub.post('sentry/api/42/envelope/') do |env|
50+
expect(env.request_headers["Content-Type"]).to eq("application/x-sentry-envelope")
51+
expect(env.request_headers["Content-Encoding"]).to eq("")
52+
53+
envelope = env.body
54+
expect(envelope).to include(event.event_id)
55+
expect(envelope).to include("foobarbaz")
56+
end
57+
end
58+
end
59+
60+
it "compresses data by default" do
61+
configuration.transport.http_adapter = [:test, compressed_stubs]
62+
63+
subject.send_data(data)
64+
compressed_stubs.verify_stubbed_calls
65+
end
66+
67+
it "doesn't compress small event" do
68+
configuration.transport.http_adapter = [:test, uncompressed_stubs]
69+
70+
event.instance_variable_set(:@threads, nil) # shrink event
71+
72+
subject.send_data(data)
73+
uncompressed_stubs.verify_stubbed_calls
74+
end
75+
76+
it "doesn't compress data if the encoding is not gzip" do
77+
configuration.transport.http_adapter = [:test, uncompressed_stubs]
78+
configuration.transport.encoding = "json"
79+
80+
subject.send_data(data)
81+
uncompressed_stubs.verify_stubbed_calls
82+
end
83+
end
84+
3085
describe "failed request handling" do
3186
before do
32-
Sentry.init do |c|
33-
c.dsn = 'http://12345@sentry.localdomain/sentry/42'
34-
c.transport.http_adapter = [:test, stubs]
35-
c.transport.transport_class = described_class
36-
end
87+
configuration.transport.http_adapter = [:test, stubs]
3788
end
89+
3890
context "receive 4xx responses" do
3991
let(:stubs) do
4092
Faraday::Adapter::Test::Stubs.new do |stub|
@@ -43,7 +95,7 @@
4395
end
4496

4597
it 'raises an error' do
46-
expect { subject.send_data(event.to_hash) }.to raise_error(Sentry::Error, /the server responded with status 404/)
98+
expect { subject.send_data(data) }.to raise_error(Sentry::Error, /the server responded with status 404/)
4799

48100
stubs.verify_stubbed_calls
49101
end
@@ -57,7 +109,7 @@
57109
end
58110

59111
it 'raises an error' do
60-
expect { subject.send_data(event.to_hash) }.to raise_error(Sentry::Error, /the server responded with status 500/)
112+
expect { subject.send_data(data) }.to raise_error(Sentry::Error, /the server responded with status 500/)
61113

62114
stubs.verify_stubbed_calls
63115
end
@@ -71,7 +123,7 @@
71123
end
72124

73125
it 'raises an error with header' do
74-
expect { subject.send_data(event.to_hash) }.to raise_error(Sentry::Error, /error_in_header/)
126+
expect { subject.send_data(data) }.to raise_error(Sentry::Error, /error_in_header/)
75127

76128
stubs.verify_stubbed_calls
77129
end

0 commit comments

Comments
 (0)