sentry-ruby 0.1.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.craft.yml +1 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +5 -0
- data/README.md +197 -21
- data/Rakefile +3 -1
- data/lib/{sentry.rb → sentry-ruby.rb} +29 -3
- data/lib/sentry/benchmarks/benchmark_transport.rb +14 -0
- data/lib/sentry/breadcrumb.rb +7 -7
- data/lib/sentry/breadcrumb/sentry_logger.rb +10 -26
- data/lib/sentry/breadcrumb_buffer.rb +2 -5
- data/lib/sentry/client.rb +32 -37
- data/lib/sentry/configuration.rb +77 -91
- data/lib/sentry/dsn.rb +6 -3
- data/lib/sentry/event.rb +42 -40
- data/lib/sentry/hub.rb +13 -2
- data/lib/sentry/interfaces/request.rb +1 -10
- data/lib/sentry/rack.rb +1 -0
- data/lib/sentry/rack/tracing.rb +39 -0
- data/lib/sentry/scope.rb +26 -4
- data/lib/sentry/span.rb +155 -0
- data/lib/sentry/transaction.rb +113 -0
- data/lib/sentry/transaction_event.rb +29 -0
- data/lib/sentry/transport.rb +11 -24
- data/lib/sentry/transport/configuration.rb +1 -8
- data/lib/sentry/transport/http_transport.rb +5 -2
- data/lib/sentry/transport/state.rb +2 -2
- data/lib/sentry/utils/request_id.rb +16 -0
- data/lib/sentry/version.rb +1 -1
- metadata +9 -6
- data/lib/sentry/event/options.rb +0 -31
- data/lib/sentry/ruby.rb +0 -1
- data/lib/sentry/utils/deep_merge.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 517bd830d9052aef4d3c9011f95e1d95f7740fae3bfdd746ece393766f637d84
|
4
|
+
data.tar.gz: 0b25ac7ffe3abf0c8b0a153681952bd36315fe406341add2e7e724632ca74d35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a717d3e5286400706e44f8bf1a17d6901e5fc7149efbff7f2f70758b1ac5c4f0f134f0d875a5543fa95777013aa1b0b0168f7c41fa149316bd9ced3a2f4ed48e
|
7
|
+
data.tar.gz: ad58cf9e97b482ff9b3107a677d1bc03d3429bba26052f908ce43b25635985f65525b3345afccd1488d5c94eabb0c6565b1ce16d003859da2e359f6ccbdd1eb9
|
data/.craft.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 4.0.0
|
4
|
+
|
5
|
+
- Only documents update for the official release and no API/feature changes.
|
6
|
+
|
7
|
+
## 0.3.0
|
8
|
+
|
9
|
+
- Major API changes: [1123](https://github.com/getsentry/sentry-ruby/pull/1123)
|
10
|
+
- Support event hint: [1122](https://github.com/getsentry/sentry-ruby/pull/1122)
|
11
|
+
- Add request-id tag to events: [1120](https://github.com/getsentry/sentry-ruby/pull/1120) (by @tvec)
|
12
|
+
|
13
|
+
## 0.2.0
|
14
|
+
|
15
|
+
- Multiple fixes and refactorings
|
16
|
+
- Tracing support
|
17
|
+
|
18
|
+
## 0.1.3
|
19
|
+
|
20
|
+
Fix require reference
|
21
|
+
|
22
|
+
## 0.1.2
|
23
|
+
|
24
|
+
- Fix: Fix async callback [1098](https://github.com/getsentry/sentry-ruby/pull/1098)
|
25
|
+
- Refactor: Some code cleanup [1100](https://github.com/getsentry/sentry-ruby/pull/1100)
|
26
|
+
- Refactor: Remove Event options [1101](https://github.com/getsentry/sentry-ruby/pull/1101)
|
27
|
+
|
3
28
|
## 0.1.1
|
4
29
|
|
5
30
|
- Feature: Allow passing custom scope to Hub#capture* helpers [1086](https://github.com/getsentry/sentry-ruby/pull/1086)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,44 +1,220 @@
|
|
1
|
-
|
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
|
-
|
8
|
+
# sentry-ruby, the Ruby Client for Sentry
|
4
9
|
|
5
|
-
|
10
|
+
**The old `sentry-raven` client has entered maintenance mode and was moved to [here](https://github.com/getsentry/sentry-ruby/tree/master/sentry-raven).**
|
6
11
|
|
7
|
-
|
12
|
+
---
|
8
13
|
|
9
|
-
|
14
|
+
|
15
|
+
[![Gem Version](https://img.shields.io/gem/v/sentry-ruby.svg)](https://rubygems.org/gems/sentry-ruby)
|
16
|
+
![Build Status](https://github.com/getsentry/sentry-ruby/workflows/sentry-ruby%20Test/badge.svg)
|
17
|
+
[![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master)
|
18
|
+
[![Gem](https://img.shields.io/gem/dt/sentry-ruby.svg)](https://rubygems.org/gems/sentry-ruby/)
|
19
|
+
[![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)
|
20
|
+
|
21
|
+
|
22
|
+
[Documentation](https://docs.sentry.io/platforms/ruby/) | [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues) | [Forum](https://forum.sentry.io/) | IRC: irc.freenode.net, #sentry
|
23
|
+
|
24
|
+
The official Ruby-language client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API.
|
25
|
+
|
26
|
+
|
27
|
+
## Requirements
|
28
|
+
|
29
|
+
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.
|
30
|
+
|
31
|
+
## Getting Started
|
32
|
+
|
33
|
+
### Install
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
gem "sentry-ruby"
|
37
|
+
```
|
38
|
+
|
39
|
+
and depends on the integrations you want to have, you might also want to install these:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
gem "sentry-rails"
|
43
|
+
gem "sentry-sidekiq"
|
44
|
+
# and mores to come in the future!
|
45
|
+
```
|
46
|
+
|
47
|
+
### Sentry only runs when Sentry DSN is set
|
48
|
+
|
49
|
+
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!
|
50
|
+
|
51
|
+
```bash
|
52
|
+
# Set your SENTRY_DSN environment variable.
|
53
|
+
export SENTRY_DSN=http://public@example.com/project-id
|
54
|
+
```
|
55
|
+
```ruby
|
56
|
+
# Or you can configure the client in the code.
|
57
|
+
Sentry.init do |config|
|
58
|
+
config.dsn = 'http://public@example.com/project-id'
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
### Sentry doesn't report some kinds of data by default
|
63
|
+
|
64
|
+
**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)
|
65
|
+
|
66
|
+
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:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Sentry.init do |config|
|
70
|
+
# other configs
|
71
|
+
config.send_default_pii = true
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
### Performance Monitoring
|
76
|
+
|
77
|
+
You can activate performance monitoring by enabling traces sampling:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
Sentry.init do |config|
|
81
|
+
# set a uniform sample rate between 0.0 and 1.0
|
82
|
+
config.traces_sample_rate = 0.2
|
83
|
+
|
84
|
+
# or control sampling dynamically
|
85
|
+
config.traces_sampler = lambda do |sampling_context|
|
86
|
+
# sampling_context[:transaction_context] contains the information about the transaction
|
87
|
+
# sampling_context[:parent_sampled] contains the transaction's parent's sample decision
|
88
|
+
true # return value can be a boolean or a float between 0.0 and 1.0
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
To lean more about performance monitoring, please visit the [official documentation](https://docs.sentry.io/platforms/ruby/performance).
|
94
|
+
|
95
|
+
### Usage
|
96
|
+
|
97
|
+
`sentry-ruby` has a default integration with `Rack`, so you only need to use the middleware in your application like:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'sentry-ruby'
|
101
|
+
|
102
|
+
Sentry.init do |config|
|
103
|
+
config.dsn = 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
104
|
+
|
105
|
+
# To activate performance monitoring, set one of these options.
|
106
|
+
# We recommend adjusting the value in production:
|
107
|
+
config.traces_sample_rate = 0.5
|
108
|
+
# or
|
109
|
+
config.traces_sampler = lambda do |context|
|
110
|
+
true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
use Sentry::Rack::Tracing # this needs to be placed first
|
115
|
+
use Sentry::Rack::CaptureException
|
116
|
+
```
|
117
|
+
|
118
|
+
Otherwise, Sentry you can always use the capture helpers manually
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
Sentry.capture_message("hello world!")
|
122
|
+
|
123
|
+
begin
|
124
|
+
1 / 0
|
125
|
+
rescue ZeroDivisionError => exception
|
126
|
+
Sentry.capture_exception(exception)
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
We also provide integrations with popular frameworks/libraries with the related extensions:
|
131
|
+
|
132
|
+
- [sentry-rails](https://github.com/getsentry/sentry-ruby/tree/master/sentry-rails)
|
133
|
+
- [sentry-sidekiq](https://github.com/getsentry/sentry-ruby/tree/master/sentry-sidekiq)
|
134
|
+
|
135
|
+
### More configuration
|
136
|
+
|
137
|
+
You're all set - but there's a few more settings you may want to know about too!
|
138
|
+
|
139
|
+
#### async
|
140
|
+
|
141
|
+
When an error or message occurs, the notification is immediately sent to Sentry. Sentry can be configured to send asynchronously:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
config.async = lambda { |event|
|
145
|
+
Thread.new { Sentry.send_event(event) }
|
146
|
+
}
|
147
|
+
```
|
148
|
+
|
149
|
+
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.
|
150
|
+
|
151
|
+
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.
|
10
152
|
|
11
153
|
```ruby
|
12
|
-
|
154
|
+
config.async = lambda { |event| SentryJob.perform_later(event) }
|
155
|
+
|
156
|
+
class SentryJob < ActiveJob::Base
|
157
|
+
queue_as :default
|
158
|
+
|
159
|
+
def perform(event)
|
160
|
+
Sentry.send_event(event)
|
161
|
+
end
|
162
|
+
end
|
13
163
|
```
|
14
164
|
|
15
|
-
|
165
|
+
#### Contexts
|
16
166
|
|
17
|
-
|
167
|
+
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:
|
18
168
|
|
19
|
-
|
169
|
+
```ruby
|
170
|
+
Sentry.configure_scope do |scope|
|
171
|
+
scope.set_user(id: 1, email: "test@example.com")
|
20
172
|
|
21
|
-
|
173
|
+
scope.set_tag(:tag, "foo")
|
174
|
+
scope.set_tags(tag_1: "foo", tag_2: "bar")
|
22
175
|
|
23
|
-
|
176
|
+
scope.set_extra(:order_number, 1234)
|
177
|
+
scope.set_extras(order_number: 1234, tickets_count: 4)
|
178
|
+
end
|
24
179
|
|
25
|
-
|
180
|
+
Sentry.capture_exception(exception) # the event will carry all those information now
|
181
|
+
```
|
26
182
|
|
27
|
-
|
183
|
+
Or use top-level setters
|
28
184
|
|
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.
|
30
185
|
|
31
|
-
|
186
|
+
```ruby
|
187
|
+
Sentry.set_user(id: 1, email: "test@example.com")
|
188
|
+
Sentry.set_tags(tag_1: "foo", tag_2: "bar")
|
189
|
+
Sentry.set_extras(order_number: 1234, tickets_count: 4)
|
32
190
|
|
33
|
-
|
191
|
+
```
|
192
|
+
|
193
|
+
Or build up a temporary scope for local information:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Sentry.configure_scope do |scope|
|
197
|
+
scope.set_tags(tag_1: "foo")
|
198
|
+
end
|
34
199
|
|
35
|
-
|
200
|
+
Sentry.with_scope do |scope|
|
201
|
+
scope.set_tags(tag_1: "bar", tag_2: "baz")
|
36
202
|
|
203
|
+
Sentry.capture_message("message") # this event will have 2 tags: tag_1 => "bar" and tag_2 => "baz"
|
204
|
+
end
|
37
205
|
|
38
|
-
|
206
|
+
Sentry.capture_message("another message") # this event will have 1 tag: tag_1 => "foo"
|
207
|
+
```
|
208
|
+
|
209
|
+
Of course, you can always assign the information on a per-event basis:
|
39
210
|
|
40
|
-
|
211
|
+
```ruby
|
212
|
+
Sentry.capture_exception(exception, tags: {foo: "bar"})
|
213
|
+
```
|
41
214
|
|
42
|
-
##
|
215
|
+
## More Information
|
43
216
|
|
44
|
-
|
217
|
+
* [Documentation](https://docs.sentry.io/platforms/ruby/)
|
218
|
+
* [Bug Tracker](https://github.com/getsentry/sentry-ruby/issues)
|
219
|
+
* [Forum](https://forum.sentry.io/)
|
220
|
+
- [Discord](https://discord.gg/ez5KZN7)
|
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
1
3
|
require "sentry/version"
|
2
4
|
require "sentry/core_ext/object/deep_dup"
|
3
5
|
require "sentry/configuration"
|
4
6
|
require "sentry/logger"
|
5
7
|
require "sentry/event"
|
8
|
+
require "sentry/transaction_event"
|
9
|
+
require "sentry/span"
|
10
|
+
require "sentry/transaction"
|
6
11
|
require "sentry/hub"
|
7
12
|
require "sentry/rack"
|
8
13
|
|
@@ -20,7 +25,15 @@ module Sentry
|
|
20
25
|
META
|
21
26
|
end
|
22
27
|
|
28
|
+
def self.utc_now
|
29
|
+
Time.now.utc
|
30
|
+
end
|
31
|
+
|
23
32
|
class << self
|
33
|
+
extend Forwardable
|
34
|
+
|
35
|
+
def_delegators :get_current_scope, :set_tags, :set_extras, :set_user
|
36
|
+
|
24
37
|
def init(&block)
|
25
38
|
config = Configuration.new
|
26
39
|
yield(config)
|
@@ -39,8 +52,8 @@ module Sentry
|
|
39
52
|
configuration.logger
|
40
53
|
end
|
41
54
|
|
42
|
-
def
|
43
|
-
get_current_scope.breadcrumbs
|
55
|
+
def add_breadcrumb(breadcrumb, &block)
|
56
|
+
get_current_scope.breadcrumbs.record(breadcrumb, &block)
|
44
57
|
end
|
45
58
|
|
46
59
|
def configuration
|
@@ -52,7 +65,12 @@ module Sentry
|
|
52
65
|
end
|
53
66
|
|
54
67
|
def get_current_hub
|
55
|
-
|
68
|
+
# we need to assign a hub to the current thread if it doesn't have one yet
|
69
|
+
#
|
70
|
+
# ideally, we should do this proactively whenever a new thread is created
|
71
|
+
# but it's impossible for the SDK to keep track every new thread
|
72
|
+
# so we need to use this rather passive way to make sure the app doesn't crash
|
73
|
+
Thread.current[THREAD_LOCAL] || clone_hub_to_current_thread
|
56
74
|
end
|
57
75
|
|
58
76
|
def clone_hub_to_current_thread
|
@@ -71,6 +89,10 @@ module Sentry
|
|
71
89
|
get_current_hub.configure_scope(&block)
|
72
90
|
end
|
73
91
|
|
92
|
+
def send_event(event)
|
93
|
+
get_current_client.send_event(event)
|
94
|
+
end
|
95
|
+
|
74
96
|
def capture_event(event)
|
75
97
|
get_current_hub.capture_event(event)
|
76
98
|
end
|
@@ -83,6 +105,10 @@ module Sentry
|
|
83
105
|
get_current_hub.capture_message(message, **options, &block)
|
84
106
|
end
|
85
107
|
|
108
|
+
def start_transaction(**options)
|
109
|
+
get_current_hub.start_transaction(**options)
|
110
|
+
end
|
111
|
+
|
86
112
|
def last_event_id
|
87
113
|
get_current_hub.last_event_id
|
88
114
|
end
|
data/lib/sentry/breadcrumb.rb
CHANGED
@@ -2,13 +2,13 @@ module Sentry
|
|
2
2
|
class Breadcrumb
|
3
3
|
attr_accessor :category, :data, :message, :level, :timestamp, :type
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
@category =
|
7
|
-
@data = {}
|
8
|
-
@level =
|
9
|
-
@message =
|
10
|
-
@timestamp =
|
11
|
-
@type =
|
5
|
+
def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
|
6
|
+
@category = category
|
7
|
+
@data = data || {}
|
8
|
+
@level = level
|
9
|
+
@message = message
|
10
|
+
@timestamp = timestamp || Sentry.utc_now.to_i
|
11
|
+
@type = type
|
12
12
|
end
|
13
13
|
|
14
14
|
def to_hash
|
@@ -58,17 +58,15 @@ module Sentry
|
|
58
58
|
last_crumb = current_breadcrumbs.peek
|
59
59
|
# try to avoid dupes from logger broadcasts
|
60
60
|
if last_crumb.nil? || last_crumb.message != message
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
61
|
+
level = Sentry::Breadcrumb::SentryLogger::LEVELS.fetch(severity, nil)
|
62
|
+
crumb = Sentry::Breadcrumb.new(
|
63
|
+
level: level,
|
64
|
+
category: category,
|
65
|
+
message: message,
|
66
|
+
type: severity >= 3 ? "error" : level
|
67
|
+
)
|
68
|
+
|
69
|
+
Sentry.add_breadcrumb(crumb)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
@@ -80,21 +78,7 @@ module Sentry
|
|
80
78
|
end
|
81
79
|
|
82
80
|
def current_breadcrumbs
|
83
|
-
Sentry.breadcrumbs
|
84
|
-
end
|
85
|
-
end
|
86
|
-
module OldBreadcrumbsSentryLogger
|
87
|
-
def self.included(base)
|
88
|
-
base.class_eval do
|
89
|
-
include Sentry::Breadcrumbs::SentryLogger
|
90
|
-
alias_method :add_without_sentry, :add
|
91
|
-
alias_method :add, :add_with_sentry
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def add_with_sentry(*args)
|
96
|
-
add_breadcrumb(*args)
|
97
|
-
add_without_sentry(*args)
|
81
|
+
Sentry.get_current_scope.breadcrumbs
|
98
82
|
end
|
99
83
|
end
|
100
84
|
end
|