Skip to content

Possible memory leak when logs and metrics are enabled. #2963

@luizkowalski

Description

@luizkowalski

Issue Description

We saw steady memory growth in a Rails 8 production app after enabling Sentry SDK telemetry logs/metrics.

Image

Logs repeatedly showed: Envelope sending failed: deadlock; recursive locking [Sentry::MetricEventBuffer] Failed to send Sentry::MetricEvent: deadlock; recursive locking

After disabling it, memory stabilized around 700mb and live slots stabilized around ~3.4M, check this drop in the heap after disabling logs/metrics:

Image Image

Reproduction Steps

I didn't manage to reproduce the exact deadlock, but got something like this:

require "sentry-ruby"

class FailingTransport < Sentry::Transport
  def send_data(data, options = {})
    raise "forced transport failure"
  end
end

Sentry.init do |config|
  config.dsn = "https://public@example.com/1"
  config.enable_logs = true
  config.enable_metrics = true
  config.enabled_patches = %i[logger]
  config.transport.transport_class = FailingTransport
  config.sdk_logger.level = Logger::ERROR
end

2.times { Sentry.metrics.count("repro.counter", value: 1) }

sleep 6
Sentry.close

my Puma setup:

development = ENV["RAILS_ENV"] == "development"

threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
bind "tcp://0.0.0.0:#{ENV.fetch('PORT', 3000)}"

# workers ENV.fetch("WEB_CONCURRENCY", 4)
workers ENV.fetch("WEB_CONCURRENCY", development ? 2 : 1)

preload_app!

before_fork { Process.warmup }

activate_control_app

plugin :yabeda
plugin :tmp_restart

# Add this on_worker_boot callback to start the minutely probes in the Puma worker processes
before_worker_boot do
  SemanticLogger.reopen if defined?(SemanticLogger)
end

# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]

I'm running with 4 workers and 5 threads

Expected Behavior

Actual Behavior

Ruby Version

4.0.5 +YJIT

SDK Version

6.6.0

Integration and Its Version

Rails, Yabeda, Good Job

Sentry Config

config.enable_logs = true
config.enabled_patches = %i[logger]
config.enable_metrics = true
config.profiler_class = Sentry::Vernier::Profiler
config.profiles_sample_rate = 0.3
config.traces_sample_rate = 0.4

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions