hawk-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 +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +14 -13
- data/docs/api.md +25 -0
- data/docs/integrations.md +12 -20
- data/docs/releasing.md +3 -3
- data/lib/hawk/boundary.rb +1 -0
- data/lib/hawk/breadcrumbs/logger.rb +1 -0
- data/lib/hawk/breadcrumbs/net_http.rb +1 -0
- data/lib/hawk/breadcrumbs/rails.rb +1 -0
- data/lib/hawk/breadcrumbs.rb +1 -0
- data/lib/hawk/client.rb +96 -2
- data/lib/hawk/configuration.rb +197 -8
- data/lib/hawk/delayed_job.rb +2 -1
- data/lib/hawk/delivery.rb +1 -0
- data/lib/hawk/diagnostics.rb +8 -0
- data/lib/hawk/event.rb +1 -0
- data/lib/hawk/filter.rb +1 -0
- data/lib/hawk/filtered_fields.rb +1 -0
- data/lib/hawk/framework_filter.rb +1 -0
- data/lib/hawk/hook.rb +1 -0
- data/lib/hawk/integrations.rb +16 -0
- data/lib/hawk/job_context.rb +1 -0
- data/lib/hawk/json_value.rb +1 -0
- data/lib/hawk/process_hooks.rb +1 -0
- data/lib/hawk/rack/body.rb +1 -0
- data/lib/hawk/rack.rb +15 -1
- data/lib/hawk/rails/action_cable.rb +1 -0
- data/lib/hawk/rails/active_job.rb +1 -0
- data/lib/hawk/rails/error_subscriber.rb +1 -0
- data/lib/hawk/rails/integration.rb +1 -3
- data/lib/hawk/rails/payload_filter.rb +1 -0
- data/lib/hawk/rake.rb +2 -1
- data/lib/hawk/release.rb +1 -0
- data/lib/hawk/resque.rb +2 -1
- data/lib/hawk/scope.rb +25 -1
- data/lib/hawk/scope_store.rb +1 -0
- data/lib/hawk/sidekiq.rb +2 -1
- data/lib/hawk/source.rb +1 -0
- data/lib/hawk/token.rb +2 -0
- data/lib/hawk/transport.rb +1 -0
- data/lib/hawk/version.rb +3 -1
- data/lib/hawk-ruby.rb +3 -0
- data/lib/hawk.rb +51 -2
- data/sig/hawk/integrations.rbs +3 -0
- metadata +5 -1
data/lib/hawk/configuration.rb
CHANGED
|
@@ -2,16 +2,193 @@
|
|
|
2
2
|
|
|
3
3
|
module Hawk
|
|
4
4
|
# Settings are validated before clients install handlers or start delivery.
|
|
5
|
+
# Configure settings before calling {Hawk.init} or {Client.build}.
|
|
6
|
+
# @see file:docs/configuration.md Configuration guide
|
|
5
7
|
class Configuration
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
:before_send, :before_breadcrumb, :framework_filter, :diagnostic_callback, :diagnostic_logger,
|
|
11
|
-
:propagate_job_context,
|
|
12
|
-
:include_request_body, :include_job_arguments, :include_headers, :include_cookies,
|
|
13
|
-
:breadcrumbs_logger, :breadcrumbs_http, :breadcrumbs_rails, :logger_error_level
|
|
8
|
+
# Project integration token. Defaults to ENV["HAWK_TOKEN"]; nil or empty disables capture.
|
|
9
|
+
#
|
|
10
|
+
# @return [String, nil]
|
|
11
|
+
attr_accessor :token
|
|
14
12
|
|
|
13
|
+
# Collector URL override. Defaults to the token-derived endpoint; permits HTTPS or loopback HTTP.
|
|
14
|
+
#
|
|
15
|
+
# @return [String, nil]
|
|
16
|
+
attr_accessor :endpoint
|
|
17
|
+
|
|
18
|
+
# Event environment. Defaults to RAILS_ENV, RACK_ENV, or "development", in that order.
|
|
19
|
+
#
|
|
20
|
+
# @return [String]
|
|
21
|
+
attr_accessor :environment
|
|
22
|
+
|
|
23
|
+
# Environments that permit capture. Defaults to nil, which permits all environments.
|
|
24
|
+
#
|
|
25
|
+
# @return [Array<String>, nil]
|
|
26
|
+
attr_accessor :enabled_environments
|
|
27
|
+
|
|
28
|
+
# Application revision. Defaults to HAWK_RELEASE or REVISION.
|
|
29
|
+
#
|
|
30
|
+
# @return [String, nil]
|
|
31
|
+
attr_accessor :release
|
|
32
|
+
|
|
33
|
+
# Detect the Git revision at initialization when release is unset. Defaults to false.
|
|
34
|
+
#
|
|
35
|
+
# @return [Boolean]
|
|
36
|
+
attr_accessor :detect_release
|
|
37
|
+
|
|
38
|
+
# Capture probability from 0.0 through 1.0. Defaults to 1.0.
|
|
39
|
+
#
|
|
40
|
+
# @return [Float]
|
|
41
|
+
attr_accessor :sample_rate
|
|
42
|
+
|
|
43
|
+
# Delivery policy: :async queues events; :sync sends in the caller. Defaults to :async.
|
|
44
|
+
#
|
|
45
|
+
# @return [Symbol]
|
|
46
|
+
attr_accessor :delivery_mode
|
|
47
|
+
|
|
48
|
+
# Maximum waiting events, as a positive integer. Defaults to 100.
|
|
49
|
+
#
|
|
50
|
+
# @return [Integer]
|
|
51
|
+
attr_accessor :queue_capacity
|
|
52
|
+
|
|
53
|
+
# Allowed roots for source snippets. Defaults to [Dir.pwd].
|
|
54
|
+
#
|
|
55
|
+
# @return [Array<String>]
|
|
56
|
+
attr_accessor :source_roots
|
|
57
|
+
|
|
58
|
+
# Include bounded source snippets from source_roots. Defaults to true.
|
|
59
|
+
#
|
|
60
|
+
# @return [Boolean]
|
|
61
|
+
attr_accessor :send_source
|
|
62
|
+
|
|
63
|
+
# Nonnegative connection timeout in seconds. Defaults to 1.0.
|
|
64
|
+
#
|
|
65
|
+
# @return [Numeric]
|
|
66
|
+
attr_accessor :connect_timeout
|
|
67
|
+
|
|
68
|
+
# Nonnegative socket read timeout in seconds. Defaults to 2.0.
|
|
69
|
+
#
|
|
70
|
+
# @return [Numeric]
|
|
71
|
+
attr_accessor :read_timeout
|
|
72
|
+
|
|
73
|
+
# Nonnegative socket write timeout in seconds. Defaults to 2.0.
|
|
74
|
+
#
|
|
75
|
+
# @return [Numeric]
|
|
76
|
+
attr_accessor :write_timeout
|
|
77
|
+
|
|
78
|
+
# Nonnegative flush and close deadline in seconds. Defaults to 5.0.
|
|
79
|
+
#
|
|
80
|
+
# @return [Numeric]
|
|
81
|
+
attr_accessor :flush_timeout
|
|
82
|
+
|
|
83
|
+
# Nonnegative fallback cooldown after collector limits, in seconds. Defaults to 60.0.
|
|
84
|
+
#
|
|
85
|
+
# @return [Numeric]
|
|
86
|
+
attr_accessor :limit_cooldown
|
|
87
|
+
|
|
88
|
+
# Initial context for execution scopes. Defaults to an empty hash.
|
|
89
|
+
#
|
|
90
|
+
# @return [Hash{String, Symbol => Object}]
|
|
91
|
+
attr_accessor :context
|
|
92
|
+
|
|
93
|
+
# Initial user data, preferably with an :id. Defaults to nil.
|
|
94
|
+
#
|
|
95
|
+
# @return [Hash{String, Symbol => Object}, nil]
|
|
96
|
+
attr_accessor :user
|
|
97
|
+
|
|
98
|
+
# Exception ancestor names excluded from capture. Defaults to an empty array.
|
|
99
|
+
#
|
|
100
|
+
# @return [Array<String>]
|
|
101
|
+
attr_accessor :ignored_exceptions
|
|
102
|
+
|
|
103
|
+
# Sensitive key patterns added to built-in filters. Defaults to an empty array.
|
|
104
|
+
#
|
|
105
|
+
# @return [Array<String, Regexp>]
|
|
106
|
+
attr_accessor :filter_parameters
|
|
107
|
+
|
|
108
|
+
# Integration switches. Unspecified integrations are enabled; defaults to an empty hash.
|
|
109
|
+
#
|
|
110
|
+
# @return [Hash{Symbol => Boolean}]
|
|
111
|
+
attr_accessor :integrations
|
|
112
|
+
|
|
113
|
+
# Install uncaught main-process exception capture and exit draining. Defaults to true.
|
|
114
|
+
#
|
|
115
|
+
# @return [Boolean]
|
|
116
|
+
attr_accessor :global_errors
|
|
117
|
+
|
|
118
|
+
# Receives a detached, filtered event hash without the token. Returns a hash to send or nil to
|
|
119
|
+
# drop. Defaults to nil.
|
|
120
|
+
#
|
|
121
|
+
# @return [#call, nil]
|
|
122
|
+
attr_accessor :before_send
|
|
123
|
+
|
|
124
|
+
# Receives a detached, filtered breadcrumb hash. Returns a hash to retain or nil to drop.
|
|
125
|
+
# Defaults to nil.
|
|
126
|
+
#
|
|
127
|
+
# @return [#call, nil]
|
|
128
|
+
attr_accessor :before_breadcrumb
|
|
129
|
+
|
|
130
|
+
# Framework filter receiving a payload hash and returning a hash or nil. Defaults to nil.
|
|
131
|
+
#
|
|
132
|
+
# @return [#call, nil]
|
|
133
|
+
attr_accessor :framework_filter
|
|
134
|
+
|
|
135
|
+
# Receives counter snapshots as `Hash{Symbol => Integer}`. Defaults to nil; return values are
|
|
136
|
+
# ignored.
|
|
137
|
+
#
|
|
138
|
+
# @return [#call, nil]
|
|
139
|
+
attr_accessor :diagnostic_callback
|
|
140
|
+
|
|
141
|
+
# Receives sanitized warnings containing counters without event data. Defaults to nil.
|
|
142
|
+
#
|
|
143
|
+
# @return [#warn, nil]
|
|
144
|
+
attr_accessor :diagnostic_logger
|
|
145
|
+
|
|
146
|
+
# Propagate explicit context and user through supported job adapters. Defaults to true.
|
|
147
|
+
#
|
|
148
|
+
# @return [Boolean]
|
|
149
|
+
attr_accessor :propagate_job_context
|
|
150
|
+
|
|
151
|
+
# Include already available request bodies without reading the input stream. Defaults to false.
|
|
152
|
+
#
|
|
153
|
+
# @return [Boolean]
|
|
154
|
+
attr_accessor :include_request_body
|
|
155
|
+
|
|
156
|
+
# Include job arguments in captured metadata. Defaults to false.
|
|
157
|
+
#
|
|
158
|
+
# @return [Boolean]
|
|
159
|
+
attr_accessor :include_job_arguments
|
|
160
|
+
|
|
161
|
+
# Include request headers, excluding cookies. Defaults to false.
|
|
162
|
+
#
|
|
163
|
+
# @return [Boolean]
|
|
164
|
+
attr_accessor :include_headers
|
|
165
|
+
|
|
166
|
+
# Include request cookies in their dedicated field. Defaults to false.
|
|
167
|
+
#
|
|
168
|
+
# @return [Boolean]
|
|
169
|
+
attr_accessor :include_cookies
|
|
170
|
+
|
|
171
|
+
# Install automatic Logger breadcrumbs. Defaults to false.
|
|
172
|
+
#
|
|
173
|
+
# @return [Boolean]
|
|
174
|
+
attr_accessor :breadcrumbs_logger
|
|
175
|
+
|
|
176
|
+
# Install automatic Net::HTTP breadcrumbs. Defaults to false.
|
|
177
|
+
#
|
|
178
|
+
# @return [Boolean]
|
|
179
|
+
attr_accessor :breadcrumbs_http
|
|
180
|
+
|
|
181
|
+
# Enable Rails notification breadcrumbs when Rails is active. Defaults to true.
|
|
182
|
+
#
|
|
183
|
+
# @return [Boolean]
|
|
184
|
+
attr_accessor :breadcrumbs_rails
|
|
185
|
+
|
|
186
|
+
# Minimum Logger severity converted into events. Defaults to nil, which disables conversion.
|
|
187
|
+
#
|
|
188
|
+
# @return [Integer, nil]
|
|
189
|
+
attr_accessor :logger_error_level
|
|
190
|
+
|
|
191
|
+
# Creates settings with environment-derived identity and bounded delivery defaults.
|
|
15
192
|
def initialize
|
|
16
193
|
initialize_identity
|
|
17
194
|
initialize_delivery
|
|
@@ -19,6 +196,10 @@ module Hawk
|
|
|
19
196
|
initialize_hooks
|
|
20
197
|
end
|
|
21
198
|
|
|
199
|
+
# Validates token, collector URL, delivery limits, sampling, and callable hooks.
|
|
200
|
+
#
|
|
201
|
+
# @return [nil]
|
|
202
|
+
# @raise [ConfigurationError] if a checked setting is invalid
|
|
22
203
|
def validate!
|
|
23
204
|
value = @token
|
|
24
205
|
Token.decode(value) if value && !value.empty?
|
|
@@ -32,12 +213,18 @@ module Hawk
|
|
|
32
213
|
nil
|
|
33
214
|
end
|
|
34
215
|
|
|
216
|
+
# @return [Boolean] whether a nonempty token and the environment permit capture
|
|
217
|
+
# @note This check does not validate the token.
|
|
35
218
|
def enabled?
|
|
36
219
|
value = @token
|
|
37
220
|
environments = @enabled_environments
|
|
38
221
|
!!(value && !value.empty? && (environments.nil? || environments.include?(@environment)))
|
|
39
222
|
end
|
|
40
223
|
|
|
224
|
+
# Resolves the configured collector URL or derives one from the token.
|
|
225
|
+
#
|
|
226
|
+
# @return [URI::HTTP, URI::HTTPS] collector URI
|
|
227
|
+
# @raise [ConfigurationError] if the token or URL is invalid
|
|
41
228
|
def collector_uri
|
|
42
229
|
override = @endpoint
|
|
43
230
|
return Token.decode(@token || "").endpoint unless override
|
|
@@ -50,6 +237,8 @@ module Hawk
|
|
|
50
237
|
raise ConfigurationError, "Invalid collector endpoint"
|
|
51
238
|
end
|
|
52
239
|
|
|
240
|
+
# @param name [Symbol] integration key, such as :rack or :sidekiq
|
|
241
|
+
# @return [Boolean] configured switch, or true when unspecified
|
|
53
242
|
def integration_enabled?(name)
|
|
54
243
|
@integrations.fetch(name, true)
|
|
55
244
|
end
|
data/lib/hawk/delayed_job.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../hawk"
|
|
3
|
+
require_relative "../hawk" unless defined?(Hawk.init)
|
|
4
4
|
require "delayed_job"
|
|
5
5
|
require "delayed/plugin"
|
|
6
6
|
|
|
7
7
|
module Hawk
|
|
8
8
|
# Native lifecycle callbacks retain retries, payloads, and failure storage.
|
|
9
|
+
# @api private
|
|
9
10
|
module DelayedJob
|
|
10
11
|
def self.install
|
|
11
12
|
return unless supported_version?
|
data/lib/hawk/delivery.rb
CHANGED
data/lib/hawk/diagnostics.rb
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
module Hawk
|
|
4
4
|
# Counters and callbacks contain no event data or collector credentials.
|
|
5
5
|
class Diagnostics
|
|
6
|
+
# @api private
|
|
6
7
|
def initialize(callback = nil, logger: nil)
|
|
7
8
|
@callback = callback
|
|
8
9
|
@logger = logger
|
|
9
10
|
reset
|
|
10
11
|
end
|
|
11
12
|
|
|
13
|
+
# @api private
|
|
12
14
|
def increment(name)
|
|
13
15
|
reset if @pid != Process.pid
|
|
14
16
|
@mutex.synchronize { @counts[name] = @counts.fetch(name, 0) + 1 }
|
|
@@ -16,6 +18,12 @@ module Hawk
|
|
|
16
18
|
nil
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# Returns a thread-safe copy of observed counters.
|
|
22
|
+
#
|
|
23
|
+
# Absent counters have not been incremented. Forked children start fresh counts.
|
|
24
|
+
#
|
|
25
|
+
# @return [Hash{Symbol => Integer}] counts such as :sent, :failed, :overflow,
|
|
26
|
+
# :filtered, and :duplicate_overflow
|
|
19
27
|
def snapshot
|
|
20
28
|
reset if @pid != Process.pid
|
|
21
29
|
@mutex.synchronize { @counts.dup }
|
data/lib/hawk/event.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Hawk
|
|
4
4
|
# Builds the native protocol payload; hooks never receive integration tokens.
|
|
5
|
+
# @api private
|
|
5
6
|
class Event
|
|
6
7
|
def initialize(configuration:, id:, exception: nil, message: nil, context: {}, user: nil,
|
|
7
8
|
breadcrumbs: [], addons: {}, level: :error, filtered_paths: [])
|
data/lib/hawk/filter.rb
CHANGED
data/lib/hawk/filtered_fields.rb
CHANGED
data/lib/hawk/hook.rb
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Hawk
|
|
4
|
+
# Discovers frameworks already loaded by the application during startup.
|
|
5
|
+
# @api private
|
|
6
|
+
module Integrations
|
|
7
|
+
def self.load
|
|
8
|
+
require_relative "rails/integration" if defined?(::Rails::Railtie)
|
|
9
|
+
require_relative "sidekiq" if defined?(::Sidekiq)
|
|
10
|
+
require_relative "resque" if defined?(::Resque)
|
|
11
|
+
require_relative "delayed_job" if defined?(::Delayed::Worker)
|
|
12
|
+
require_relative "rake" if defined?(::Rake::Task)
|
|
13
|
+
nil
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/hawk/job_context.rb
CHANGED
data/lib/hawk/json_value.rb
CHANGED
data/lib/hawk/process_hooks.rb
CHANGED
data/lib/hawk/rack/body.rb
CHANGED
data/lib/hawk/rack.rb
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../hawk"
|
|
3
|
+
require_relative "../hawk" unless defined?(Hawk.init)
|
|
4
4
|
|
|
5
5
|
module Hawk
|
|
6
6
|
# Request scope covers application calls and the deferred response body.
|
|
7
|
+
# Rack middleware reporting application and deferred response-body errors.
|
|
8
|
+
#
|
|
9
|
+
# @example Add to config.ru
|
|
10
|
+
# require "hawk-ruby"
|
|
11
|
+
# use Hawk::Rack
|
|
12
|
+
# run app
|
|
7
13
|
class Rack
|
|
14
|
+
# @param app [#call] downstream Rack application
|
|
15
|
+
# @param client [Client, nil] explicit client; nil uses Hawk.client for each request
|
|
16
|
+
# @param integration [Symbol] configuration switch controlling capture
|
|
8
17
|
def initialize(app, client: nil, integration: :rack)
|
|
9
18
|
@app = app
|
|
10
19
|
@client = client
|
|
11
20
|
@integration = integration
|
|
12
21
|
end
|
|
13
22
|
|
|
23
|
+
# Runs the application in a fresh request scope when capture is enabled.
|
|
24
|
+
#
|
|
25
|
+
# @param env [Hash{String => Object}] Rack request environment
|
|
26
|
+
# @return [Array(Integer, Hash, #each)] Rack response with a monitored body
|
|
27
|
+
# @raise [Exception] application exceptions, after reporting when eligible
|
|
14
28
|
def call(env)
|
|
15
29
|
client = active_client
|
|
16
30
|
return @app.call(env) unless client
|
|
@@ -10,6 +10,7 @@ require_relative "../breadcrumbs/rails"
|
|
|
10
10
|
|
|
11
11
|
module Hawk
|
|
12
12
|
# Framework filtering is injected without changing the user's before_send hook.
|
|
13
|
+
# @api private
|
|
13
14
|
module Rails
|
|
14
15
|
def self.configure(configuration)
|
|
15
16
|
return unless configuration.integration_enabled?(:rails)
|
|
@@ -35,9 +36,6 @@ module Hawk
|
|
|
35
36
|
ActionCable.install
|
|
36
37
|
ActiveJob.install
|
|
37
38
|
Breadcrumbs::Rails.install if configuration.breadcrumbs_rails
|
|
38
|
-
require_relative "../sidekiq" if defined?(::Sidekiq)
|
|
39
|
-
require_relative "../resque" if defined?(::Resque)
|
|
40
|
-
require_relative "../delayed_job" if defined?(::Delayed::Worker)
|
|
41
39
|
nil
|
|
42
40
|
end
|
|
43
41
|
end
|
data/lib/hawk/rake.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../hawk"
|
|
3
|
+
require_relative "../hawk" unless defined?(Hawk.init)
|
|
4
4
|
require "rake"
|
|
5
5
|
|
|
6
6
|
module Hawk
|
|
7
7
|
# Optional task capture delegates execution and preserves application errors.
|
|
8
|
+
# @api private
|
|
8
9
|
module Rake
|
|
9
10
|
# Prepended to tasks without replacing their original execute implementation.
|
|
10
11
|
module TaskMethods
|
data/lib/hawk/release.rb
CHANGED
data/lib/hawk/resque.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../hawk"
|
|
3
|
+
require_relative "../hawk" unless defined?(Hawk.init)
|
|
4
4
|
require "resque"
|
|
5
5
|
require "resque/failure"
|
|
6
6
|
|
|
7
7
|
module Hawk
|
|
8
8
|
# Resque 2.7 delegates failures to its existing backend without payload changes.
|
|
9
|
+
# @api private
|
|
9
10
|
module Resque
|
|
10
11
|
def self.install
|
|
11
12
|
return unless ::Resque::VERSION == "2.7.0"
|
data/lib/hawk/scope.rb
CHANGED
|
@@ -4,8 +4,10 @@ require "securerandom"
|
|
|
4
4
|
|
|
5
5
|
module Hawk
|
|
6
6
|
# Execution data is copied at scope boundaries and before event delivery.
|
|
7
|
+
# Mutable execution data yielded by {Hawk.with_scope} and {Client#with_scope}.
|
|
7
8
|
class Scope
|
|
8
9
|
# Identity comparison avoids invoking application exception equality methods.
|
|
10
|
+
# @api private
|
|
9
11
|
class Ledger
|
|
10
12
|
def initialize
|
|
11
13
|
@errors = {}
|
|
@@ -26,9 +28,18 @@ module Hawk
|
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
# @return [Hash{String => Object}] copied context for this execution
|
|
32
|
+
attr_reader :context
|
|
33
|
+
|
|
34
|
+
# @return [Hash{String => Object}, nil] copied user data for this execution
|
|
35
|
+
attr_reader :user
|
|
36
|
+
|
|
37
|
+
# @return [String] fallback user identifier retained across copies of this scope
|
|
38
|
+
attr_reader :anonymous_id
|
|
39
|
+
# @api private
|
|
30
40
|
attr_accessor :addons, :breadcrumbs, :ledger, :boundary, :request_metadata
|
|
31
41
|
|
|
42
|
+
# @api private
|
|
32
43
|
def initialize(context: {}, user: nil, anonymous_id: SecureRandom.uuid)
|
|
33
44
|
@context = JSONValue.object(context)
|
|
34
45
|
@user = user ? JSONValue.object(user) : nil
|
|
@@ -42,20 +53,30 @@ module Hawk
|
|
|
42
53
|
@filtered_user = false
|
|
43
54
|
end
|
|
44
55
|
|
|
56
|
+
# Merges copied context, replacing matching top-level keys.
|
|
57
|
+
#
|
|
58
|
+
# @param context [Hash{String, Symbol => Object}] application context
|
|
59
|
+
# @return [void]
|
|
45
60
|
def set_context(context)
|
|
46
61
|
update_context(context, false)
|
|
47
62
|
end
|
|
48
63
|
|
|
64
|
+
# Replaces the scoped user with copied data; nil clears it.
|
|
65
|
+
#
|
|
66
|
+
# @param user [Hash{String, Symbol => Object}, nil] user data
|
|
67
|
+
# @return [void]
|
|
49
68
|
def set_user(user)
|
|
50
69
|
update_user(user, false)
|
|
51
70
|
end
|
|
52
71
|
|
|
72
|
+
# @api private
|
|
53
73
|
def restore_filtered(context, user)
|
|
54
74
|
update_context(context, true)
|
|
55
75
|
update_user(user, true) if user
|
|
56
76
|
nil
|
|
57
77
|
end
|
|
58
78
|
|
|
79
|
+
# @api private
|
|
59
80
|
def filtered_paths(except_context: [], user_override: false)
|
|
60
81
|
paths = (@filtered_context_keys.keys - except_context).map { |key| ["context", key] }
|
|
61
82
|
paths << ["user"] if @filtered_user && !user_override
|
|
@@ -63,11 +84,13 @@ module Hawk
|
|
|
63
84
|
paths
|
|
64
85
|
end
|
|
65
86
|
|
|
87
|
+
# @api private
|
|
66
88
|
def event_addons
|
|
67
89
|
reader = @request_metadata
|
|
68
90
|
reader ? @addons.merge("request" => reader.call) : @addons
|
|
69
91
|
end
|
|
70
92
|
|
|
93
|
+
# @api private
|
|
71
94
|
def event_data(context, user, default_user, addons)
|
|
72
95
|
context = JSONValue.object(context)
|
|
73
96
|
value = JSONValue.object(user || @user || default_user || {})
|
|
@@ -76,6 +99,7 @@ module Hawk
|
|
|
76
99
|
filtered_paths: filtered_paths(except_context: context.keys, user_override: !user.nil?) }
|
|
77
100
|
end
|
|
78
101
|
|
|
102
|
+
# @api private
|
|
79
103
|
def copy
|
|
80
104
|
duplicate = Scope.new(context: @context, user: @user, anonymous_id: @anonymous_id)
|
|
81
105
|
duplicate.addons = JSONValue.object(@addons)
|
data/lib/hawk/scope_store.rb
CHANGED
data/lib/hawk/sidekiq.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../hawk"
|
|
3
|
+
require_relative "../hawk" unless defined?(Hawk.init)
|
|
4
4
|
require "sidekiq"
|
|
5
5
|
|
|
6
6
|
module Hawk
|
|
7
7
|
# Native middleware covers each backend attempt, including pre-execution errors.
|
|
8
|
+
# @api private
|
|
8
9
|
module Sidekiq
|
|
9
10
|
def self.install
|
|
10
11
|
return unless ::Sidekiq::VERSION.match?(/\A[78]\./)
|
data/lib/hawk/source.rb
CHANGED
data/lib/hawk/token.rb
CHANGED
|
@@ -5,9 +5,11 @@ require "json"
|
|
|
5
5
|
require "uri"
|
|
6
6
|
|
|
7
7
|
module Hawk
|
|
8
|
+
# Raised when client configuration or its integration token is invalid.
|
|
8
9
|
class ConfigurationError < ArgumentError; end
|
|
9
10
|
|
|
10
11
|
# Resolves collector identity without exposing the integration secret.
|
|
12
|
+
# @api private
|
|
11
13
|
class Token
|
|
12
14
|
LABEL = /\A[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\z/i
|
|
13
15
|
|
data/lib/hawk/transport.rb
CHANGED
data/lib/hawk/version.rb
CHANGED
data/lib/hawk-ruby.rb
ADDED