안녕하세요!
디스코urs에서 Sentry를 사용하려고 할 때 발견한 버그에 대해 아이디어가 있는지 확인하려고 여기에 게시글을 올렸습니다. 백그라운드 작업과 서버에서 발생된 모든 에러를 수집하기 위해 Sentry(오픈소스 Glitchtip 서버 구현체: https://glitchtip.com/ )를 사용하고자 합니다. 디스코urs에는 자체 에러 수집 기능인 Logster가 있다는 것을 알고 있지만, 발생된 모든 에러를 추적하고 더 많은 컨텍스트로 검사하기 위해 Sentry 사용을 시도해 보았습니다.
Sentry 설정을 포함하는 초기화 파일(initializer)을 추가했습니다:
Sentry.init do |config|
config.breadcrumbs_logger = [:active_support_logger, :http_logger]
config.dsn = ENV['SENTRY_DSN']
end
그런데 rake 작업과 sidekiq 작업의 HTTP 호출 중에 무한 재귀(infinite recursion)가 발생하는 것을 발견했습니다. (Sentry를 추가하기 전에는 정상적으로 종료되던 작업들이었습니다.) sentry-ruby에 오픈한 Github 이슈에서 더 자세한 내용과 재현 방법을 확인할 수 있습니다:
opened 09:40PM - 06 Feb 23 UTC
closed 06:32PM - 13 Feb 23 UTC
sentry-ruby
Bug
### Issue Description
Hello!
I am coming across an error trying to use the… sentry ruby bindings on with a rails app, during a rake task. The task uploads the precompiled assets to an S3 server. It exits cleanly without the sentry integration, but when I add it, it enters into an infinitely recursive loop with the patched HTTP module. I am not sure how to debug this further or what to do.
Thank you!
### Reproduction Steps
**edited with simpler steps**:
```bash
$ git clone https://github.com/saulshanabrook/discourse-hosting
$ cd discourse-hosting
$ echo 'HOSTNAME=any-domain.com' > .env
$ docker compose run --rm upload_assets
```
Following the steps of https://github.com/saulshanabrook/discourse-hosting#local-development-with-docker-compose the error will be raised when running `docker compose run --rm upload_assets`:
### Expected Behavior
The command exits cleanly without an error
### Actual Behavior
It raises a `SystemStackError`:
```ruby
$ docker compose run --rm upload_assets
[+] Running 4/0
⠿ Container discourse-hosting-db-1 Running 0.0s
⠿ Container discourse-hosting-minio-1 Running 0.0s
⠿ Container discourse-hosting-redis-1 Running 0.0s
⠿ Container discourse-hosting-glitchtip-web-1 Running 0.0s
** Invoke s3:upload_assets (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke s3:ensure_cors_rules (first_time)
** Invoke environment
** Execute s3:ensure_cors_rules
** Execute s3:upload_assets
rake aborted!
SystemStackError: stack level too deep
...
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:35:in `block in request'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/hub.rb:100:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry-ruby.rb:446:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:32:in `request'
(eval):5:in `request'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:35:in `block in request'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/hub.rb:100:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry-ruby.rb:446:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:32:in `request'
(eval):5:in `request'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:35:in `block in request'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/hub.rb:100:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry-ruby.rb:446:in `with_child_span'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/net/http.rb:32:in `request'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/connection_pool.rb:348:in `request'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:79:in `block in transmit'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:133:in `block in session'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/connection_pool.rb:104:in `session_for'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:128:in `session'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:76:in `transmit'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/net_http/handler.rb:50:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/content_length.rb:24:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:85:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:132:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:63:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_host_id.rb:17:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/xml/error_handler.rb:10:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/transfer_encoding.rb:26:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/helpful_socket_errors.rb:12:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/s3_signer.rb:110:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/redirects.rb:20:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/retry_errors.rb:360:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/http_checksum.rb:19:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/endpoint_pattern.rb:30:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:67:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:136:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/bucket_dns.rb:35:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:41:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/expect_100_continue.rb:22:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb:26:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/arn.rb:62:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/rest/handler.rb:10:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/recursion_detection.rb:18:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/user_agent.rb:13:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/endpoint.rb:47:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_validator.rb:26:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/arn.rb:88:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:27:in `call'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:56:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:111:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:22:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:71:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/response_target.rb:24:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/seahorse/client/request.rb:72:in `send_request'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/poller.rb:65:in `send_request'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/poller.rb:51:in `call'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:107:in `block in poll'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:104:in `loop'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:104:in `poll'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:94:in `block (2 levels) in wait'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:93:in `catch'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:93:in `block in wait'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:92:in `catch'
/usr/local/bundle/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/waiters/waiter.rb:92:in `wait'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/waiters.rb:123:in `wait'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/bucket.rb:98:in `wait_until_exists'
/usr/local/bundle/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/bucket.rb:79:in `exists?'
/var/www/discourse/lib/s3_helper.rb:404:in `s3_bucket'
/var/www/discourse/lib/s3_helper.rb:240:in `list'
/var/www/discourse/lib/tasks/s3.rake:14:in `existing_assets'
/var/www/discourse/lib/tasks/s3.rake:24:in `should_skip?'
/var/www/discourse/lib/tasks/s3.rake:36:in `upload'
/var/www/discourse/lib/tasks/s3.rake:192:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/s3.rake:192:in `each'
/var/www/discourse/lib/tasks/s3.rake:192:in `block in <main>'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'
/usr/local/bundle/gems/sentry-ruby-5.8.0/lib/sentry/rake.rb:26:in `execute'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:83:in `block in run'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:80:in `run'
/usr/local/lib/ruby/gems/3.1.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/rake:25:in `load'
/usr/local/bin/rake:25:in `<top (required)>'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli.rb:486:in `exec'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli.rb:31:in `dispatch'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/cli.rb:25:in `start'
/usr/local/bundle/gems/bundler-2.3.22/exe/bundle:48:in `block in <top (required)>'
/usr/local/bundle/gems/bundler-2.3.22/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
/usr/local/bundle/gems/bundler-2.3.22/exe/bundle:36:in `<top (required)>'
/usr/local/bundle/bin/bundle:25:in `load'
/usr/local/bundle/bin/bundle:25:in `<main>'
Tasks: TOP => s3:upload_assets
```
### Ruby Version
3.1
### SDK Version
sentry-ruby-5.8.0
### Integration and Its Version
_No response_
### Sentry Config
```ruby
Sentry.init do |config|
# this gem also provides a new breadcrumb logger that accepts instrumentations from ActiveSupport
# it's not activated by default, but you can enable it with
# config.breadcrumbs_logger = [:active_support_logger]
config.dsn = ENV['SENTRY_DSN']
end
```
지원되지 않는 discourse_docker 리포지토리를 사용하고 있다는 것을 알고 있지만, 다른 사람이 비슷한 에러를 겪어 보았거나 아이디어가 있는지 확인하려고 어쨌든 여기에 게시글을 올렸습니다.
기존의 discourse sentry 플러그인(Discourse Sentry )이 있지만, 이는 지원되지 않는 클라이언트 라이브러리(sentry-raven)를 사용하므로 사용하지 않기로 결정했습니다.
Sentry를 Discourse와 함께 사용하고자 하는 분들을 위해, 해당 패키지의 유지보수자 중 한 명이 제안된 수정 사항을 댓글로 남겼습니다 .
그들은 이 문제가 Discourse의 MethodProfiler에서 발생하고 있으며, 이 클래스가 alias_method를 사용한다고 설명했습니다(관련 코드 ). 두 도구가 함께 작동할 수 있도록, 점점 더 보편화되고 있는 prepend로 이를 대체할 것을 제안했습니다.
저는 Ruby에 충분히 숙련되지 않아 두 방식의 차이를 정확히 이해하지 못합니다. 당분간은 이 코드 부분을 주석 처리하여 Discourse의 메서드 프로파일링을 비활성화해 보겠습니다.