sentry-ruby 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd48cd818d98c18e281aab8c37346fc7dc204b78396afe0ccaa64fa3cc8c0d2f
4
- data.tar.gz: 2d4f7e657e9a3abc1d1063aa73e86ef7d9e09b0e5205f2a16b54d2242955316e
3
+ metadata.gz: 4cd10cdc1a28f396af641980c7440ab8fc74648a2ebe1364e81d137af7a8d832
4
+ data.tar.gz: d96bebca93ed6d16fc4bc1a7c6f14a53f33ebf84f4d6197ce79ee344bd2a0056
5
5
  SHA512:
6
- metadata.gz: 612e9205c0d42c107a9a3a1d5b7bc759fd4daae5ede8ffd0efec1a0c3d1aa22860669f5f4d5a244397dcfe481f7784ae3f23c42c9e316338702cf372f8610e48
7
- data.tar.gz: 45535f8367e8b37ba0f106b78ee2e9b7f40622ccb9b7207ba34ee49238600c6885a16125f15ff65957d713871f576b8579ecdbc88fbfb45cc6feecab0e64b1aa
6
+ metadata.gz: bacf5d66a156684b3dcf3048806ffab6b53f3172a146626a4b28e4a80d1c933a729ee813a933052a425d86d3c58ce04b8409a55ba0b3fe76c45cce3defc8a6f0
7
+ data.tar.gz: 756550d44dd6765e478ae2922f69c2098121c3ae290dd99345805d5690281021683146b54e999b77ed82b82330f40b5ec7e57b172a39741e4023c911c9867cb0
data/.craft.yml CHANGED
@@ -12,6 +12,7 @@ artifactProvider:
12
12
  targets:
13
13
  - name: gem
14
14
  - name: github
15
+ tagPrefix: sentry-ruby-v
15
16
  - name: registry
16
17
  type: sdk
17
18
  config:
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ - Fix: Fix async callback [1098](https://github.com/getsentry/sentry-ruby/pull/1098)
6
+ - Refactor: Some code cleanup [1100](https://github.com/getsentry/sentry-ruby/pull/1100)
7
+ - Refactor: Remove Event options [1101](https://github.com/getsentry/sentry-ruby/pull/1101)
8
+
3
9
  ## 0.1.1
4
10
 
5
11
  - Feature: Allow passing custom scope to Hub#capture* helpers [1086](https://github.com/getsentry/sentry-ruby/pull/1086)
data/README.md CHANGED
@@ -1,44 +1,178 @@
1
- # Sentry::Ruby
1
+ <p align="center">
2
+ <a href="https://sentry.io" target="_blank" align="center">
3
+ <img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
4
+ </a>
5
+ <br>
6
+ </p>
2
7
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sentry/ruby`. To experiment with that code, run `bin/console` for an interactive prompt.
8
+ # sentry-ruby, the Ruby Client for Sentry
4
9
 
5
- TODO: Delete this and the text above, and describe your gem
10
+ ---
6
11
 
7
- ## Installation
8
12
 
9
- Add this line to your application's Gemfile:
13
+ [![Gem Version](https://img.shields.io/gem/v/sentry-ruby.svg)](https://rubygems.org/gems/sentry-ruby)
14
+ ![Build Status](https://github.com/getsentry/sentry-ruby/workflows/sentry-ruby%20Test/badge.svg)
15
+ [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master)
16
+ [![Gem](https://img.shields.io/gem/dt/sentry-ruby.svg)](https://rubygems.org/gems/sentry-ruby/)
17
+ [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-ruby&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-ruby&package-manager=bundler&version-scheme=semver)
18
+
19
+
20
+ [Documentation](https://docs.sentry.io/clients/ruby/) | [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues) | [Forum](https://forum.sentry.io/) | IRC: irc.freenode.net, #sentry
21
+
22
+ The official Ruby-language client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API.
23
+
24
+
25
+ ## Requirements
26
+
27
+ We test on Ruby 2.4, 2.5, 2.6 and 2.7 at the latest patchlevel/teeny version. We also support JRuby 9.0.
28
+
29
+ ## Getting Started
30
+
31
+ ### Install
10
32
 
11
33
  ```ruby
12
- gem 'sentry-ruby'
34
+ gem "sentry-ruby"
13
35
  ```
14
36
 
15
- And then execute:
37
+ and depends on the integrations you want to have, you might also want to install these:
16
38
 
17
- $ bundle install
39
+ ```ruby
40
+ gem "sentry-rails"
41
+ gem "sentry-sidekiq"
42
+ # and mores to come in the future!
43
+ ```
44
+
45
+ ### Sentry only runs when Sentry DSN is set
46
+
47
+ Sentry 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!
18
48
 
19
- Or install it yourself as:
49
+ ```bash
50
+ # Set your SENTRY_DSN environment variable.
51
+ export SENTRY_DSN=http://public@example.com/project-id
52
+ ```
53
+ ```ruby
54
+ # Or you can configure the client in the code.
55
+ Sentry.init do |config|
56
+ config.dsn = 'http://public@example.com/project-id'
57
+ end
58
+ ```
20
59
 
21
- $ gem install sentry-ruby
60
+ ### Sentry doesn't report some kinds of data by default
22
61
 
23
- ## Usage
62
+ **Sentry ignores some exceptions by default** - most of these are related to 404s parameter parsing errors. [For a complete list, see the `IGNORE_DEFAULT` constant](https://github.com/getsentry/sentry-ruby/blob/master/sentry-ruby/lib/sentry/configuration.rb#L118) and the integration gems' `IGNORE_DEFAULT`, like [`sentry-rails`'s](https://github.com/getsentry/sentry-ruby/blob/update-readme/sentry-rails/lib/sentry/rails/configuration.rb#L12)
24
63
 
25
- TODO: Write usage instructions here
64
+ Sentry doesn't send personally identifiable information (pii) by default, such as request body, user ip or cookies. If you want those information to be sent, you can use the `send_default_pii` config option:
26
65
 
27
- ## Development
66
+ ```ruby
67
+ Sentry.init do |config|
68
+ # other configs
69
+ config.send_default_pii = true
70
+ end
71
+ ```
72
+
73
+ ### Usage
74
+
75
+ `sentry-ruby` has a default integration with `Rack`, so you only need to use the middleware in your application like:
76
+
77
+ ```
78
+ require 'rack'
79
+ require 'sentry'
80
+
81
+ use Sentry::Rack::CaptureException
82
+
83
+ run theapp
84
+ ```
85
+
86
+ Otherwise, Sentry you can always use the capture helpers manually
87
+
88
+ ```ruby
89
+ Sentry.capture_message("hello world!")
90
+
91
+ begin
92
+ 1 / 0
93
+ rescue ZeroDivisionError => exception
94
+ Sentry.capture_exception(exception)
95
+ end
96
+ ```
28
97
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
98
+ We also provide integrations with popular frameworks/libraries with the related extensions:
30
99
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
100
+ - [sentry-rails](https://github.com/getsentry/sentry-ruby/tree/master/sentry-rails)
101
+ - [sentry-sidekiq](https://github.com/getsentry/sentry-ruby/tree/master/sentry-sidekiq)
32
102
 
33
- ## Contributing
103
+ ### More configuration
34
104
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sentry-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/sentry-ruby/blob/master/CODE_OF_CONDUCT.md).
105
+ You're all set - but there's a few more settings you may want to know about too!
36
106
 
107
+ #### async
37
108
 
38
- ## License
109
+ When an error or message occurs, the notification is immediately sent to Sentry. Sentry can be configured to send asynchronously:
39
110
 
40
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
111
+ ```ruby
112
+ config.async = lambda { |event|
113
+ Thread.new { Sentry.send_event(event) }
114
+ }
115
+ ```
116
+
117
+ Using a thread to send events will be adequate for truly parallel Ruby platforms such as JRuby, though the benefit on MRI/CRuby will be limited. If the async callback raises an exception, Sentry will attempt to send synchronously.
118
+
119
+ Note that the naive example implementation has a major drawback - it can create an infinite number of threads. We recommend creating a background job, using your background job processor, that will send Sentry notifications in the background.
120
+
121
+ ```ruby
122
+ config.async = lambda { |event| SentryJob.perform_later(event) }
123
+
124
+ class SentryJob < ActiveJob::Base
125
+ queue_as :default
126
+
127
+ def perform(event)
128
+ Sentry.send_event(event)
129
+ end
130
+ end
131
+ ```
132
+
133
+ #### Contexts
134
+
135
+ In sentry-ruby, every event will inherit their contextual data from the current scope. So you can enrich the event's data by configuring the current scope like:
136
+
137
+ ```ruby
138
+ Sentry.configure_scope do |scope|
139
+ scope.set_user(id: 1, email: "test@example.com")
140
+
141
+ scope.set_tag(:tag, "foo")
142
+ scope.set_tags(tag_1: "foo", tag_2: "bar")
143
+
144
+ scope.set_extra(:order_number, 1234)
145
+ scope.set_extras(order_number: 1234, tickets_count: 4)
146
+ end
147
+
148
+ Sentry.capture_exception(exception) # the event will carry all those information now
149
+ ```
150
+
151
+ Or build up a temporary scope for local information:
152
+
153
+ ```ruby
154
+ Sentry.configure_scope do |scope|
155
+ scope.set_tags(tag_1: "foo")
156
+ end
157
+
158
+ Sentry.with_scope do |scope|
159
+ scope.set_tags(tag_1: "bar", tag_2: "baz")
160
+
161
+ Sentry.capture_message("message") # this event will have 2 tags: tag_1 => "bar" and tag_2 => "baz"
162
+ end
163
+
164
+ Sentry.capture_message("another message") # this event will have 1 tag: tag_1 => "foo"
165
+ ```
166
+
167
+ Of course, you can always assign the information on a per-event basis:
168
+
169
+ ```ruby
170
+ Sentry.capture_exception(exception, tags: {foo: "bar"})
171
+ ```
41
172
 
42
- ## Code of Conduct
173
+ ## More Information
43
174
 
44
- Everyone interacting in the Sentry::Ruby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/sentry-ruby/blob/master/CODE_OF_CONDUCT.md).
175
+ * [Documentation](https://docs.sentry.io/clients/ruby/)
176
+ * [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues)
177
+ * [Forum](https://forum.sentry.io/)
178
+ - [Discord](https://discord.gg/ez5KZN7)
@@ -52,7 +52,12 @@ module Sentry
52
52
  end
53
53
 
54
54
  def get_current_hub
55
- Thread.current[THREAD_LOCAL]
55
+ # we need to assign a hub to the current thread if it doesn't have one yet
56
+ #
57
+ # ideally, we should do this proactively whenever a new thread is created
58
+ # but it's impossible for the SDK to keep track every new thread
59
+ # so we need to use this rather passive way to make sure the app doesn't crash
60
+ Thread.current[THREAD_LOCAL] || clone_hub_to_current_thread
56
61
  end
57
62
 
58
63
  def clone_hub_to_current_thread
@@ -71,6 +76,10 @@ module Sentry
71
76
  get_current_hub.configure_scope(&block)
72
77
  end
73
78
 
79
+ def send_event(event)
80
+ get_current_client.send_event(event)
81
+ end
82
+
74
83
  def capture_event(event)
75
84
  get_current_hub.capture_event(event)
76
85
  end
@@ -1,5 +1,4 @@
1
1
  require "sentry/transport"
2
- require 'sentry/utils/deep_merge'
3
2
 
4
3
  module Sentry
5
4
  class Client
@@ -21,51 +20,35 @@ module Sentry
21
20
  end
22
21
  end
23
22
 
24
- def capture_exception(exception, scope:, **options, &block)
25
- event = event_from_exception(exception, **options)
26
- return unless event
27
-
28
- block.call(event) if block
29
- capture_event(event, scope)
30
- end
31
-
32
- def capture_message(message, scope:, **options, &block)
33
- event = event_from_message(message, **options)
34
- block.call(event) if block
35
- capture_event(event, scope)
36
- end
37
-
38
23
  def capture_event(event, scope)
39
24
  scope.apply_to_event(event)
40
- send_event(event)
41
- event
42
- end
43
25
 
44
- def event_from_exception(exception, **options)
45
- exception_context =
46
- if exception.instance_variable_defined?(:@__sentry_context)
47
- exception.instance_variable_get(:@__sentry_context)
48
- elsif exception.respond_to?(:sentry_context)
49
- exception.sentry_context
50
- else
51
- {}
26
+ if configuration.async?
27
+ begin
28
+ # We have to convert to a JSON-like hash, because background job
29
+ # processors (esp ActiveJob) may not like weird types in the event hash
30
+ configuration.async.call(event.to_json_compatible)
31
+ rescue => e
32
+ configuration.logger.error(LOGGER_PROGNAME) { "async event sending failed: #{e.message}" }
33
+ send_event(event)
52
34
  end
35
+ else
36
+ send_event(event)
37
+ end
53
38
 
54
- options = Utils::DeepMergeHash.deep_merge(exception_context, options)
39
+ event
40
+ end
55
41
 
42
+ def event_from_exception(exception)
56
43
  return unless @configuration.exception_class_allowed?(exception)
57
44
 
58
- options = Event::Options.new(**options)
59
-
60
- Event.new(configuration: configuration, options: options).tap do |event|
45
+ Event.new(configuration: configuration).tap do |event|
61
46
  event.add_exception_interface(exception)
62
47
  end
63
48
  end
64
49
 
65
- def event_from_message(message, **options)
66
- options.merge!(message: message)
67
- options = Event::Options.new(options)
68
- Event.new(configuration: configuration, options: options)
50
+ def event_from_message(message)
51
+ Event.new(configuration: configuration, message: message)
69
52
  end
70
53
 
71
54
  def send_event(event, hint = nil)
@@ -93,9 +93,6 @@ module Sentry
93
93
  # Silences ready message when true.
94
94
  attr_accessor :silence_ready
95
95
 
96
- # Default tags for events. Hash.
97
- attr_accessor :tags
98
-
99
96
  attr_reader :transport
100
97
 
101
98
  # Optional Proc, called before sending an event to the server/
@@ -157,7 +154,7 @@ module Sentry
157
154
  self.dsn = ENV['SENTRY_DSN']
158
155
  self.server_name = server_name_from_env
159
156
  self.should_capture = false
160
- self.tags = {}
157
+
161
158
  @transport = Transport::Configuration.new
162
159
  self.before_send = false
163
160
  self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
@@ -2,10 +2,8 @@
2
2
 
3
3
  require 'socket'
4
4
  require 'securerandom'
5
- require 'sentry/event/options'
6
5
  require 'sentry/interface'
7
6
  require 'sentry/backtrace'
8
- require 'sentry/utils/deep_merge'
9
7
  require 'sentry/utils/real_ip'
10
8
 
11
9
  module Sentry
@@ -23,7 +21,7 @@ module Sentry
23
21
 
24
22
  alias event_id id
25
23
 
26
- def initialize(options:, configuration:)
24
+ def initialize(configuration:, message: nil)
27
25
  # this needs to go first because some setters rely on configuration
28
26
  @configuration = configuration
29
27
 
@@ -33,27 +31,21 @@ module Sentry
33
31
  @platform = :ruby
34
32
  @sdk = Sentry.sdk_meta
35
33
 
36
- @user = options.user
37
- @extra = options.extra
38
- @contexts = options.contexts
39
- @tags = configuration.tags.merge(options.tags)
34
+ @user = {}
35
+ @extra = {}
36
+ @contexts = {}
37
+ @tags = {}
40
38
 
41
- @fingerprint = options.fingerprint
39
+ @fingerprint = []
42
40
 
43
- @server_name = options.server_name || configuration.server_name
44
- @environment = options.environment || configuration.current_environment
45
- @release = options.release || configuration.release
41
+ @server_name = configuration.server_name
42
+ @environment = configuration.current_environment
43
+ @release = configuration.release
46
44
  @modules = list_gem_specs if configuration.send_modules
47
45
 
48
- @message = options.message if options.message
46
+ @message = message || ""
49
47
 
50
- self.level = options.level
51
-
52
- if !options.backtrace.empty?
53
- @stacktrace = Sentry::StacktraceInterface.new.tap do |int|
54
- int.frames = stacktrace_interface_from(options.backtrace)
55
- end
56
- end
48
+ self.level = :error
57
49
  end
58
50
 
59
51
  class << self
@@ -113,6 +105,10 @@ module Sentry
113
105
  end
114
106
 
115
107
  def add_exception_interface(exc)
108
+ if exc.respond_to?(:sentry_context)
109
+ @extra.merge!(exc.sentry_context)
110
+ end
111
+
116
112
  @exception = Sentry::ExceptionInterface.new.tap do |exc_int|
117
113
  exceptions = Sentry::Utils::ExceptionCauseChain.exception_to_array(exc).reverse
118
114
  backtraces = Set.new
@@ -26,27 +26,12 @@ module Sentry
26
26
 
27
27
  return nil unless encoded_data
28
28
 
29
- begin
30
- if configuration.async?
31
- begin
32
- # We have to convert to a JSON-like hash, because background job
33
- # processors (esp ActiveJob) may not like weird types in the event hash
34
- configuration.async.call(event.to_json_compatible)
35
- rescue => e
36
- configuration.logger.error(LOGGER_PROGNAME) { "async event sending failed: #{e.message}" }
37
- send_data(encoded_data, content_type: content_type)
38
- end
39
- else
40
- send_data(encoded_data, content_type: content_type)
41
- end
42
-
43
- state.success
44
- rescue => e
45
- failed_for_exception(e, event)
46
- return
47
- end
29
+ send_data(encoded_data, content_type: content_type)
48
30
 
31
+ state.success
49
32
  event
33
+ rescue => e
34
+ failed_for_exception(e, event)
50
35
  end
51
36
 
52
37
  def generate_auth_header
@@ -1,3 +1,3 @@
1
1
  module Sentry
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -55,7 +55,6 @@ files:
55
55
  - lib/sentry/core_ext/object/duplicable.rb
56
56
  - lib/sentry/dsn.rb
57
57
  - lib/sentry/event.rb
58
- - lib/sentry/event/options.rb
59
58
  - lib/sentry/hub.rb
60
59
  - lib/sentry/interface.rb
61
60
  - lib/sentry/interfaces/exception.rb
@@ -73,7 +72,6 @@ files:
73
72
  - lib/sentry/transport/dummy_transport.rb
74
73
  - lib/sentry/transport/http_transport.rb
75
74
  - lib/sentry/transport/state.rb
76
- - lib/sentry/utils/deep_merge.rb
77
75
  - lib/sentry/utils/exception_cause_chain.rb
78
76
  - lib/sentry/utils/real_ip.rb
79
77
  - lib/sentry/version.rb
@@ -1,31 +0,0 @@
1
- module Sentry
2
- class Event
3
- class Options
4
- attr_reader :message,
5
- :user, :extra, :tags, :contexts,
6
- :backtrace, :level, :fingerprint,
7
- :server_name, :release, :environment
8
-
9
- def initialize(
10
- message: "",
11
- user: {}, extra: {}, tags: {}, contexts: {},
12
- backtrace: [], level: :error, fingerprint: [],
13
- # nilable attributes because we'll fallback to the configuration's values
14
- server_name: nil, release: nil, environment: nil
15
- )
16
- @message = message || ""
17
- @user = user || {}
18
- @extra = extra || {}
19
- @tags = tags || {}
20
- @contexts = contexts || {}
21
- @backtrace = backtrace || []
22
- @fingerprint = fingerprint || []
23
- @level = level || :error
24
- @server_name = server_name
25
- @environment = environment
26
- @release = release
27
- end
28
- end
29
- end
30
- end
31
-
@@ -1,22 +0,0 @@
1
- module Sentry
2
- module Utils
3
- # ported from ActiveSupport
4
- module DeepMergeHash
5
- def self.deep_merge(hash, other_hash, &block)
6
- deep_merge!(hash, other_hash, &block)
7
- end
8
-
9
- def self.deep_merge!(hash, other_hash, &block)
10
- hash.merge!(other_hash) do |key, this_val, other_val|
11
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
12
- deep_merge(this_val, other_val, &block)
13
- elsif block_given?
14
- block.call(key, this_val, other_val)
15
- else
16
- other_val
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end