sentry-ruby 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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