forge_ops_tracker 0.15.1 → 0.16.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/CHANGELOG.md +19 -0
- data/README.md +44 -13
- data/lib/forge_ops_tracker/configuration.rb +31 -2
- data/lib/forge_ops_tracker/middleware/request_context.rb +34 -3
- data/lib/forge_ops_tracker/railtie.rb +13 -3
- data/lib/forge_ops_tracker/version.rb +1 -1
- data/lib/forge_ops_tracker.rb +48 -2
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a535fb7cb193fd614ee40259a9b20e62832149c7a2dbeb7d1d40253c0630f65a
|
|
4
|
+
data.tar.gz: 559a19cd52a56addacc87c5533bc0954c7ca2de6eac81a6afb18769f280c06c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 158342795c1dbb5e7575da43ddcd239c25b52111c268ede3fdfdbb9b5621cf1a10cd120e602f75fe2e57bd46faed9483aaa1a61f8c9f91770474210414400e8f
|
|
7
|
+
data.tar.gz: 5b4f11f1758833c58f8925f1354f8a7da49b80d04344cc2c340a2662a186fcfc0a8451709faef4c78a60d618c9f0ea936c460c97b3af8bad2687fbc8f6fbfdae
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.0 (2026-10-02)
|
|
4
|
+
|
|
5
|
+
- Changed: outside Rails, the environment now defaults to `production` when nothing sets it (it
|
|
6
|
+
was `development`). It comes from `FORGE_OPS_ENVIRONMENT`, then `RAILS_ENV`, then `RACK_ENV`,
|
|
7
|
+
then `production`. Only `production` and `staging` send by default, so before this a plain Ruby
|
|
8
|
+
or Rack process that set just a DSN sent nothing at all. To keep the old behavior there, set
|
|
9
|
+
`FORGE_OPS_ENVIRONMENT=development` (or `RACK_ENV=development`, or `config.environment`).
|
|
10
|
+
- Changed: under Rails, `FORGE_OPS_ENVIRONMENT` now takes precedence over `Rails.env` when it's
|
|
11
|
+
set. Without it nothing changes: development and test still don't send.
|
|
12
|
+
- When a DSN is set but the environment isn't in `enabled_environments`, one warning is now logged
|
|
13
|
+
per process, naming the environment and how to send from it: at boot under Rails (to
|
|
14
|
+
`Rails.logger`), otherwise from `configure`, the Rack middleware, or `capture_exception` (to
|
|
15
|
+
`config.logger`, or stderr when there isn't one). Nothing is logged when no DSN is set.
|
|
16
|
+
- New `ForgeOpsTracker.capture_exception(error, context: {})` reports an exception you've rescued,
|
|
17
|
+
through the same path `Rails.error` reports into, so it works without Rails too.
|
|
18
|
+
- Plain Rack and Sinatra apps are now covered: `use ForgeOpsTracker::Middleware::RequestContext`
|
|
19
|
+
reports an exception escaping the app, and an error Sinatra itself turned into a 5xx response.
|
|
20
|
+
Under Rails it still only adds request context, since `Rails.error` already reports those.
|
|
21
|
+
|
|
3
22
|
## 0.15.1 (2026-10-01)
|
|
4
23
|
|
|
5
24
|
- Errors reported just before a process exits are now sent before it ends. Delivery runs on a
|
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# ForgeOpsTracker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Exception reporting client for [ForgeOps](https://getforgeops.net), for Rails, plain Rack and
|
|
4
|
+
Sinatra apps, and scripts.
|
|
4
5
|
|
|
5
6
|
## Installation
|
|
6
7
|
|
|
@@ -25,6 +26,11 @@ ForgeOpsTracker.configure do |config|
|
|
|
25
26
|
end
|
|
26
27
|
```
|
|
27
28
|
|
|
29
|
+
The environment is `FORGE_OPS_ENVIRONMENT` when set, otherwise `Rails.env` under Rails, and
|
|
30
|
+
outside Rails `RAILS_ENV`, then `RACK_ENV`, then `production`. Only `production` and `staging`
|
|
31
|
+
send by default, so a Rails app in development or test doesn't report. When a DSN is set but the
|
|
32
|
+
environment isn't enabled, one warning is logged per process (at boot under Rails) saying so.
|
|
33
|
+
|
|
28
34
|
Delivery happens on a small background thread with a bounded queue and short HTTP timeouts. Every
|
|
29
35
|
failure mode (network errors, timeouts, a full queue, a malformed DSN) is caught and dropped
|
|
30
36
|
rather than raised, so a broken or unreachable tracker can never take down the host app.
|
|
@@ -71,6 +77,34 @@ Bottom line: if an exception would otherwise crash something, you're already cov
|
|
|
71
77
|
code already catches and handles it, route that specific `rescue` through `Rails.error.handle`/
|
|
72
78
|
`.record` instead of a bare one wherever you want ForgeOps to know about it.
|
|
73
79
|
|
|
80
|
+
### Outside Rails: Rack, Sinatra, and scripts
|
|
81
|
+
|
|
82
|
+
Without Rails there's no `Rails.error`, so add the Rack middleware, which reports any exception
|
|
83
|
+
escaping your app (and, in Sinatra, an error it turned into a 5xx response itself), then re-raises
|
|
84
|
+
it unchanged:
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
# config.ru, or inside a Sinatra::Base subclass
|
|
88
|
+
require "forge_ops_tracker"
|
|
89
|
+
|
|
90
|
+
ForgeOpsTracker.configure do |config|
|
|
91
|
+
config.dsn = ENV["FORGE_OPS_DSN"]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
use ForgeOpsTracker::Middleware::RequestContext
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Report an exception you rescued yourself, anywhere (Rails included), with
|
|
98
|
+
`ForgeOpsTracker.capture_exception`:
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
begin
|
|
102
|
+
charge_card(order)
|
|
103
|
+
rescue Stripe::CardError => e
|
|
104
|
+
ForgeOpsTracker.capture_exception(e, context: { order_id: order.id })
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
74
108
|
### Sidekiq job failures and renamed job classes
|
|
75
109
|
|
|
76
110
|
A failing Sidekiq job is reported through `Rails.error` like any other error. Since 0.10.1 the issue
|
|
@@ -254,7 +288,7 @@ end
|
|
|
254
288
|
```
|
|
255
289
|
|
|
256
290
|
Requires a ForgeOps plan that includes release health; on a plan that doesn't, the periodic
|
|
257
|
-
flushes are
|
|
291
|
+
flushes are accepted but not recorded, and the response says why.
|
|
258
292
|
|
|
259
293
|
## Performance monitoring
|
|
260
294
|
|
|
@@ -279,8 +313,7 @@ end
|
|
|
279
313
|
```
|
|
280
314
|
|
|
281
315
|
Requires a ForgeOps plan that includes performance monitoring; on a plan that doesn't, the
|
|
282
|
-
periodic flushes are
|
|
283
|
-
failure.
|
|
316
|
+
periodic flushes are accepted but not recorded, and the response says why.
|
|
284
317
|
|
|
285
318
|
### Database queries, background jobs, and outbound HTTP calls
|
|
286
319
|
|
|
@@ -353,8 +386,7 @@ unaffected: confirmed directly that Net::HTTP connects lazily, inside `#request`
|
|
|
353
386
|
time it's called on a not-yet-started instance.
|
|
354
387
|
|
|
355
388
|
Requires a ForgeOps plan that includes performance monitoring, the same plan feature performance
|
|
356
|
-
monitoring itself already requires; on a plan that doesn't, the periodic flushes are
|
|
357
|
-
rejected server-side and dropped, exactly like any other delivery failure.
|
|
389
|
+
monitoring itself already requires; on a plan that doesn't, the periodic flushes are accepted but not recorded, and the response says why.
|
|
358
390
|
|
|
359
391
|
## Tracing
|
|
360
392
|
|
|
@@ -408,7 +440,7 @@ end
|
|
|
408
440
|
```
|
|
409
441
|
|
|
410
442
|
Requires a ForgeOps plan that includes distributed tracing; on a plan that doesn't, traces are
|
|
411
|
-
|
|
443
|
+
accepted but not recorded, and the response says why. The `trace_id`
|
|
412
444
|
on error events is sent either way.
|
|
413
445
|
|
|
414
446
|
### The SQL behind each database span
|
|
@@ -476,7 +508,7 @@ What it doesn't do:
|
|
|
476
508
|
It does use one pooled connection, briefly, for each plan. With the limits above that's at most 10
|
|
477
509
|
short checkouts a minute, but on a pool that's already at capacity, leave it off or raise
|
|
478
510
|
`explain_threshold_ms`. Plans are part of performance monitoring; on a plan without it, they're
|
|
479
|
-
|
|
511
|
+
accepted but not recorded, and the response says why.
|
|
480
512
|
|
|
481
513
|
## What changed
|
|
482
514
|
|
|
@@ -521,8 +553,8 @@ their values), so an added or removed variable shows up as a change. Names that
|
|
|
521
553
|
host, like `HOSTNAME`, `PATH`, `PORT`, `LC_*`, and Kubernetes service variables, are left out, as
|
|
522
554
|
are the gem's own `FORGE_OPS_*` settings.
|
|
523
555
|
|
|
524
|
-
Requires a ForgeOps plan that includes change tracking; on a plan that doesn't, both are
|
|
525
|
-
|
|
556
|
+
Requires a ForgeOps plan that includes change tracking; on a plan that doesn't, both are accepted but not recorded,
|
|
557
|
+
and the response says why.
|
|
526
558
|
|
|
527
559
|
## Custom metrics
|
|
528
560
|
|
|
@@ -543,7 +575,7 @@ end
|
|
|
543
575
|
```
|
|
544
576
|
|
|
545
577
|
Requires a ForgeOps plan that includes custom metrics; on a plan that doesn't, the periodic
|
|
546
|
-
flushes are
|
|
578
|
+
flushes are accepted but not recorded, and the response says why.
|
|
547
579
|
|
|
548
580
|
## Infrastructure monitoring
|
|
549
581
|
|
|
@@ -572,5 +604,4 @@ ForgeOpsTracker.capture_infrastructure_metric("disk_used_percent", value: disk_u
|
|
|
572
604
|
|
|
573
605
|
The example above is Linux-specific (`/proc/loadavg`, `/proc/meminfo`); on another OS, read that
|
|
574
606
|
platform's own equivalents instead. Requires a ForgeOps plan that includes infrastructure
|
|
575
|
-
monitoring; on a plan that doesn't, the periodic flushes are
|
|
576
|
-
dropped, exactly like any other delivery failure.
|
|
607
|
+
monitoring; on a plan that doesn't, the periodic flushes are accepted but not recorded, and the response says why.
|
|
@@ -23,7 +23,7 @@ module ForgeOpsTracker
|
|
|
23
23
|
|
|
24
24
|
def initialize
|
|
25
25
|
@dsn = ENV["FORGE_OPS_DSN"]
|
|
26
|
-
@environment =
|
|
26
|
+
@environment = self.class.resolve_environment
|
|
27
27
|
@release = ENV["FORGE_OPS_RELEASE"]
|
|
28
28
|
@server_name = safe_hostname
|
|
29
29
|
@enabled_environments = %w[production staging]
|
|
@@ -262,10 +262,39 @@ module ForgeOpsTracker
|
|
|
262
262
|
end
|
|
263
263
|
|
|
264
264
|
def enabled?
|
|
265
|
-
|
|
265
|
+
configured? && environment_enabled?
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Whether a usable DSN is set, regardless of environment.
|
|
269
|
+
def configured?
|
|
270
|
+
!blank?(dsn) && !blank?(api_key)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# The one-line warning ForgeOpsTracker.warn_if_environment_disabled logs when a DSN is set but
|
|
274
|
+
# this environment isn't one that sends, or nil when there's nothing to warn about (no DSN, or
|
|
275
|
+
# the environment is enabled).
|
|
276
|
+
def disabled_environment_warning
|
|
277
|
+
return nil if !configured? || environment_enabled?
|
|
278
|
+
|
|
279
|
+
enabled = enabled_environments.map(&:to_s)
|
|
280
|
+
enabled = enabled.empty? ? "none" : enabled.join(", ")
|
|
281
|
+
"[ForgeOps] Not sending: this environment is \"#{environment}\", and only #{enabled} are enabled. " \
|
|
282
|
+
"Set FORGE_OPS_ENVIRONMENT=production (or add \"#{environment}\" to enabled_environments) to send from here."
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# FORGE_OPS_ENVIRONMENT, then RAILS_ENV, then RACK_ENV, then "production". Defaulting to
|
|
286
|
+
# "production" means a plain Ruby or Rack process that only sets a DSN actually sends; a Rails
|
|
287
|
+
# app gets Rails.env from the Railtie instead (unless FORGE_OPS_ENVIRONMENT is set), so
|
|
288
|
+
# development and test stay quiet there, with one warning at boot when a DSN is set.
|
|
289
|
+
def self.resolve_environment(env = ENV)
|
|
290
|
+
[ env["FORGE_OPS_ENVIRONMENT"], env["RAILS_ENV"], env["RACK_ENV"] ].find { |value| value && !value.strip.empty? } || "production"
|
|
266
291
|
end
|
|
267
292
|
|
|
268
293
|
private
|
|
294
|
+
def environment_enabled?
|
|
295
|
+
enabled_environments.map(&:to_s).include?(environment.to_s)
|
|
296
|
+
end
|
|
297
|
+
|
|
269
298
|
# Same substitution every *_uri method above spells out by hand: a sibling path under the
|
|
270
299
|
# DSN's own /api/v1/events.
|
|
271
300
|
def sibling_uri(path)
|
|
@@ -19,6 +19,14 @@ module ForgeOpsTracker
|
|
|
19
19
|
# Rescues Exception, not StandardError, and always re-raises: this only ever observes an
|
|
20
20
|
# exception on its way out, it never handles one, so there's no reason to let anything slip
|
|
21
21
|
# past without its context attached.
|
|
22
|
+
#
|
|
23
|
+
# Outside Rails it is also what reports an unhandled request error, since there's no
|
|
24
|
+
# Rails.error to do it: add it to a plain Rack or Sinatra app with
|
|
25
|
+
# `use ForgeOpsTracker::Middleware::RequestContext`. It reports a StandardError escaping the
|
|
26
|
+
# app, and a Sinatra error the app turned into a 5xx response itself (Sinatra keeps that in
|
|
27
|
+
# env["sinatra.error"] rather than raising it when raise_errors is off, its production
|
|
28
|
+
# default). report_exceptions defaults to true only when Rails isn't loaded, and the Railtie
|
|
29
|
+
# passes false, so nothing is reported twice under Rails.
|
|
22
30
|
class RequestContext
|
|
23
31
|
THREAD_KEY = :forge_ops_tracker_request_context
|
|
24
32
|
|
|
@@ -28,9 +36,13 @@ module ForgeOpsTracker
|
|
|
28
36
|
# app raised them.
|
|
29
37
|
SNAPSHOT_IVAR = :@__forge_ops_tracker_request_snapshot
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
FRAMEWORK_ERROR_KEY = "sinatra.error".freeze
|
|
40
|
+
|
|
41
|
+
def initialize(app, configuration: ForgeOpsTracker.configuration, report_exceptions: !defined?(::Rails::Railtie))
|
|
32
42
|
@app = app
|
|
33
43
|
@configuration = configuration
|
|
44
|
+
@report_exceptions = report_exceptions
|
|
45
|
+
ForgeOpsTracker.warn_if_environment_disabled if report_exceptions && configuration.equal?(ForgeOpsTracker.configuration)
|
|
34
46
|
end
|
|
35
47
|
|
|
36
48
|
def call(env)
|
|
@@ -38,11 +50,14 @@ module ForgeOpsTracker
|
|
|
38
50
|
|
|
39
51
|
state = RequestState.for(env)
|
|
40
52
|
Thread.current[THREAD_KEY] = state
|
|
41
|
-
app.call(env)
|
|
53
|
+
response = app.call(env)
|
|
54
|
+
report_framework_error(env, response) if report_exceptions
|
|
55
|
+
response
|
|
42
56
|
rescue Exception => e
|
|
43
57
|
if state
|
|
44
58
|
state.mark_errored!
|
|
45
59
|
self.class.attach_snapshot(e, state)
|
|
60
|
+
report(e, env) if report_exceptions && e.is_a?(StandardError)
|
|
46
61
|
end
|
|
47
62
|
raise
|
|
48
63
|
ensure
|
|
@@ -84,7 +99,23 @@ module ForgeOpsTracker
|
|
|
84
99
|
end
|
|
85
100
|
|
|
86
101
|
private
|
|
87
|
-
attr_reader :app, :configuration
|
|
102
|
+
attr_reader :app, :configuration, :report_exceptions
|
|
103
|
+
|
|
104
|
+
# Called while this request's RequestState and the other middlewares' thread-locals are
|
|
105
|
+
# all still set, so the report carries the trace id, user and breadcrumbs.
|
|
106
|
+
def report(error, env)
|
|
107
|
+
ForgeOpsTracker.capture_exception(error, context: { "path" => env["PATH_INFO"], "method" => env["REQUEST_METHOD"] }.compact)
|
|
108
|
+
rescue StandardError
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def report_framework_error(env, response)
|
|
113
|
+
error = env[FRAMEWORK_ERROR_KEY]
|
|
114
|
+
return unless error.is_a?(StandardError) && response.is_a?(Array) && response.first.to_i >= 500
|
|
115
|
+
|
|
116
|
+
RequestContext.current&.mark_errored!
|
|
117
|
+
report(error, env)
|
|
118
|
+
end
|
|
88
119
|
end
|
|
89
120
|
end
|
|
90
121
|
end
|
|
@@ -38,10 +38,19 @@ module ForgeOpsTracker
|
|
|
38
38
|
initializer "forge_ops_tracker.subscribe_error_reporter" do |app|
|
|
39
39
|
configuration = ForgeOpsTracker.configuration
|
|
40
40
|
configuration.app_root ||= app.root.to_s
|
|
41
|
-
|
|
41
|
+
# FORGE_OPS_ENVIRONMENT wins when set, so a staging box running RAILS_ENV=production can
|
|
42
|
+
# still report as staging; otherwise Rails.env, so development and test stay quiet.
|
|
43
|
+
forge_ops_environment = ENV["FORGE_OPS_ENVIRONMENT"].to_s.strip
|
|
44
|
+
configuration.environment = forge_ops_environment.empty? ? Rails.env.to_s : forge_ops_environment
|
|
42
45
|
configuration.logger ||= Rails.logger
|
|
43
46
|
|
|
44
|
-
Rails.error.subscribe(ForgeOpsTracker
|
|
47
|
+
Rails.error.subscribe(ForgeOpsTracker.error_subscriber)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# After every config/initializers file has run, so the DSN and environment are final: one
|
|
51
|
+
# warning at boot when a DSN is set but this environment doesn't send (development, say).
|
|
52
|
+
config.after_initialize do
|
|
53
|
+
ForgeOpsTracker.warn_if_environment_disabled
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
initializer "forge_ops_tracker.track_sessions" do |app|
|
|
@@ -94,7 +103,8 @@ module ForgeOpsTracker
|
|
|
94
103
|
# PerformanceInstrumentation.controller_endpoint for what each is used for).
|
|
95
104
|
initializer "forge_ops_tracker.request_context" do |app|
|
|
96
105
|
configuration = ForgeOpsTracker.configuration
|
|
97
|
-
|
|
106
|
+
# report_exceptions: false because Rails.error already reports an unhandled request error.
|
|
107
|
+
app.middleware.use ForgeOpsTracker::Middleware::RequestContext, configuration: configuration, report_exceptions: false
|
|
98
108
|
|
|
99
109
|
ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |*args|
|
|
100
110
|
next unless configuration.enabled?
|
data/lib/forge_ops_tracker.rb
CHANGED
|
@@ -30,6 +30,8 @@ require "forge_ops_tracker/middleware/span_tracing"
|
|
|
30
30
|
require "forge_ops_tracker/middleware/request_context"
|
|
31
31
|
|
|
32
32
|
module ForgeOpsTracker
|
|
33
|
+
ENVIRONMENT_WARNING_LOCK = Mutex.new
|
|
34
|
+
|
|
33
35
|
class << self
|
|
34
36
|
def configuration
|
|
35
37
|
@configuration ||= Configuration.new
|
|
@@ -37,10 +39,54 @@ module ForgeOpsTracker
|
|
|
37
39
|
|
|
38
40
|
# Outside Rails this is also where the startup ChangeSnapshot goes out, since there's no
|
|
39
41
|
# Railtie to send it once the app has booted; under Rails the Railtie sends it instead, after
|
|
40
|
-
# initialization, when Active Record can report the migration version.
|
|
42
|
+
# initialization, when Active Record can report the migration version. The same goes for the
|
|
43
|
+
# one-time "Not sending" warning (see warn_if_environment_disabled).
|
|
41
44
|
def configure
|
|
42
45
|
yield configuration
|
|
43
|
-
|
|
46
|
+
return if defined?(::Rails::Railtie)
|
|
47
|
+
|
|
48
|
+
warn_if_environment_disabled
|
|
49
|
+
ChangeSnapshot.start(configuration)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Reports an exception you've already rescued, e.g. from a Sinatra error handler, a plain Rack
|
|
53
|
+
# app, a script, or a background worker that isn't wired through Rails.error. Goes through the
|
|
54
|
+
# same ErrorSubscriber Rails.error reports into, so it carries the current request's user,
|
|
55
|
+
# breadcrumbs and trace the same way, and is a no-op when the gem isn't enabled. Under Rails,
|
|
56
|
+
# Rails.error.report/handle/record do the same thing. Never raises.
|
|
57
|
+
def capture_exception(error, context: {})
|
|
58
|
+
warn_if_environment_disabled unless configuration.enabled?
|
|
59
|
+
error_subscriber.report(error, handled: true, context: context || {}, source: "application")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The one ErrorSubscriber this process reports through: the Railtie subscribes it to
|
|
63
|
+
# Rails.error, and capture_exception calls it directly, so both share one delivery queue.
|
|
64
|
+
def error_subscriber
|
|
65
|
+
@error_subscriber ||= ErrorSubscriber.new(configuration)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Logs one warning per process when a DSN is set but the environment isn't in
|
|
69
|
+
# enabled_environments, so a process that would send nothing says so instead of staying
|
|
70
|
+
# silent. Goes to configuration.logger (Rails.logger under Rails), or $stderr when there isn't
|
|
71
|
+
# one. Never logs without a DSN. Returns whether it logged.
|
|
72
|
+
def warn_if_environment_disabled
|
|
73
|
+
message = configuration.disabled_environment_warning
|
|
74
|
+
return false unless message
|
|
75
|
+
|
|
76
|
+
ENVIRONMENT_WARNING_LOCK.synchronize do
|
|
77
|
+
return false if @environment_warning_logged
|
|
78
|
+
|
|
79
|
+
@environment_warning_logged = true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if configuration.logger
|
|
83
|
+
configuration.logger.warn(message)
|
|
84
|
+
else
|
|
85
|
+
Kernel.warn(message)
|
|
86
|
+
end
|
|
87
|
+
true
|
|
88
|
+
rescue StandardError
|
|
89
|
+
false
|
|
44
90
|
end
|
|
45
91
|
|
|
46
92
|
# Records one thing that changed in a running system, e.g.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forge_ops_tracker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ForgeOps
|
|
@@ -79,6 +79,20 @@ dependencies:
|
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
81
|
version: '0.30'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rack
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '2.2'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '2.2'
|
|
82
96
|
description: Hooks Rails' error reporter and reports exceptions to ForgeOps over HTTP,
|
|
83
97
|
without ever raising back into the host application.
|
|
84
98
|
executables: []
|