Skip to content

Commit ea175f2

Browse files
committed
Have a higher max limit for TelemetryEventBuffer after which we
completely drop events * This is mainly to protect from memory blowup in high throughput scenarios * Also raised the Metric buffer limits to 1k/10k as compared to 100/1k for logs (consistent with Python)
1 parent a354683 commit ea175f2

File tree

5 files changed

+64
-10
lines changed

5 files changed

+64
-10
lines changed

sentry-ruby/lib/sentry/log_event_buffer.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ module Sentry
1010
# @!visibility private
1111
class LogEventBuffer < TelemetryEventBuffer
1212
DEFAULT_MAX_EVENTS = 100
13+
MAX_EVENTS_BEFORE_DROP = 1000
1314

1415
def initialize(configuration, client)
1516
super(
1617
configuration,
1718
client,
1819
event_class: LogEvent,
1920
max_items: configuration.max_log_events || DEFAULT_MAX_EVENTS,
21+
max_items_before_drop: MAX_EVENTS_BEFORE_DROP,
2022
envelope_type: "log",
2123
envelope_content_type: "application/vnd.sentry.items.log+json",
2224
before_send: configuration.before_send_log

sentry-ruby/lib/sentry/metric_event_buffer.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ module Sentry
99
#
1010
# @!visibility private
1111
class MetricEventBuffer < TelemetryEventBuffer
12-
DEFAULT_MAX_METRICS = 100
12+
DEFAULT_MAX_METRICS = 1000
13+
MAX_METRICS_BEFORE_DROP = 10_000
1314

1415
def initialize(configuration, client)
1516
super(
1617
configuration,
1718
client,
1819
event_class: MetricEvent,
1920
max_items: configuration.max_metric_events || DEFAULT_MAX_METRICS,
21+
max_items_before_drop: MAX_METRICS_BEFORE_DROP,
2022
envelope_type: "trace_metric",
2123
envelope_content_type: "application/vnd.sentry.items.trace-metric+json",
2224
before_send: configuration.before_send_metric

sentry-ruby/lib/sentry/telemetry_event_buffer.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@ class TelemetryEventBuffer < ThreadedPeriodicWorker
1414
FLUSH_INTERVAL = 5 # seconds
1515

1616
# @!visibility private
17-
attr_reader :pending_items
17+
attr_reader :pending_items, :envelope_type, :data_category
1818

19-
def initialize(configuration, client, event_class:, max_items:, envelope_type:, envelope_content_type:, before_send:)
19+
def initialize(configuration, client, event_class:, max_items:, max_items_before_drop:, envelope_type:, envelope_content_type:, before_send:)
2020
super(configuration.sdk_logger, FLUSH_INTERVAL)
2121

2222
@client = client
2323
@dsn = configuration.dsn
2424
@debug = configuration.debug
2525
@event_class = event_class
2626
@max_items = max_items
27+
@max_items_before_drop = max_items_before_drop
2728
@envelope_type = envelope_type
29+
@data_category = Sentry::Envelope::Item.data_category(@envelope_type)
2830
@envelope_content_type = envelope_content_type
2931
@before_send = before_send
3032

@@ -53,10 +55,16 @@ def flush
5355
alias_method :run, :flush
5456

5557
def add_item(item)
56-
raise ArgumentError, "expected a #{@event_class}, got #{item.class}" unless item.is_a?(@event_class)
58+
log_debug("[#{self.class}] expected a #{@event_class}, got #{item.class}") unless item.is_a?(@event_class)
5759

5860
@mutex.synchronize do
59-
@pending_items << item
61+
if size >= @max_items_before_drop
62+
log_debug("[#{self.class}] exceeded max capacity, dropping event")
63+
@client.transport.record_lost_event(:queue_overflow, @data_category)
64+
else
65+
@pending_items << item
66+
end
67+
6068
send_items if size >= @max_items
6169
end
6270

@@ -103,7 +111,6 @@ def send_items
103111
end
104112

105113
unless discarded_count.zero?
106-
@data_category = Sentry::Envelope::Item.data_category(@envelope_type)
107114
@client.transport.record_lost_event(:before_send, @data_category, num: discarded_count)
108115
end
109116

sentry-ruby/spec/sentry/configuration_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ class SentryConfigurationSample < Sentry::Configuration
771771

772772
describe "#max_metric_events" do
773773
it "returns 100 by default" do
774-
expect(subject.max_metric_events).to eq(100)
774+
expect(subject.max_metric_events).to eq(1000)
775775
end
776776

777777
it "can be set to an integer value" do

sentry-ruby/spec/support/shared_examples_for_telemetry_event_buffers.rb

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
RSpec.shared_examples "telemetry event buffer" do |event_factory:, max_items_config:, enable_config:|
44
let(:string_io) { StringIO.new }
5-
let(:logger) { ::Logger.new(string_io) }
6-
let(:client) { double(Sentry::Client) }
5+
let(:sdk_logger) { ::Logger.new(string_io) }
6+
let(:client) { Sentry.get_current_client }
77
let(:event) { event_factory.call }
88

99
before do
1010
perform_basic_setup do |config|
11-
config.sdk_logger = logger
11+
config.sdk_logger = sdk_logger
1212
config.background_worker_threads = 0
1313
config.public_send(:"#{max_items_config}=", max_items)
1414
config.public_send(:"#{enable_config}=", true)
@@ -67,6 +67,49 @@
6767
end
6868
end
6969

70+
describe "max capacity and dropping events" do
71+
let(:max_items) { 3 }
72+
let(:max_items_before_drop) { 10 }
73+
74+
before do
75+
subject.instance_variable_set(:@max_items_before_drop, max_items_before_drop)
76+
77+
# don't clear pending items to allow buffer to grow
78+
allow(subject).to receive(:clear!)
79+
end
80+
81+
it "adds items up to max_items_before_drop capacity" do
82+
expect {
83+
max_items_before_drop.times { subject.add_item(event) }
84+
}.to change { subject.size }.from(0).to(max_items_before_drop)
85+
end
86+
87+
it "drops events when buffer reaches max_items_before_drop" do
88+
max_items_before_drop.times { subject.add_item(event) }
89+
90+
expect {
91+
subject.add_item(event)
92+
}.not_to change { subject.size }
93+
94+
expect(subject.size).to eq(max_items_before_drop)
95+
end
96+
97+
it "records lost event when dropping due to queue overflow" do
98+
max_items_before_drop.times { subject.add_item(event) }
99+
100+
expect(client.transport).to receive(:record_lost_event).with(:queue_overflow, subject.data_category)
101+
102+
subject.add_item(event)
103+
end
104+
105+
it "logs debug message when dropping events" do
106+
max_items_before_drop.times { subject.add_item(event) }
107+
subject.add_item(event)
108+
109+
expect(string_io.string).to include("exceeded max capacity, dropping event")
110+
end
111+
end
112+
70113
describe "error handling" do
71114
let(:max_items) { 3 }
72115

0 commit comments

Comments
 (0)