Skip to content

Commit 7980187

Browse files
committed
Unify LogEventBuffer and MetricEventBuffer logic
1 parent 846c2ba commit 7980187

File tree

10 files changed

+325
-500
lines changed

10 files changed

+325
-500
lines changed

sentry-ruby/lib/sentry/client.rb

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def capture_event(event, scope, hint = {})
107107
# @return [LogEvent]
108108
def buffer_log_event(event, scope)
109109
return unless event.is_a?(LogEvent)
110-
@log_event_buffer.add_event(scope.apply_to_telemetry(event))
110+
@log_event_buffer.add_item(scope.apply_to_telemetry(event))
111111
event
112112
end
113113

@@ -117,7 +117,7 @@ def buffer_log_event(event, scope)
117117
def buffer_metric_event(event, scope)
118118
return unless event.is_a?(MetricEvent)
119119
event = scope.apply_to_telemetry(event)
120-
@metric_event_buffer.add_metric(event)
120+
@metric_event_buffer.add_item(event)
121121
event
122122
end
123123

@@ -295,104 +295,6 @@ def send_event(event, hint = nil)
295295
raise
296296
end
297297

298-
# Send an envelope with batched logs
299-
# @param log_events [Array<LogEvent>] the log events to be sent
300-
# @api private
301-
# @return [void]
302-
def send_logs(log_events)
303-
envelope = Envelope.new(
304-
event_id: Sentry::Utils.uuid,
305-
sent_at: Sentry.utc_now.iso8601,
306-
dsn: configuration.dsn,
307-
sdk: Sentry.sdk_meta
308-
)
309-
310-
discarded_count = 0
311-
envelope_items = []
312-
313-
if configuration.before_send_log
314-
log_events.each do |log_event|
315-
processed_log_event = configuration.before_send_log.call(log_event)
316-
317-
if processed_log_event
318-
envelope_items << processed_log_event.to_h
319-
else
320-
discarded_count += 1
321-
end
322-
end
323-
324-
envelope_items
325-
else
326-
envelope_items = log_events.map(&:to_h)
327-
end
328-
329-
envelope.add_item(
330-
{
331-
type: "log",
332-
item_count: envelope_items.size,
333-
content_type: "application/vnd.sentry.items.log+json"
334-
},
335-
{ items: envelope_items }
336-
)
337-
338-
send_envelope(envelope)
339-
340-
unless discarded_count.zero?
341-
transport.record_lost_event(:before_send, "log_item", num: discarded_count)
342-
end
343-
end
344-
345-
# Send an envelope with batched metrics
346-
# @param metrics [Array<MetricEvent>] the metrics to send
347-
# @api private
348-
# @return [void]
349-
def send_metrics(metrics)
350-
return if metrics.nil? || metrics.empty?
351-
352-
envelope = Envelope.new(
353-
event_id: Sentry::Utils.uuid,
354-
sent_at: Sentry.utc_now.iso8601,
355-
dsn: configuration.dsn,
356-
sdk: Sentry.sdk_meta
357-
)
358-
359-
discarded_count = 0
360-
envelope_items = []
361-
362-
if configuration.before_send_metric
363-
metrics.each do |metric|
364-
processed_metric = configuration.before_send_metric.call(metric)
365-
366-
if processed_metric
367-
envelope_items << processed_metric.to_h
368-
else
369-
discarded_count += 1
370-
end
371-
end
372-
373-
envelope_items
374-
else
375-
envelope_items = metrics.map(&:to_h)
376-
end
377-
378-
return if envelope_items.empty?
379-
380-
envelope.add_item(
381-
{
382-
type: "trace_metric",
383-
item_count: envelope_items.size,
384-
content_type: "application/vnd.sentry.items.trace-metric+json"
385-
},
386-
{ items: envelope_items }
387-
)
388-
389-
send_envelope(envelope)
390-
391-
unless discarded_count.zero?
392-
transport.record_lost_event(:before_send, "metric", num: discarded_count)
393-
end
394-
end
395-
396298
# Send an envelope directly to Sentry.
397299
# @param envelope [Envelope] the envelope to be sent.
398300
# @return [void]

sentry-ruby/lib/sentry/envelope/item.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Envelope::Item
1515
# rate limits and client reports use the data_category rather than envelope item type
1616
def self.data_category(type)
1717
case type
18-
when "session", "attachment", "transaction", "profile", "span", "log", "trace_metric" then type
18+
when "session", "attachment", "transaction", "profile", "span", "trace_metric" then type
19+
when "log" then "log_item"
1920
when "sessions" then "session"
2021
when "check_in" then "monitor"
2122
when "event" then "error"
Lines changed: 11 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,26 @@
11
# frozen_string_literal: true
22

3-
require "sentry/threaded_periodic_worker"
3+
require "sentry/telemetry_event_buffer"
44

55
module Sentry
66
# LogEventBuffer buffers log events and sends them to Sentry in a single envelope.
77
#
88
# This is used internally by the `Sentry::Client`.
99
#
1010
# @!visibility private
11-
class LogEventBuffer < ThreadedPeriodicWorker
12-
FLUSH_INTERVAL = 5 # seconds
11+
class LogEventBuffer < TelemetryEventBuffer
1312
DEFAULT_MAX_EVENTS = 100
1413

15-
# @!visibility private
16-
attr_reader :pending_events
17-
1814
def initialize(configuration, client)
19-
super(configuration.sdk_logger, FLUSH_INTERVAL)
20-
21-
@client = client
22-
@pending_events = []
23-
@max_events = configuration.max_log_events || DEFAULT_MAX_EVENTS
24-
@mutex = Mutex.new
25-
26-
log_debug("[Logging] Initialized buffer with max_events=#{@max_events}, flush_interval=#{FLUSH_INTERVAL}s")
27-
end
28-
29-
def start
30-
ensure_thread
31-
self
32-
end
33-
34-
def flush
35-
@mutex.synchronize do
36-
return if empty?
37-
38-
log_debug("[LogEventBuffer] flushing #{size} log events")
39-
40-
send_events
41-
end
42-
43-
log_debug("[LogEventBuffer] flushed #{size} log events")
44-
45-
self
46-
end
47-
alias_method :run, :flush
48-
49-
def add_event(event)
50-
raise ArgumentError, "expected a LogEvent, got #{event.class}" unless event.is_a?(LogEvent)
51-
52-
@mutex.synchronize do
53-
@pending_events << event
54-
send_events if size >= @max_events
55-
end
56-
57-
self
58-
end
59-
60-
def empty?
61-
@pending_events.empty?
62-
end
63-
64-
def size
65-
@pending_events.size
66-
end
67-
68-
def clear!
69-
@pending_events.clear
70-
end
71-
72-
private
73-
74-
def send_events
75-
@client.send_logs(@pending_events)
76-
rescue => e
77-
log_debug("[LogEventBuffer] Failed to send logs: #{e.message}")
78-
ensure
79-
clear!
15+
super(
16+
configuration,
17+
client,
18+
event_class: LogEvent,
19+
max_items: configuration.max_log_events || DEFAULT_MAX_EVENTS,
20+
envelope_type: "log",
21+
envelope_content_type: "application/vnd.sentry.items.log+json",
22+
before_send: configuration.before_send_log
23+
)
8024
end
8125
end
8226
end
Lines changed: 11 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,26 @@
11
# frozen_string_literal: true
22

3-
require "sentry/threaded_periodic_worker"
3+
require "sentry/telemetry_event_buffer"
44

55
module Sentry
66
# MetricEventBuffer buffers metric events and sends them to Sentry in a single envelope.
77
#
88
# This is used internally by the `Sentry::Client`.
99
#
1010
# @!visibility private
11-
class MetricEventBuffer < ThreadedPeriodicWorker
12-
FLUSH_INTERVAL = 5 # seconds
11+
class MetricEventBuffer < TelemetryEventBuffer
1312
DEFAULT_MAX_METRICS = 100
1413

15-
# @!visibility private
16-
attr_reader :pending_metrics
17-
1814
def initialize(configuration, client)
19-
super(configuration.sdk_logger, FLUSH_INTERVAL)
20-
21-
@client = client
22-
@pending_metrics = []
23-
@max_metrics = configuration.max_metric_events || DEFAULT_MAX_METRICS
24-
@mutex = Mutex.new
25-
26-
log_debug("[Metrics] Initialized buffer with max_metrics=#{@max_metrics}, flush_interval=#{FLUSH_INTERVAL}s")
27-
end
28-
29-
def start
30-
ensure_thread
31-
self
32-
end
33-
34-
def flush
35-
@mutex.synchronize do
36-
return if empty?
37-
38-
log_debug("[MetricEventBuffer] flushing #{size} metrics")
39-
40-
send_metrics
41-
end
42-
end
43-
alias_method :run, :flush
44-
45-
def add_metric(metric)
46-
raise ArgumentError, "expected a MetricEvent, got #{metric.class}" unless metric.is_a?(MetricEvent)
47-
48-
@mutex.synchronize do
49-
@pending_metrics << metric
50-
send_metrics if size >= @max_metrics
51-
end
52-
53-
self
54-
end
55-
56-
def empty?
57-
@pending_metrics.empty?
58-
end
59-
60-
def size
61-
@pending_metrics.size
62-
end
63-
64-
def clear!
65-
@pending_metrics.clear
66-
end
67-
68-
private
69-
70-
def send_metrics
71-
@client.send_metrics(@pending_metrics)
72-
rescue => e
73-
log_debug("[MetricEventBuffer] Failed to send metrics: #{e.message}")
74-
ensure
75-
clear!
15+
super(
16+
configuration,
17+
client,
18+
event_class: MetricEvent,
19+
max_items: configuration.max_metric_events || DEFAULT_MAX_METRICS,
20+
envelope_type: "trace_metric",
21+
envelope_content_type: "application/vnd.sentry.items.trace-metric+json",
22+
before_send: configuration.before_send_metric
23+
)
7624
end
7725
end
7826
end

0 commit comments

Comments
 (0)