sentry-raven 3.0.1 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.craft.yml +2 -1
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
  4. data/.github/pull_request_template.md +16 -0
  5. data/.github/workflows/test.yml +41 -26
  6. data/.github/workflows/zeus_upload.yml +32 -0
  7. data/.gitignore +1 -0
  8. data/.rubocop.yml +6 -3
  9. data/{changelog.md → CHANGELOG.md} +157 -7
  10. data/CONTRIBUTING.md +71 -0
  11. data/Gemfile +5 -2
  12. data/README.md +29 -14
  13. data/lib/raven/backtrace.rb +2 -0
  14. data/lib/raven/base.rb +2 -0
  15. data/lib/raven/breadcrumbs/active_support_logger.rb +25 -0
  16. data/lib/raven/breadcrumbs/logger.rb +2 -92
  17. data/lib/raven/breadcrumbs/sentry_logger.rb +73 -0
  18. data/lib/raven/cli.rb +8 -19
  19. data/lib/raven/client.rb +1 -1
  20. data/lib/raven/configuration.rb +81 -5
  21. data/lib/raven/context.rb +13 -8
  22. data/lib/raven/core_ext/object/deep_dup.rb +57 -0
  23. data/lib/raven/core_ext/object/duplicable.rb +153 -0
  24. data/lib/raven/event.rb +23 -13
  25. data/lib/raven/helpers/deprecation_helper.rb +17 -0
  26. data/lib/raven/instance.rb +10 -1
  27. data/lib/raven/integrations/delayed_job.rb +2 -1
  28. data/lib/raven/integrations/rack-timeout.rb +5 -1
  29. data/lib/raven/integrations/rack.rb +15 -2
  30. data/lib/raven/integrations/rails.rb +12 -3
  31. data/lib/raven/integrations/rails/active_job.rb +2 -1
  32. data/lib/raven/integrations/rails/backtrace_cleaner.rb +29 -0
  33. data/lib/raven/integrations/sidekiq.rb +4 -78
  34. data/lib/raven/integrations/sidekiq/cleanup_middleware.rb +13 -0
  35. data/lib/raven/integrations/sidekiq/error_handler.rb +38 -0
  36. data/lib/raven/processor/cookies.rb +1 -1
  37. data/lib/raven/processor/removecircularreferences.rb +2 -1
  38. data/lib/raven/transports/http.rb +0 -2
  39. data/lib/raven/utils/context_filter.rb +42 -0
  40. data/lib/raven/version.rb +1 -1
  41. data/lib/sentry-raven-without-integrations.rb +6 -1
  42. data/lib/sentry_raven_without_integrations.rb +1 -0
  43. data/sentry-ruby/.gitignore +11 -0
  44. data/sentry-ruby/.rspec +3 -0
  45. data/sentry-ruby/.travis.yml +6 -0
  46. data/sentry-ruby/CODE_OF_CONDUCT.md +74 -0
  47. data/sentry-ruby/Gemfile +9 -0
  48. data/sentry-ruby/LICENSE.txt +21 -0
  49. data/sentry-ruby/README.md +44 -0
  50. data/sentry-ruby/Rakefile +6 -0
  51. data/sentry-ruby/bin/console +14 -0
  52. data/sentry-ruby/bin/setup +8 -0
  53. data/sentry-ruby/examples/rails-6.0/.browserslistrc +1 -0
  54. data/sentry-ruby/examples/rails-6.0/.gitignore +35 -0
  55. data/sentry-ruby/examples/rails-6.0/Gemfile +58 -0
  56. data/sentry-ruby/examples/rails-6.0/README.md +23 -0
  57. data/sentry-ruby/examples/rails-6.0/Rakefile +6 -0
  58. data/sentry-ruby/examples/rails-6.0/app/assets/config/manifest.js +2 -0
  59. data/sentry-ruby/examples/rails-6.0/app/assets/images/.keep +0 -0
  60. data/sentry-ruby/examples/rails-6.0/app/assets/stylesheets/application.css +15 -0
  61. data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/channel.rb +4 -0
  62. data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/connection.rb +4 -0
  63. data/sentry-ruby/examples/rails-6.0/app/controllers/application_controller.rb +2 -0
  64. data/sentry-ruby/examples/rails-6.0/app/controllers/concerns/.keep +0 -0
  65. data/sentry-ruby/examples/rails-6.0/app/controllers/welcome_controller.rb +23 -0
  66. data/sentry-ruby/examples/rails-6.0/app/helpers/application_helper.rb +2 -0
  67. data/sentry-ruby/examples/rails-6.0/app/javascript/channels/consumer.js +6 -0
  68. data/sentry-ruby/examples/rails-6.0/app/javascript/channels/index.js +5 -0
  69. data/sentry-ruby/examples/rails-6.0/app/javascript/packs/application.js +17 -0
  70. data/sentry-ruby/examples/rails-6.0/app/jobs/application_job.rb +7 -0
  71. data/sentry-ruby/examples/rails-6.0/app/mailers/application_mailer.rb +4 -0
  72. data/sentry-ruby/examples/rails-6.0/app/models/application_record.rb +3 -0
  73. data/sentry-ruby/examples/rails-6.0/app/models/concerns/.keep +0 -0
  74. data/sentry-ruby/examples/rails-6.0/app/views/layouts/application.html.erb +15 -0
  75. data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.html.erb +13 -0
  76. data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.text.erb +1 -0
  77. data/sentry-ruby/examples/rails-6.0/app/views/welcome/report_demo.html.erb +22 -0
  78. data/sentry-ruby/examples/rails-6.0/app/views/welcome/view_error.html.erb +1 -0
  79. data/sentry-ruby/examples/rails-6.0/app/workers/error_worker.rb +7 -0
  80. data/sentry-ruby/examples/rails-6.0/babel.config.js +72 -0
  81. data/sentry-ruby/examples/rails-6.0/bin/bundle +114 -0
  82. data/sentry-ruby/examples/rails-6.0/bin/rails +9 -0
  83. data/sentry-ruby/examples/rails-6.0/bin/rake +9 -0
  84. data/sentry-ruby/examples/rails-6.0/bin/setup +36 -0
  85. data/sentry-ruby/examples/rails-6.0/bin/spring +17 -0
  86. data/sentry-ruby/examples/rails-6.0/bin/webpack +18 -0
  87. data/sentry-ruby/examples/rails-6.0/bin/webpack-dev-server +18 -0
  88. data/sentry-ruby/examples/rails-6.0/bin/yarn +11 -0
  89. data/sentry-ruby/examples/rails-6.0/config.ru +5 -0
  90. data/sentry-ruby/examples/rails-6.0/config/application.rb +28 -0
  91. data/sentry-ruby/examples/rails-6.0/config/boot.rb +4 -0
  92. data/sentry-ruby/examples/rails-6.0/config/cable.yml +10 -0
  93. data/sentry-ruby/examples/rails-6.0/config/credentials.yml.enc +1 -0
  94. data/sentry-ruby/examples/rails-6.0/config/database.yml +25 -0
  95. data/sentry-ruby/examples/rails-6.0/config/environment.rb +5 -0
  96. data/sentry-ruby/examples/rails-6.0/config/environments/development.rb +62 -0
  97. data/sentry-ruby/examples/rails-6.0/config/environments/production.rb +112 -0
  98. data/sentry-ruby/examples/rails-6.0/config/environments/test.rb +48 -0
  99. data/sentry-ruby/examples/rails-6.0/config/initializers/application_controller_renderer.rb +8 -0
  100. data/sentry-ruby/examples/rails-6.0/config/initializers/assets.rb +14 -0
  101. data/sentry-ruby/examples/rails-6.0/config/initializers/backtrace_silencers.rb +7 -0
  102. data/sentry-ruby/examples/rails-6.0/config/initializers/content_security_policy.rb +30 -0
  103. data/sentry-ruby/examples/rails-6.0/config/initializers/cookies_serializer.rb +5 -0
  104. data/sentry-ruby/examples/rails-6.0/config/initializers/filter_parameter_logging.rb +4 -0
  105. data/sentry-ruby/examples/rails-6.0/config/initializers/inflections.rb +16 -0
  106. data/sentry-ruby/examples/rails-6.0/config/initializers/mime_types.rb +4 -0
  107. data/sentry-ruby/examples/rails-6.0/config/initializers/wrap_parameters.rb +14 -0
  108. data/sentry-ruby/examples/rails-6.0/config/locales/en.yml +33 -0
  109. data/sentry-ruby/examples/rails-6.0/config/puma.rb +38 -0
  110. data/sentry-ruby/examples/rails-6.0/config/routes.rb +10 -0
  111. data/sentry-ruby/examples/rails-6.0/config/spring.rb +6 -0
  112. data/sentry-ruby/examples/rails-6.0/config/storage.yml +34 -0
  113. data/sentry-ruby/examples/rails-6.0/config/webpack/development.js +5 -0
  114. data/sentry-ruby/examples/rails-6.0/config/webpack/environment.js +3 -0
  115. data/sentry-ruby/examples/rails-6.0/config/webpack/production.js +5 -0
  116. data/sentry-ruby/examples/rails-6.0/config/webpack/test.js +5 -0
  117. data/sentry-ruby/examples/rails-6.0/config/webpacker.yml +96 -0
  118. data/sentry-ruby/examples/rails-6.0/db/seeds.rb +7 -0
  119. data/sentry-ruby/examples/rails-6.0/lib/assets/.keep +0 -0
  120. data/sentry-ruby/examples/rails-6.0/lib/tasks/.keep +0 -0
  121. data/sentry-ruby/examples/rails-6.0/package.json +15 -0
  122. data/sentry-ruby/examples/rails-6.0/postcss.config.js +12 -0
  123. data/sentry-ruby/examples/rails-6.0/public/404.html +67 -0
  124. data/sentry-ruby/examples/rails-6.0/public/422.html +67 -0
  125. data/sentry-ruby/examples/rails-6.0/public/500.html +66 -0
  126. data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon-precomposed.png +0 -0
  127. data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon.png +0 -0
  128. data/sentry-ruby/examples/rails-6.0/public/favicon.ico +0 -0
  129. data/sentry-ruby/examples/rails-6.0/public/robots.txt +1 -0
  130. data/sentry-ruby/examples/rails-6.0/storage/.keep +0 -0
  131. data/sentry-ruby/examples/rails-6.0/test/application_system_test_case.rb +5 -0
  132. data/sentry-ruby/examples/rails-6.0/test/channels/application_cable/connection_test.rb +11 -0
  133. data/sentry-ruby/examples/rails-6.0/test/controllers/.keep +0 -0
  134. data/sentry-ruby/examples/rails-6.0/test/fixtures/.keep +0 -0
  135. data/sentry-ruby/examples/rails-6.0/test/fixtures/files/.keep +0 -0
  136. data/sentry-ruby/examples/rails-6.0/test/helpers/.keep +0 -0
  137. data/sentry-ruby/examples/rails-6.0/test/integration/.keep +0 -0
  138. data/sentry-ruby/examples/rails-6.0/test/mailers/.keep +0 -0
  139. data/sentry-ruby/examples/rails-6.0/test/models/.keep +0 -0
  140. data/sentry-ruby/examples/rails-6.0/test/system/.keep +0 -0
  141. data/sentry-ruby/examples/rails-6.0/test/test_helper.rb +13 -0
  142. data/sentry-ruby/examples/rails-6.0/vendor/.keep +0 -0
  143. data/sentry-ruby/examples/rails-6.0/yarn.lock +7508 -0
  144. data/sentry-ruby/lib/sentry.rb +16 -0
  145. data/sentry-ruby/lib/sentry/backtrace.rb +128 -0
  146. data/sentry-ruby/lib/sentry/client.rb +162 -0
  147. data/sentry-ruby/lib/sentry/client/state.rb +40 -0
  148. data/sentry-ruby/lib/sentry/configuration.rb +533 -0
  149. data/sentry-ruby/lib/sentry/event.rb +209 -0
  150. data/sentry-ruby/lib/sentry/interface.rb +31 -0
  151. data/sentry-ruby/lib/sentry/interfaces/exception.rb +15 -0
  152. data/sentry-ruby/lib/sentry/interfaces/http.rb +16 -0
  153. data/sentry-ruby/lib/sentry/interfaces/message.rb +18 -0
  154. data/sentry-ruby/lib/sentry/interfaces/single_exception.rb +14 -0
  155. data/sentry-ruby/lib/sentry/interfaces/stack_trace.rb +69 -0
  156. data/sentry-ruby/lib/sentry/linecache.rb +44 -0
  157. data/sentry-ruby/lib/sentry/logger.rb +20 -0
  158. data/sentry-ruby/lib/sentry/transports.rb +19 -0
  159. data/sentry-ruby/lib/sentry/transports/dummy.rb +16 -0
  160. data/sentry-ruby/lib/sentry/transports/http.rb +66 -0
  161. data/sentry-ruby/lib/sentry/transports/stdout.rb +20 -0
  162. data/sentry-ruby/lib/sentry/utils/deep_merge.rb +22 -0
  163. data/sentry-ruby/lib/sentry/utils/exception_cause_chain.rb +20 -0
  164. data/sentry-ruby/lib/sentry/version.rb +3 -0
  165. data/sentry-ruby/sentry-ruby.gemspec +26 -0
  166. data/sentry-ruby/spec/sentry/backtrace_spec.rb +38 -0
  167. data/sentry-ruby/spec/sentry/client_spec.rb +443 -0
  168. data/sentry-ruby/spec/sentry/configuration_spec.rb +400 -0
  169. data/sentry-ruby/spec/sentry/event_spec.rb +238 -0
  170. data/sentry-ruby/spec/sentry/interface_spec.rb +38 -0
  171. data/sentry-ruby/spec/sentry/interfaces/stack_trace_spec.rb +11 -0
  172. data/sentry-ruby/spec/sentry/linecache_spec.rb +40 -0
  173. data/sentry-ruby/spec/sentry/transports/http_spec.rb +57 -0
  174. data/sentry-ruby/spec/sentry/transports/stdout_spec.rb +11 -0
  175. data/sentry-ruby/spec/sentry_spec.rb +9 -0
  176. data/sentry-ruby/spec/spec_helper.rb +49 -0
  177. data/sentry-ruby/spec/support/linecache.txt +6 -0
  178. metadata +152 -4
  179. data/lib/raven/breadcrumbs/activesupport.rb +0 -19
data/Gemfile CHANGED
@@ -2,9 +2,10 @@ source "https://rubygems.org/"
2
2
 
3
3
  gemspec
4
4
 
5
- rails_version = ENV["RAILS_VERSION"].to_f
5
+ rails_version = ENV["RAILS_VERSION"]
6
+ rails_version = "5.2" if rails_version.nil?
6
7
 
7
- if rails_version != 0
8
+ if rails_version.to_f != 0
8
9
  gem "rails", "~> #{rails_version}"
9
10
  gem "rspec-rails", "~> 4.0"
10
11
  end
@@ -16,7 +17,9 @@ gem "rack-timeout"
16
17
 
17
18
  gem "pry"
18
19
  gem "benchmark-ips"
20
+ gem "benchmark_driver"
19
21
  gem "benchmark-ipsa"
22
+ gem "benchmark-memory"
20
23
  gem "ruby-prof", platform: :mri
21
24
  gem "rake", "> 12"
22
25
  gem "rubocop", "~> 0.81.0"
data/README.md CHANGED
@@ -7,6 +7,11 @@
7
7
 
8
8
  # Raven-Ruby, the Ruby Client for Sentry
9
9
 
10
+ ### 🚧 We're restructuring this SDK for the [version 4.0](https://github.com/getsentry/raven-ruby/issues/1029) 🚧
11
+
12
+ ---
13
+
14
+
10
15
  [![Gem Version](https://img.shields.io/gem/v/sentry-raven.svg)](https://rubygems.org/gems/sentry-raven)
11
16
  ![Build Status](https://github.com/getsentry/raven-ruby/workflows/Test/badge.svg)
12
17
  [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/raven-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/raven-ruby/branch/master)
@@ -18,6 +23,7 @@
18
23
 
19
24
  The official Ruby-language client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API.
20
25
 
26
+
21
27
  ## Requirements
22
28
 
23
29
  We test on Ruby 2.3, 2.4, 2.5, 2.6 and 2.7 at the latest patchlevel/teeny version. We also support JRuby 9.0. Our Rails integration works with Rails 4.2+, including Rails 5 and Rails 6.
@@ -30,7 +36,7 @@ We test on Ruby 2.3, 2.4, 2.5, 2.6 and 2.7 at the latest patchlevel/teeny versio
30
36
  gem "sentry-raven"
31
37
  ```
32
38
 
33
- ### Raven only runs when SENTRY_DSN is set
39
+ ### Raven only runs when Sentry DSN is set
34
40
 
35
41
  Raven will capture and send exceptions to the Sentry server whenever its DSN is set. This makes environment-based configuration easy - if you don't want to send errors in a certain environment, just don't set the DSN in that environment!
36
42
 
@@ -39,7 +45,7 @@ Raven will capture and send exceptions to the Sentry server whenever its DSN is
39
45
  export SENTRY_DSN=http://public@example.com/project-id
40
46
  ```
41
47
  ```ruby
42
- # Or you can configure the client in the code (not recommended - keep your DSN secret!)
48
+ # Or you can configure the client in the code.
43
49
  Raven.configure do |config|
44
50
  config.dsn = 'http://public@example.com/project-id'
45
51
  end
@@ -49,11 +55,11 @@ end
49
55
 
50
56
  **Raven ignores some exceptions by default** - most of these are related to 404s or controller actions not being found. [For a complete list, see the `IGNORE_DEFAULT` constant](https://github.com/getsentry/raven-ruby/blob/master/lib/raven/configuration.rb).
51
57
 
52
- Raven doesn't report POST data or cookies by default. In addition, it will attempt to remove any obviously sensitive data, such as credit card or Social Security numbers. For more information about how Sentry processes your data, [check out the documentation on the `processors` config setting.](https://docs.getsentry.com/hosted/clients/ruby/config/)
58
+ Raven doesn't report POST data or cookies by default. In addition, it will attempt to remove any obviously sensitive data, such as credit card or Social Security numbers. For more information about how Sentry processes your data, [check out the documentation on the `processors` config setting.](https://docs.sentry.io/platforms/ruby/config/)
53
59
 
54
60
  ### Usage
55
61
 
56
- **If you use Rails, you're already done - no more configuration required!** Check [Integrations](https://docs.getsentry.com/hosted/clients/ruby/integrations/) for more details on other gems Sentry integrates with automatically.
62
+ **If you use Rails, you're already done - no more configuration required!** Check [Integrations](https://docs.sentry.io/platforms/ruby/integrations/) for more details on other gems Sentry integrates with automatically.
57
63
 
58
64
  Otherwise, Raven supports two methods of capturing exceptions:
59
65
 
@@ -105,26 +111,35 @@ end
105
111
  If Raven fails to send an event to Sentry for any reason (either the Sentry server has returned a 4XX or 5XX response), this Proc or lambda will be called.
106
112
 
107
113
  ```ruby
108
- config.transport_failure_callback = lambda { |event|
109
- AdminMailer.email_admins("Oh god, it's on fire!", event).deliver_later
114
+ config.transport_failure_callback = lambda { |event, error|
115
+ AdminMailer.email_admins("Oh god, it's on fire because #{error.message}!", event).deliver_later
110
116
  }
111
117
  ```
112
118
 
113
119
  #### Context
114
120
 
115
- Much of the usefulness of Sentry comes from additional context data with the events. Raven makes this very convenient by providing methods to set thread local context data that is then submitted automatically with all events.
116
-
117
- There are three primary methods for providing request context:
121
+ Much of the usefulness of Sentry comes from additional context data with the events. Raven makes this very convenient by providing methods to set thread local context data that is then submitted automatically with all events:
118
122
 
119
123
  ```ruby
120
- # bind the logged in user
121
124
  Raven.user_context email: 'foo@example.com'
122
125
 
123
- # tag the request with something interesting
124
- Raven.tags_context interesting: 'yes'
126
+ Raven.tags.merge!(interesting: 'yes')
127
+
128
+ Raven.extra.merge!(additional_info: 'foo')
129
+ ```
130
+
131
+ You can also use `tags_context` and `extra_context` to provide scoped information:
125
132
 
126
- # provide a bit of additional context
127
- Raven.extra_context happiness: 'very'
133
+ ```ruby
134
+ Raven.tags_context(interesting: 'yes') do
135
+ # the `interesting: 'yes'` tag will only present in the requests sent inside the block
136
+ Raven.capture_exception(exception)
137
+ end
138
+
139
+ Raven.extra_context(additional_info: 'foo') do
140
+ # same as above, the `additional_info` will only present in this request
141
+ Raven.capture_exception(exception)
142
+ end
128
143
  ```
129
144
 
130
145
  For more information, see [Context](https://docs.sentry.io/clients/ruby/context/).
@@ -94,6 +94,8 @@ module Raven
94
94
  def self.parse(backtrace, opts = {})
95
95
  ruby_lines = backtrace.is_a?(Array) ? backtrace : backtrace.split(/\n\s*/)
96
96
 
97
+ ruby_lines = opts[:configuration].backtrace_cleanup_callback.call(ruby_lines) if opts[:configuration]&.backtrace_cleanup_callback
98
+
97
99
  filters = opts[:filters] || []
98
100
  filtered_lines = ruby_lines.to_a.map do |line|
99
101
  filters.reduce(line) do |nested_line, proc|
@@ -1,4 +1,6 @@
1
1
  require 'raven/version'
2
+ require "raven/helpers/deprecation_helper"
3
+ require 'raven/core_ext/object/deep_dup'
2
4
  require 'raven/backtrace'
3
5
  require 'raven/breadcrumbs'
4
6
  require 'raven/processor'
@@ -0,0 +1,25 @@
1
+ module Raven
2
+ module Breadcrumbs
3
+ module ActiveSupportLogger
4
+ class << self
5
+ def add(name, started, _finished, _unique_id, data)
6
+ Raven.breadcrumbs.record do |crumb|
7
+ crumb.data = data
8
+ crumb.category = name
9
+ crumb.timestamp = started.to_i
10
+ end
11
+ end
12
+
13
+ def inject
14
+ @subscriber = ::ActiveSupport::Notifications.subscribe(/.*/) do |name, started, finished, unique_id, data|
15
+ add(name, started, finished, unique_id, data)
16
+ end
17
+ end
18
+
19
+ def detach
20
+ ::ActiveSupport::Notifications.unsubscribe(@subscriber)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,93 +1,3 @@
1
- require 'logger'
1
+ DeprecationHelper.deprecate_old_breadcrumbs_configuration(:sentry_logger)
2
2
 
3
- module Raven
4
- module BreadcrumbLogger
5
- LEVELS = {
6
- ::Logger::DEBUG => 'debug',
7
- ::Logger::INFO => 'info',
8
- ::Logger::WARN => 'warn',
9
- ::Logger::ERROR => 'error',
10
- ::Logger::FATAL => 'fatal'
11
- }.freeze
12
-
13
- EXC_FORMAT = /^([a-zA-Z0-9]+)\:\s(.*)$/.freeze
14
-
15
- def self.parse_exception(message)
16
- lines = message.split(/\n\s*/)
17
- # TODO: wat
18
- return nil unless lines.length > 2
19
-
20
- match = lines[0].match(EXC_FORMAT)
21
- return nil unless match
22
-
23
- _, type, value = match.to_a
24
- [type, value]
25
- end
26
-
27
- def add(*args)
28
- add_breadcrumb(*args)
29
- super
30
- end
31
-
32
- def add_breadcrumb(severity, message = nil, progname = nil)
33
- message = progname if message.nil? # see Ruby's Logger docs for why
34
- return if ignored_logger?(progname)
35
- return if message.nil? || message == ""
36
-
37
- # some loggers will add leading/trailing space as they (incorrectly, mind you)
38
- # think of logging as a shortcut to std{out,err}
39
- message = message.to_s.strip
40
-
41
- last_crumb = Raven.breadcrumbs.peek
42
- # try to avoid dupes from logger broadcasts
43
- if last_crumb.nil? || last_crumb.message != message
44
- error = Raven::BreadcrumbLogger.parse_exception(message)
45
- # TODO(dcramer): we need to filter out the "currently captured error"
46
- if error
47
- Raven.breadcrumbs.record do |crumb|
48
- crumb.level = Raven::BreadcrumbLogger::LEVELS.fetch(severity, nil)
49
- crumb.category = progname || 'error'
50
- crumb.type = 'error'
51
- crumb.data = {
52
- :type => error[0],
53
- :value => error[1]
54
- }
55
- end
56
- else
57
- Raven.breadcrumbs.record do |crumb|
58
- crumb.level = Raven::BreadcrumbLogger::LEVELS.fetch(severity, nil)
59
- crumb.category = progname || 'logger'
60
- crumb.message = message
61
- end
62
- end
63
- end
64
- end
65
-
66
- private
67
-
68
- def ignored_logger?(progname)
69
- progname == "sentry" ||
70
- Raven.configuration.exclude_loggers.include?(progname)
71
- end
72
- end
73
- module OldBreadcrumbLogger
74
- def self.included(base)
75
- base.class_eval do
76
- include Raven::BreadcrumbLogger
77
- alias_method :add_without_raven, :add
78
- alias_method :add, :add_with_raven
79
- end
80
- end
81
-
82
- def add_with_raven(*args)
83
- add_breadcrumb(*args)
84
- add_without_raven(*args)
85
- end
86
- end
87
- end
88
-
89
- Raven.safely_prepend(
90
- "BreadcrumbLogger",
91
- :from => Raven,
92
- :to => ::Logger
93
- )
3
+ require "raven/breadcrumbs/sentry_logger"
@@ -0,0 +1,73 @@
1
+ require 'logger'
2
+
3
+ module Raven
4
+ module Breadcrumbs
5
+ module SentryLogger
6
+ LEVELS = {
7
+ ::Logger::DEBUG => 'debug',
8
+ ::Logger::INFO => 'info',
9
+ ::Logger::WARN => 'warn',
10
+ ::Logger::ERROR => 'error',
11
+ ::Logger::FATAL => 'fatal'
12
+ }.freeze
13
+
14
+ def add(*args)
15
+ add_breadcrumb(*args)
16
+ super
17
+ end
18
+
19
+ def add_breadcrumb(severity, message = nil, progname = nil)
20
+ message = progname if message.nil? # see Ruby's Logger docs for why
21
+ return if ignored_logger?(progname)
22
+ return if message.nil? || message == ""
23
+
24
+ # some loggers will add leading/trailing space as they (incorrectly, mind you)
25
+ # think of logging as a shortcut to std{out,err}
26
+ message = message.to_s.strip
27
+
28
+ last_crumb = Raven.breadcrumbs.peek
29
+ # try to avoid dupes from logger broadcasts
30
+ if last_crumb.nil? || last_crumb.message != message
31
+ Raven.breadcrumbs.record do |crumb|
32
+ crumb.level = Raven::Breadcrumbs::SentryLogger::LEVELS.fetch(severity, nil)
33
+ crumb.category = progname || 'logger'
34
+ crumb.message = message
35
+ crumb.type =
36
+ if severity >= 3
37
+ "error"
38
+ else
39
+ crumb.level
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def ignored_logger?(progname)
48
+ progname == "sentry" ||
49
+ Raven.configuration.exclude_loggers.include?(progname)
50
+ end
51
+ end
52
+ module OldBreadcrumbsSentryLogger
53
+ def self.included(base)
54
+ base.class_eval do
55
+ include Raven::Breadcrumbs::SentryLogger
56
+ alias_method :add_without_raven, :add
57
+ alias_method :add, :add_with_raven
58
+ end
59
+ end
60
+
61
+ def add_with_raven(*args)
62
+ add_breadcrumb(*args)
63
+ add_without_raven(*args)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ Raven.safely_prepend(
70
+ "Breadcrumbs::SentryLogger",
71
+ :from => Raven,
72
+ :to => ::Logger
73
+ )
@@ -1,6 +1,6 @@
1
1
  module Raven
2
2
  class CLI
3
- def self.test(dsn = nil, silent = false, config = nil) # rubocop:disable all
3
+ def self.test(dsn = nil, silent = false, config = nil)
4
4
  config ||= Raven.configuration
5
5
 
6
6
  config.logger = if silent
@@ -18,7 +18,7 @@ module Raven
18
18
 
19
19
  # wipe out env settings to ensure we send the event
20
20
  unless config.capture_allowed?
21
- env_name = config.environments.pop || 'production'
21
+ env_name = config.environments.last || 'production'
22
22
  config.current_environment = env_name
23
23
  end
24
24
 
@@ -33,27 +33,16 @@ module Raven
33
33
  evt = instance.capture_exception(e)
34
34
  end
35
35
 
36
- if evt && !(evt.is_a? Thread)
37
- if evt.is_a? Hash
38
- instance.logger.debug "-> event ID: #{evt[:event_id]}"
39
- else
40
- instance.logger.debug "-> event ID: #{evt.id}"
41
- end
42
- elsif evt # async configuration
43
- if evt.value.is_a? Hash
44
- instance.logger.debug "-> event ID: #{evt.value[:event_id]}"
45
- else
46
- instance.logger.debug "-> event ID: #{evt.value.id}"
47
- end
36
+ if evt
37
+ instance.logger.debug "-> event ID: #{evt.id}"
38
+ instance.logger.debug ""
39
+ instance.logger.debug "Done!"
40
+ evt
48
41
  else
49
42
  instance.logger.debug ""
50
43
  instance.logger.debug "An error occurred while attempting to send the event."
51
- exit 1
44
+ false
52
45
  end
53
-
54
- instance.logger.debug ""
55
- instance.logger.debug "Done!"
56
- evt
57
46
  end
58
47
  end
59
48
  end
@@ -125,7 +125,7 @@ module Raven
125
125
  configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")
126
126
 
127
127
  # configuration.transport_failure_callback can be false & nil
128
- configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
128
+ configuration.transport_failure_callback.call(event, e) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
129
129
  end
130
130
  end
131
131
 
@@ -12,6 +12,11 @@ module Raven
12
12
  attr_reader :async
13
13
  alias async? async
14
14
 
15
+ # An array of breadcrumbs loggers to be used. Available options are:
16
+ # - :sentry_logger
17
+ # - :active_support_logger
18
+ attr_reader :breadcrumbs_logger
19
+
15
20
  # Number of lines of code context to capture, or nil for none
16
21
  attr_accessor :context_lines
17
22
 
@@ -83,7 +88,7 @@ module Raven
83
88
  attr_accessor :public_key
84
89
 
85
90
  # Turns on ActiveSupport breadcrumbs integration
86
- attr_accessor :rails_activesupport_breadcrumbs
91
+ attr_reader :rails_activesupport_breadcrumbs
87
92
 
88
93
  # Rails catches exceptions in the ActionDispatch::ShowExceptions or
89
94
  # ActionDispatch::DebugExceptions middlewares, depending on the environment.
@@ -118,6 +123,19 @@ module Raven
118
123
  # Otherwise, can be one of "http", "https", or "dummy"
119
124
  attr_accessor :scheme
120
125
 
126
+ # a proc/lambda that takes an array of stack traces
127
+ # it'll be used to silence (reduce) backtrace of the exception
128
+ #
129
+ # for example:
130
+ #
131
+ # ```ruby
132
+ # Raven.configuration.backtrace_cleanup_callback = lambda do |backtrace|
133
+ # Rails.backtrace_cleaner.clean(backtrace)
134
+ # end
135
+ # ```
136
+ #
137
+ attr_accessor :backtrace_cleanup_callback
138
+
121
139
  # Secret key for authentication with the Sentry server
122
140
  # If you provide a DSN, this will be set automatically.
123
141
  #
@@ -172,16 +190,35 @@ module Raven
172
190
  # Errors object - an Array that contains error messages. See #
173
191
  attr_reader :errors
174
192
 
193
+ # the dsn value, whether it's set via `config.dsn=` or `ENV["SENTRY_DSN"]`
194
+ attr_reader :dsn
195
+
196
+ # Array of rack env parameters to be included in the event sent to sentry.
197
+ attr_accessor :rack_env_whitelist
198
+
199
+ # Most of these errors generate 4XX responses. In general, Sentry clients
200
+ # only automatically report 5xx responses.
175
201
  IGNORE_DEFAULT = [
176
202
  'AbstractController::ActionNotFound',
203
+ 'ActionController::BadRequest',
177
204
  'ActionController::InvalidAuthenticityToken',
205
+ 'ActionController::InvalidCrossOriginRequest',
206
+ 'ActionController::MethodNotAllowed',
207
+ 'ActionController::NotImplemented',
208
+ 'ActionController::ParameterMissing',
178
209
  'ActionController::RoutingError',
179
210
  'ActionController::UnknownAction',
211
+ 'ActionController::UnknownFormat',
212
+ 'ActionController::UnknownHttpMethod',
213
+ 'ActionDispatch::Http::Parameters::ParseError',
214
+ 'ActionView::MissingTemplate',
215
+ 'ActiveJob::DeserializationError', # Can cause infinite loops
180
216
  'ActiveRecord::RecordNotFound',
181
217
  'CGI::Session::CookieStore::TamperedWithCookie',
182
218
  'Mongoid::Errors::DocumentNotFound',
183
- 'Sinatra::NotFound',
184
- 'ActiveJob::DeserializationError'
219
+ 'Rack::QueryParser::InvalidParameterError',
220
+ 'Rack::QueryParser::ParameterTypeError',
221
+ 'Sinatra::NotFound'
185
222
  ].freeze
186
223
 
187
224
  # Note the order - we have to remove circular references and bad characters
@@ -198,11 +235,20 @@ module Raven
198
235
  HEROKU_DYNO_METADATA_MESSAGE = "You are running on Heroku but haven't enabled Dyno Metadata. For Sentry's "\
199
236
  "release detection to work correctly, please run `heroku labs:enable runtime-dyno-metadata`".freeze
200
237
 
238
+ RACK_ENV_WHITELIST_DEFAULT = %w(
239
+ REMOTE_ADDR
240
+ SERVER_NAME
241
+ SERVER_PORT
242
+ ).freeze
243
+
201
244
  LOG_PREFIX = "** [Raven] ".freeze
202
245
  MODULE_SEPARATOR = "::".freeze
203
246
 
247
+ AVAILABLE_BREADCRUMBS_LOGGERS = [:sentry_logger, :active_support_logger].freeze
248
+
204
249
  def initialize
205
250
  self.async = false
251
+ self.breadcrumbs_logger = []
206
252
  self.context_lines = 3
207
253
  self.current_environment = current_environment_from_env
208
254
  self.encoding = 'gzip'
@@ -215,7 +261,8 @@ module Raven
215
261
  self.open_timeout = 1
216
262
  self.processors = DEFAULT_PROCESSORS.dup
217
263
  self.project_root = detect_project_root
218
- self.rails_activesupport_breadcrumbs = false
264
+ @rails_activesupport_breadcrumbs = false
265
+
219
266
  self.rails_report_rescued_exceptions = true
220
267
  self.release = detect_release
221
268
  self.sample_rate = 1.0
@@ -232,11 +279,14 @@ module Raven
232
279
  self.timeout = 2
233
280
  self.transport_failure_callback = false
234
281
  self.before_send = false
282
+ self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
235
283
  end
236
284
 
237
285
  def server=(value)
238
286
  return if value.nil?
239
287
 
288
+ @dsn = value
289
+
240
290
  uri = URI.parse(value)
241
291
  uri_path = uri.path.split('/')
242
292
 
@@ -273,6 +323,23 @@ module Raven
273
323
  @async = value
274
324
  end
275
325
 
326
+ def breadcrumbs_logger=(logger)
327
+ loggers =
328
+ if logger.is_a?(Array)
329
+ logger
330
+ else
331
+ unless AVAILABLE_BREADCRUMBS_LOGGERS.include?(logger)
332
+ raise Raven::Error, "Unsupported breadcrumbs logger. Supported loggers: #{AVAILABLE_BREADCRUMBS_LOGGERS}"
333
+ end
334
+
335
+ Array(logger)
336
+ end
337
+
338
+ require "raven/breadcrumbs/sentry_logger" if loggers.include?(:sentry_logger)
339
+
340
+ @breadcrumbs_logger = logger
341
+ end
342
+
276
343
  def transport_failure_callback=(value)
277
344
  unless value == false || value.respond_to?(:call)
278
345
  raise(ArgumentError, "transport_failure_callback must be callable (or false to disable)")
@@ -329,6 +396,11 @@ module Raven
329
396
  Backtrace::Line.instance_variable_set(:@in_app_pattern, nil) # blow away cache
330
397
  end
331
398
 
399
+ def rails_activesupport_breadcrumbs=(val)
400
+ DeprecationHelper.deprecate_old_breadcrumbs_configuration(:active_support_logger)
401
+ @rails_activesupport_breadcrumbs = val
402
+ end
403
+
332
404
  def exception_class_allowed?(exc)
333
405
  if exc.is_a?(Raven::Error)
334
406
  # Try to prevent error reporting loops
@@ -342,6 +414,10 @@ module Raven
342
414
  end
343
415
  end
344
416
 
417
+ def enabled_in_current_env?
418
+ environments.empty? || environments.include?(current_environment)
419
+ end
420
+
345
421
  private
346
422
 
347
423
  def detect_project_root
@@ -423,7 +499,7 @@ module Raven
423
499
  end
424
500
 
425
501
  def capture_in_current_environment?
426
- return true unless environments.any? && !environments.include?(current_environment)
502
+ return true if enabled_in_current_env?
427
503
 
428
504
  @errors << "Not configured to send/capture in environment '#{current_environment}'"
429
505
  false