sentry-ruby 5.10.0 → 5.26.0
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 +4 -4
- data/.rspec +3 -1
- data/Gemfile +12 -13
- data/README.md +26 -11
- data/Rakefile +9 -11
- data/bin/console +2 -0
- data/lib/sentry/attachment.rb +40 -0
- data/lib/sentry/background_worker.rb +11 -5
- data/lib/sentry/backpressure_monitor.rb +45 -0
- data/lib/sentry/backtrace.rb +12 -9
- data/lib/sentry/baggage.rb +7 -7
- data/lib/sentry/breadcrumb/sentry_logger.rb +6 -6
- data/lib/sentry/breadcrumb.rb +13 -6
- data/lib/sentry/check_in_event.rb +61 -0
- data/lib/sentry/client.rb +214 -25
- data/lib/sentry/configuration.rb +221 -38
- data/lib/sentry/core_ext/object/deep_dup.rb +1 -1
- data/lib/sentry/cron/configuration.rb +23 -0
- data/lib/sentry/cron/monitor_check_ins.rb +77 -0
- data/lib/sentry/cron/monitor_config.rb +53 -0
- data/lib/sentry/cron/monitor_schedule.rb +42 -0
- data/lib/sentry/dsn.rb +4 -4
- data/lib/sentry/envelope/item.rb +88 -0
- data/lib/sentry/envelope.rb +2 -68
- data/lib/sentry/error_event.rb +2 -2
- data/lib/sentry/event.rb +28 -47
- data/lib/sentry/excon/middleware.rb +77 -0
- data/lib/sentry/excon.rb +10 -0
- data/lib/sentry/faraday.rb +77 -0
- data/lib/sentry/graphql.rb +9 -0
- data/lib/sentry/hub.rb +138 -6
- data/lib/sentry/integrable.rb +10 -0
- data/lib/sentry/interface.rb +1 -0
- data/lib/sentry/interfaces/exception.rb +5 -3
- data/lib/sentry/interfaces/mechanism.rb +20 -0
- data/lib/sentry/interfaces/request.rb +8 -8
- data/lib/sentry/interfaces/single_exception.rb +13 -9
- data/lib/sentry/interfaces/stacktrace.rb +3 -1
- data/lib/sentry/interfaces/stacktrace_builder.rb +23 -2
- data/lib/sentry/linecache.rb +3 -3
- data/lib/sentry/log_event.rb +206 -0
- data/lib/sentry/log_event_buffer.rb +75 -0
- data/lib/sentry/logger.rb +1 -1
- data/lib/sentry/metrics/aggregator.rb +248 -0
- data/lib/sentry/metrics/configuration.rb +47 -0
- data/lib/sentry/metrics/counter_metric.rb +25 -0
- data/lib/sentry/metrics/distribution_metric.rb +25 -0
- data/lib/sentry/metrics/gauge_metric.rb +35 -0
- data/lib/sentry/metrics/local_aggregator.rb +53 -0
- data/lib/sentry/metrics/metric.rb +19 -0
- data/lib/sentry/metrics/set_metric.rb +28 -0
- data/lib/sentry/metrics/timing.rb +51 -0
- data/lib/sentry/metrics.rb +56 -0
- data/lib/sentry/net/http.rb +27 -44
- data/lib/sentry/profiler/helpers.rb +46 -0
- data/lib/sentry/profiler.rb +41 -60
- data/lib/sentry/propagation_context.rb +135 -0
- data/lib/sentry/puma.rb +12 -5
- data/lib/sentry/rack/capture_exceptions.rb +17 -8
- data/lib/sentry/rack.rb +2 -2
- data/lib/sentry/rake.rb +4 -15
- data/lib/sentry/redis.rb +10 -4
- data/lib/sentry/release_detector.rb +5 -5
- data/lib/sentry/rspec.rb +91 -0
- data/lib/sentry/scope.rb +75 -39
- data/lib/sentry/session.rb +2 -2
- data/lib/sentry/session_flusher.rb +15 -43
- data/lib/sentry/span.rb +92 -8
- data/lib/sentry/std_lib_logger.rb +50 -0
- data/lib/sentry/structured_logger.rb +138 -0
- data/lib/sentry/test_helper.rb +42 -13
- data/lib/sentry/threaded_periodic_worker.rb +39 -0
- data/lib/sentry/transaction.rb +44 -43
- data/lib/sentry/transaction_event.rb +10 -6
- data/lib/sentry/transport/configuration.rb +73 -1
- data/lib/sentry/transport/http_transport.rb +71 -41
- data/lib/sentry/transport/spotlight_transport.rb +50 -0
- data/lib/sentry/transport.rb +53 -49
- data/lib/sentry/utils/argument_checking_helper.rb +12 -0
- data/lib/sentry/utils/env_helper.rb +21 -0
- data/lib/sentry/utils/http_tracing.rb +74 -0
- data/lib/sentry/utils/logging_helper.rb +10 -7
- data/lib/sentry/utils/real_ip.rb +2 -2
- data/lib/sentry/utils/request_id.rb +1 -1
- data/lib/sentry/utils/uuid.rb +13 -0
- data/lib/sentry/vernier/output.rb +89 -0
- data/lib/sentry/vernier/profiler.rb +132 -0
- data/lib/sentry/version.rb +1 -1
- data/lib/sentry-ruby.rb +206 -35
- data/sentry-ruby-core.gemspec +3 -1
- data/sentry-ruby.gemspec +15 -6
- metadata +61 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb03eb536d1060c3a097a1ff3726ae71c8ffbd0012580d75c491665e054ac7c1
|
4
|
+
data.tar.gz: 65df577369b281f3e1d1d9335e78786a800947c2014b35608d88c863458f24ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4e398e02a8fe619afc8982760c290a168785c4557dca30767fbeb039032d7907135e84d0598a5ac90b7b1cfb8413ceda83ebe4647702ba5c10c613ff0543574
|
7
|
+
data.tar.gz: 285a3e0f650a41bcb6cc4539f48c7efcb9bc3442f31c76f301089c4672e6d9c790f407dd9d53db4e216df4eacd9be019b5bc46e453437fa1614aa48555541c9a
|
data/.rspec
CHANGED
data/Gemfile
CHANGED
@@ -1,37 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
git_source(:github) { |name| "https://github.com/#{name}.git" }
|
3
5
|
|
6
|
+
eval_gemfile "../Gemfile"
|
7
|
+
|
4
8
|
gem "sentry-ruby", path: "./"
|
5
9
|
|
6
10
|
rack_version = ENV["RACK_VERSION"]
|
7
11
|
rack_version = "3.0.0" if rack_version.nil?
|
8
12
|
gem "rack", "~> #{Gem::Version.new(rack_version)}" unless rack_version == "0"
|
9
13
|
|
14
|
+
gem "ostruct" if RUBY_VERSION >= "3.4"
|
15
|
+
|
10
16
|
redis_rb_version = ENV.fetch("REDIS_RB_VERSION", "5.0")
|
11
17
|
gem "redis", "~> #{redis_rb_version}"
|
12
18
|
|
13
19
|
gem "puma"
|
14
20
|
|
15
|
-
gem "rake", "~> 12.0"
|
16
|
-
gem "rspec", "~> 3.0"
|
17
|
-
gem "rspec-retry"
|
18
21
|
gem "timecop"
|
19
|
-
gem "simplecov"
|
20
|
-
gem "simplecov-cobertura", "~> 1.4"
|
21
|
-
gem "rexml"
|
22
22
|
gem "stackprof" unless RUBY_PLATFORM == "java"
|
23
|
+
gem "vernier", platforms: :ruby if RUBY_VERSION >= "3.2.1"
|
23
24
|
|
24
|
-
if RUBY_VERSION.to_f >= 2.
|
25
|
-
gem "debug", github: "ruby/debug", platform: :ruby
|
26
|
-
gem "irb"
|
27
|
-
end
|
28
|
-
|
29
|
-
gem "pry"
|
25
|
+
gem "graphql", ">= 2.2.6" if RUBY_VERSION.to_f >= 2.7
|
30
26
|
|
31
27
|
gem "benchmark-ips"
|
32
28
|
gem "benchmark_driver"
|
33
29
|
gem "benchmark-ipsa"
|
34
30
|
gem "benchmark-memory"
|
35
31
|
|
36
|
-
gem "yard"
|
32
|
+
gem "yard"
|
37
33
|
gem "webrick"
|
34
|
+
gem "faraday"
|
35
|
+
gem "excon"
|
36
|
+
gem "webmock"
|
data/README.md
CHANGED
@@ -13,14 +13,14 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to he
|
|
13
13
|
Sentry SDK for Ruby
|
14
14
|
===========
|
15
15
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| [](https://rubygems.org/gems/sentry-ruby)
|
19
|
-
| [](https://rubygems.org/gems/sentry-rails)
|
20
|
-
| [](https://rubygems.org/gems/sentry-sidekiq)
|
21
|
-
| [](https://rubygems.org/gems/sentry-delayed_job)
|
22
|
-
| [](https://rubygems.org/gems/sentry-resque)
|
23
|
-
| [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://rubygems.org/gems/sentry-ruby) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-ruby) |
|
19
|
+
| [](https://rubygems.org/gems/sentry-rails) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-rails) |
|
20
|
+
| [](https://rubygems.org/gems/sentry-sidekiq) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-sidekiq) |
|
21
|
+
| [](https://rubygems.org/gems/sentry-delayed_job) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-delayed_job) |
|
22
|
+
| [](https://rubygems.org/gems/sentry-resque) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-resque) |
|
23
|
+
| [](https://rubygems.org/gems/sentry-opentelemetry) | [](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml) | [](https://codecov.io/gh/getsentry/sentry-ruby) | [](https://www.rubydoc.info/gems/sentry-opentelemetry) |
|
24
24
|
|
25
25
|
|
26
26
|
|
@@ -33,7 +33,7 @@ If you're using `sentry-raven`, we recommend you to migrate to this new SDK. You
|
|
33
33
|
|
34
34
|
## Requirements
|
35
35
|
|
36
|
-
We test
|
36
|
+
We test from Ruby 2.4 to Ruby 3.4 at the latest patchlevel/teeny version. We also support JRuby 9.0.
|
37
37
|
|
38
38
|
If you use self-hosted Sentry, please also make sure its version is above `20.6.0`.
|
39
39
|
|
@@ -59,6 +59,8 @@ gem "sentry-opentelemetry"
|
|
59
59
|
|
60
60
|
You need to use Sentry.init to initialize and configure your SDK:
|
61
61
|
```ruby
|
62
|
+
require "sentry-ruby"
|
63
|
+
|
62
64
|
Sentry.init do |config|
|
63
65
|
config.dsn = "MY_DSN"
|
64
66
|
end
|
@@ -90,7 +92,7 @@ To learn more about sampling transactions, please visit the [official documentat
|
|
90
92
|
- [Sidekiq](https://docs.sentry.io/platforms/ruby/guides/sidekiq/)
|
91
93
|
- [DelayedJob](https://docs.sentry.io/platforms/ruby/guides/delayed_job/)
|
92
94
|
- [Resque](https://docs.sentry.io/platforms/ruby/guides/resque/)
|
93
|
-
- [
|
95
|
+
- [OpenTelemetry](https://docs.sentry.io/platforms/ruby/performance/instrumentation/opentelemetry/)
|
94
96
|
|
95
97
|
### Enriching Events
|
96
98
|
|
@@ -103,6 +105,19 @@ To learn more about sampling transactions, please visit the [official documentat
|
|
103
105
|
|
104
106
|
* [](https://docs.sentry.io/platforms/ruby/)
|
105
107
|
* [](https://forum.sentry.io/c/sdks)
|
106
|
-
* [](https://discord.gg/PXa5Apfe7K)
|
108
|
+
* [](https://discord.gg/PXa5Apfe7K)
|
107
109
|
* [](https://stackoverflow.com/questions/tagged/sentry)
|
108
110
|
* [](https://twitter.com/intent/follow?screen_name=getsentry)
|
111
|
+
|
112
|
+
## Contributing to the SDK
|
113
|
+
|
114
|
+
Please make sure to read the [CONTRIBUTING.md](https://github.com/getsentry/sentry-ruby/blob/master/CONTRIBUTING.md) before making a pull request.
|
115
|
+
|
116
|
+
Thanks to everyone who has contributed to this project so far.
|
117
|
+
|
118
|
+
<a href="https://github.com/getsentry/sentry-ruby/graphs/contributors">
|
119
|
+
<img src="https://contributors-img.web.app/image?repo=getsentry/sentry-ruby" />
|
120
|
+
</a>
|
121
|
+
|
122
|
+
> [!WARNING]
|
123
|
+
> Example and sample code in sentry-rails/examples and sentry-rails/spec/dummy is unmaintained. Sample code may contain security vulnerabilities, should never be used in production, and exists only for illustrative purposes.
|
data/Rakefile
CHANGED
@@ -1,20 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rake/clean"
|
2
4
|
CLOBBER.include "pkg"
|
3
5
|
|
4
6
|
require "bundler/gem_helper"
|
5
7
|
Bundler::GemHelper.install_tasks(name: "sentry-ruby")
|
6
8
|
|
7
|
-
|
9
|
+
require_relative "../lib/sentry/test/rake_tasks"
|
8
10
|
|
9
|
-
|
10
|
-
task.rspec_opts = "--order rand"
|
11
|
-
task.exclude_pattern = "spec/isolated/**/*_spec.rb"
|
12
|
-
end
|
11
|
+
ISOLATED_SPECS = "spec/isolated/**/*_spec.rb"
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
13
|
+
Sentry::Test::RakeTasks.define_spec_tasks(
|
14
|
+
isolated_specs_pattern: ISOLATED_SPECS,
|
15
|
+
spec_exclude_pattern: ISOLATED_SPECS
|
16
|
+
)
|
19
17
|
|
20
|
-
task :
|
18
|
+
task default: [:spec, :"spec:isolated"]
|
data/bin/console
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
class Attachment
|
5
|
+
PathNotFoundError = Class.new(StandardError)
|
6
|
+
|
7
|
+
attr_reader :bytes, :filename, :path, :content_type
|
8
|
+
|
9
|
+
def initialize(bytes: nil, filename: nil, content_type: nil, path: nil)
|
10
|
+
@bytes = bytes
|
11
|
+
@filename = filename || infer_filename(path)
|
12
|
+
@path = path
|
13
|
+
@content_type = content_type
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_envelope_headers
|
17
|
+
{ type: "attachment", filename: filename, content_type: content_type, length: payload.bytesize }
|
18
|
+
end
|
19
|
+
|
20
|
+
def payload
|
21
|
+
@payload ||= if bytes
|
22
|
+
bytes
|
23
|
+
else
|
24
|
+
File.binread(path)
|
25
|
+
end
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
raise PathNotFoundError, "Failed to read attachment file, file not found: #{path}"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def infer_filename(path)
|
33
|
+
if path
|
34
|
+
File.basename(path)
|
35
|
+
else
|
36
|
+
raise ArgumentError, "filename or path is required"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -9,15 +9,16 @@ module Sentry
|
|
9
9
|
include LoggingHelper
|
10
10
|
|
11
11
|
attr_reader :max_queue, :number_of_threads
|
12
|
-
|
13
|
-
attr_reader :logger
|
12
|
+
|
14
13
|
attr_accessor :shutdown_timeout
|
15
14
|
|
15
|
+
DEFAULT_MAX_QUEUE = 30
|
16
|
+
|
16
17
|
def initialize(configuration)
|
17
|
-
@max_queue = 30
|
18
18
|
@shutdown_timeout = 1
|
19
19
|
@number_of_threads = configuration.background_worker_threads
|
20
|
-
@
|
20
|
+
@max_queue = configuration.background_worker_max_queue
|
21
|
+
@sdk_logger = configuration.sdk_logger
|
21
22
|
@debug = configuration.debug
|
22
23
|
@shutdown_callback = nil
|
23
24
|
|
@@ -29,7 +30,7 @@ module Sentry
|
|
29
30
|
log_debug("config.background_worker_threads is set to 0, all events will be sent synchronously")
|
30
31
|
Concurrent::ImmediateExecutor.new
|
31
32
|
else
|
32
|
-
log_debug("Initializing the background worker with #{@number_of_threads} threads")
|
33
|
+
log_debug("Initializing the Sentry background worker with #{@number_of_threads} threads")
|
33
34
|
|
34
35
|
executor = Concurrent::ThreadPoolExecutor.new(
|
35
36
|
min_threads: 0,
|
@@ -63,6 +64,11 @@ module Sentry
|
|
63
64
|
@shutdown_callback&.call
|
64
65
|
end
|
65
66
|
|
67
|
+
def full?
|
68
|
+
@executor.is_a?(Concurrent::ThreadPoolExecutor) &&
|
69
|
+
@executor.remaining_capacity == 0
|
70
|
+
end
|
71
|
+
|
66
72
|
private
|
67
73
|
|
68
74
|
def _perform(&block)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sentry
|
4
|
+
class BackpressureMonitor < ThreadedPeriodicWorker
|
5
|
+
DEFAULT_INTERVAL = 10
|
6
|
+
MAX_DOWNSAMPLE_FACTOR = 10
|
7
|
+
|
8
|
+
def initialize(configuration, client, interval: DEFAULT_INTERVAL)
|
9
|
+
super(configuration.sdk_logger, interval)
|
10
|
+
@client = client
|
11
|
+
|
12
|
+
@healthy = true
|
13
|
+
@downsample_factor = 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def healthy?
|
17
|
+
ensure_thread
|
18
|
+
@healthy
|
19
|
+
end
|
20
|
+
|
21
|
+
def downsample_factor
|
22
|
+
ensure_thread
|
23
|
+
@downsample_factor
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
check_health
|
28
|
+
set_downsample_factor
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_health
|
32
|
+
@healthy = !(@client.transport.any_rate_limited? || Sentry.background_worker&.full?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_downsample_factor
|
36
|
+
if @healthy
|
37
|
+
log_debug("[BackpressureMonitor] health check positive, reverting to normal sampling") if @downsample_factor.positive?
|
38
|
+
@downsample_factor = 0
|
39
|
+
else
|
40
|
+
@downsample_factor += 1 if @downsample_factor < MAX_DOWNSAMPLE_FACTOR
|
41
|
+
log_debug("[BackpressureMonitor] health check negative, downsampling with a factor of #{@downsample_factor}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/sentry/backtrace.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rubygems"
|
4
|
+
|
3
5
|
module Sentry
|
4
6
|
# @api private
|
5
7
|
class Backtrace
|
@@ -10,11 +12,11 @@ module Sentry
|
|
10
12
|
RUBY_INPUT_FORMAT = /
|
11
13
|
^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
|
12
14
|
(\d+)
|
13
|
-
(?: :in
|
14
|
-
/x
|
15
|
+
(?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$
|
16
|
+
/x
|
15
17
|
|
16
18
|
# org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
|
17
|
-
JAVA_INPUT_FORMAT = /^(
|
19
|
+
JAVA_INPUT_FORMAT = /^([\w$.]+)\.([\w$]+)\(([\w$.]+):(\d+)\)$/
|
18
20
|
|
19
21
|
# The file portion of the line (such as app/models/user.rb)
|
20
22
|
attr_reader :file
|
@@ -33,12 +35,13 @@ module Sentry
|
|
33
35
|
# Parses a single line of a given backtrace
|
34
36
|
# @param [String] unparsed_line The raw line from +caller+ or some backtrace
|
35
37
|
# @return [Line] The parsed backtrace line
|
36
|
-
def self.parse(unparsed_line, in_app_pattern)
|
38
|
+
def self.parse(unparsed_line, in_app_pattern = nil)
|
37
39
|
ruby_match = unparsed_line.match(RUBY_INPUT_FORMAT)
|
40
|
+
|
38
41
|
if ruby_match
|
39
|
-
_, file, number, method = ruby_match.to_a
|
42
|
+
_, file, number, _, module_name, method = ruby_match.to_a
|
40
43
|
file.sub!(/\.class$/, RB_EXTENSION)
|
41
|
-
module_name =
|
44
|
+
module_name = module_name
|
42
45
|
else
|
43
46
|
java_match = unparsed_line.match(JAVA_INPUT_FORMAT)
|
44
47
|
_, module_name, method, file, number = java_match.to_a
|
@@ -55,6 +58,8 @@ module Sentry
|
|
55
58
|
end
|
56
59
|
|
57
60
|
def in_app
|
61
|
+
return false unless in_app_pattern
|
62
|
+
|
58
63
|
if file =~ in_app_pattern
|
59
64
|
true
|
60
65
|
else
|
@@ -76,8 +81,6 @@ module Sentry
|
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
79
|
-
APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test|spec)/.freeze
|
80
|
-
|
81
84
|
# holder for an Array of Backtrace::Line instances
|
82
85
|
attr_reader :lines
|
83
86
|
|
@@ -87,7 +90,7 @@ module Sentry
|
|
87
90
|
ruby_lines = backtrace_cleanup_callback.call(ruby_lines) if backtrace_cleanup_callback
|
88
91
|
|
89
92
|
in_app_pattern ||= begin
|
90
|
-
Regexp.new("^(#{project_root}/)?#{app_dirs_pattern
|
93
|
+
Regexp.new("^(#{project_root}/)?#{app_dirs_pattern}")
|
91
94
|
end
|
92
95
|
|
93
96
|
lines = ruby_lines.to_a.map do |unparsed_line|
|
data/lib/sentry/baggage.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cgi"
|
4
4
|
|
5
5
|
module Sentry
|
6
6
|
# A {https://www.w3.org/TR/baggage W3C Baggage Header} implementation.
|
7
7
|
class Baggage
|
8
|
-
SENTRY_PREFIX =
|
9
|
-
SENTRY_PREFIX_REGEX = /^sentry
|
8
|
+
SENTRY_PREFIX = "sentry-"
|
9
|
+
SENTRY_PREFIX_REGEX = /^sentry-/
|
10
10
|
|
11
11
|
# @return [Hash]
|
12
12
|
attr_reader :items
|
@@ -30,14 +30,14 @@ module Sentry
|
|
30
30
|
items = {}
|
31
31
|
mutable = true
|
32
32
|
|
33
|
-
header.split(
|
33
|
+
header.split(",").each do |item|
|
34
34
|
item = item.strip
|
35
|
-
key, val = item.split(
|
35
|
+
key, val = item.split("=")
|
36
36
|
|
37
37
|
next unless key && val
|
38
38
|
next unless key =~ SENTRY_PREFIX_REGEX
|
39
39
|
|
40
|
-
baggage_key = key.split(
|
40
|
+
baggage_key = key.split("-")[1]
|
41
41
|
next unless baggage_key
|
42
42
|
|
43
43
|
items[CGI.unescape(baggage_key)] = CGI.unescape(val)
|
@@ -64,7 +64,7 @@ module Sentry
|
|
64
64
|
# @return [String]
|
65
65
|
def serialize
|
66
66
|
items = @items.map { |k, v| "#{SENTRY_PREFIX}#{CGI.escape(k)}=#{CGI.escape(v)}" }
|
67
|
-
items.join(
|
67
|
+
items.join(",")
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "logger"
|
4
4
|
|
5
5
|
module Sentry
|
6
6
|
class Breadcrumb
|
7
7
|
module SentryLogger
|
8
8
|
LEVELS = {
|
9
|
-
::Logger::DEBUG =>
|
10
|
-
::Logger::INFO =>
|
11
|
-
::Logger::WARN =>
|
12
|
-
::Logger::ERROR =>
|
13
|
-
::Logger::FATAL =>
|
9
|
+
::Logger::DEBUG => "debug",
|
10
|
+
::Logger::INFO => "info",
|
11
|
+
::Logger::WARN => "warn",
|
12
|
+
::Logger::ERROR => "error",
|
13
|
+
::Logger::FATAL => "fatal"
|
14
14
|
}.freeze
|
15
15
|
|
16
16
|
def add(*args, &block)
|
data/lib/sentry/breadcrumb.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sentry
|
4
4
|
class Breadcrumb
|
5
|
+
MAX_NESTING = 10
|
5
6
|
DATA_SERIALIZATION_ERROR_MESSAGE = "[data were removed due to serialization issues]"
|
6
7
|
|
7
8
|
# @return [String, nil]
|
@@ -9,7 +10,7 @@ module Sentry
|
|
9
10
|
# @return [Hash, nil]
|
10
11
|
attr_accessor :data
|
11
12
|
# @return [String, nil]
|
12
|
-
|
13
|
+
attr_reader :level
|
13
14
|
# @return [Time, Integer, nil]
|
14
15
|
attr_accessor :timestamp
|
15
16
|
# @return [String, nil]
|
@@ -26,10 +27,10 @@ module Sentry
|
|
26
27
|
def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
|
27
28
|
@category = category
|
28
29
|
@data = data || {}
|
29
|
-
@level = level
|
30
30
|
@timestamp = timestamp || Sentry.utc_now.to_i
|
31
31
|
@type = type
|
32
32
|
self.message = message
|
33
|
+
self.level = level
|
33
34
|
end
|
34
35
|
|
35
36
|
# @return [Hash]
|
@@ -47,23 +48,29 @@ module Sentry
|
|
47
48
|
# @param message [String]
|
48
49
|
# @return [void]
|
49
50
|
def message=(message)
|
50
|
-
@message = (message
|
51
|
+
@message = message && Utils::EncodingHelper.valid_utf_8?(message) ? message.byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES) : ""
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param level [String]
|
55
|
+
# @return [void]
|
56
|
+
def level=(level) # needed to meet the Sentry spec
|
57
|
+
@level = level == "warn" ? "warning" : level
|
51
58
|
end
|
52
59
|
|
53
60
|
private
|
54
61
|
|
55
62
|
def serialized_data
|
56
63
|
begin
|
57
|
-
::JSON.parse(::JSON.generate(@data))
|
64
|
+
::JSON.parse(::JSON.generate(@data, max_nesting: MAX_NESTING))
|
58
65
|
rescue Exception => e
|
59
|
-
Sentry.
|
66
|
+
Sentry.sdk_logger.debug(LOGGER_PROGNAME) do
|
60
67
|
<<~MSG
|
61
68
|
can't serialize breadcrumb data because of error: #{e}
|
62
69
|
data: #{@data}
|
63
70
|
MSG
|
64
71
|
end
|
65
72
|
|
66
|
-
DATA_SERIALIZATION_ERROR_MESSAGE
|
73
|
+
{ error: DATA_SERIALIZATION_ERROR_MESSAGE }
|
67
74
|
end
|
68
75
|
end
|
69
76
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sentry/cron/monitor_config"
|
5
|
+
require "sentry/utils/uuid"
|
6
|
+
|
7
|
+
module Sentry
|
8
|
+
class CheckInEvent < Event
|
9
|
+
TYPE = "check_in"
|
10
|
+
|
11
|
+
# uuid to identify this check-in.
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :check_in_id
|
14
|
+
|
15
|
+
# Identifier of the monitor for this check-in.
|
16
|
+
# @return [String]
|
17
|
+
attr_accessor :monitor_slug
|
18
|
+
|
19
|
+
# Duration of this check since it has started in seconds.
|
20
|
+
# @return [Integer, nil]
|
21
|
+
attr_accessor :duration
|
22
|
+
|
23
|
+
# Monitor configuration to support upserts.
|
24
|
+
# @return [Cron::MonitorConfig, nil]
|
25
|
+
attr_accessor :monitor_config
|
26
|
+
|
27
|
+
# Status of this check-in.
|
28
|
+
# @return [Symbol]
|
29
|
+
attr_accessor :status
|
30
|
+
|
31
|
+
VALID_STATUSES = %i[ok in_progress error]
|
32
|
+
|
33
|
+
def initialize(
|
34
|
+
slug:,
|
35
|
+
status:,
|
36
|
+
duration: nil,
|
37
|
+
monitor_config: nil,
|
38
|
+
check_in_id: nil,
|
39
|
+
**options
|
40
|
+
)
|
41
|
+
super(**options)
|
42
|
+
|
43
|
+
self.monitor_slug = slug
|
44
|
+
self.status = status
|
45
|
+
self.duration = duration
|
46
|
+
self.monitor_config = monitor_config
|
47
|
+
self.check_in_id = check_in_id || Utils.uuid
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Hash]
|
51
|
+
def to_hash
|
52
|
+
data = super
|
53
|
+
data[:check_in_id] = check_in_id
|
54
|
+
data[:monitor_slug] = monitor_slug
|
55
|
+
data[:status] = status
|
56
|
+
data[:duration] = duration if duration
|
57
|
+
data[:monitor_config] = monitor_config.to_hash if monitor_config
|
58
|
+
data
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|