appsignal 3.11.0 → 3.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +109 -0
- data/Rakefile +1 -1
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +150 -32
- data/lib/appsignal/demo.rb +1 -6
- data/lib/appsignal/integrations/grape.rb +7 -0
- data/lib/appsignal/integrations/hanami.rb +8 -43
- data/lib/appsignal/integrations/padrino.rb +8 -73
- data/lib/appsignal/integrations/railtie.rb +35 -13
- data/lib/appsignal/integrations/sinatra.rb +8 -19
- data/lib/appsignal/loaders/grape.rb +13 -0
- data/lib/appsignal/loaders/hanami.rb +40 -0
- data/lib/appsignal/loaders/padrino.rb +68 -0
- data/lib/appsignal/loaders/sinatra.rb +24 -0
- data/lib/appsignal/loaders.rb +92 -0
- data/lib/appsignal/rack/abstract_middleware.rb +2 -1
- data/lib/appsignal/rack/event_handler.rb +5 -5
- data/lib/appsignal/rack.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +163 -9
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
- data/spec/lib/appsignal/config_spec.rb +153 -1
- data/spec/lib/appsignal/demo_spec.rb +1 -2
- data/spec/lib/appsignal/environment_spec.rb +4 -2
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/activejob_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
- data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
- data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
- data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
- data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
- data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
- data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
- data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
- data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +11 -9
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
- data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
- data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
- data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
- data/spec/lib/appsignal/loaders_spec.rb +137 -0
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/probes_spec.rb +6 -5
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +3 -2
- data/spec/lib/appsignal/rack/event_handler_spec.rb +33 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
- data/spec/lib/appsignal/span_spec.rb +1 -3
- data/spec/lib/appsignal/transaction_spec.rb +4 -2
- data/spec/lib/appsignal_spec.rb +278 -26
- data/spec/lib/puma/appsignal_spec.rb +0 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/loader_helper.rb +21 -0
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
- data/spec/support/testing.rb +46 -0
- metadata +15 -2
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Loaders
|
5
|
+
class HanamiLoader < Loader
|
6
|
+
register :hanami
|
7
|
+
|
8
|
+
def on_load
|
9
|
+
hanami_app_config = ::Hanami.app.config
|
10
|
+
register_config_defaults(
|
11
|
+
:root_path => hanami_app_config.root.to_s,
|
12
|
+
:env => hanami_app_config.env
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_start
|
17
|
+
require "appsignal/rack/hanami_middleware"
|
18
|
+
|
19
|
+
hanami_app_config = ::Hanami.app.config
|
20
|
+
hanami_app_config.middleware.use(
|
21
|
+
::Rack::Events,
|
22
|
+
[Appsignal::Rack::EventHandler.new]
|
23
|
+
)
|
24
|
+
hanami_app_config.middleware.use(Appsignal::Rack::HanamiMiddleware)
|
25
|
+
|
26
|
+
::Hanami::Action.prepend Appsignal::Loaders::HanamiLoader::HanamiIntegration
|
27
|
+
end
|
28
|
+
|
29
|
+
module HanamiIntegration
|
30
|
+
def call(env)
|
31
|
+
super
|
32
|
+
ensure
|
33
|
+
transaction = env[::Appsignal::Rack::APPSIGNAL_TRANSACTION]
|
34
|
+
|
35
|
+
transaction&.set_action_if_nil(self.class.name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Loaders
|
5
|
+
class PadrinoLoader < Loader
|
6
|
+
register :padrino
|
7
|
+
|
8
|
+
def on_load
|
9
|
+
register_config_defaults(
|
10
|
+
:root_path => Padrino.mounted_root,
|
11
|
+
:env => Padrino.env
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_start
|
16
|
+
require "appsignal/rack/sinatra_instrumentation"
|
17
|
+
|
18
|
+
Padrino::Application.prepend(Appsignal::Loaders::PadrinoLoader::PadrinoIntegration)
|
19
|
+
|
20
|
+
Padrino.before_load do
|
21
|
+
Padrino.use ::Rack::Events, [Appsignal::Rack::EventHandler.new]
|
22
|
+
Padrino.use Appsignal::Rack::SinatraBaseInstrumentation,
|
23
|
+
:instrument_event_name => "process_action.padrino"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module PadrinoIntegration
|
28
|
+
def route!(base = settings, pass_block = nil)
|
29
|
+
return super if !Appsignal.active? || env["sinatra.static_file"]
|
30
|
+
|
31
|
+
begin
|
32
|
+
super
|
33
|
+
ensure
|
34
|
+
transaction = Appsignal::Transaction.current
|
35
|
+
transaction.set_action_if_nil(get_payload_action(request))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def get_payload_action(request)
|
42
|
+
# Short-circuit is there's no request object to obtain information from
|
43
|
+
return settings.name.to_s unless request
|
44
|
+
|
45
|
+
# Newer versions expose the action / controller on the request class.
|
46
|
+
# Newer versions also still expose a route_obj so we must prioritize the
|
47
|
+
# action/fullpath methods.
|
48
|
+
# The `request.action` and `request.controller` values are `nil` when a
|
49
|
+
# endpoint is not found, `""` if not specified by the user.
|
50
|
+
controller_name = request.controller if request.respond_to?(:controller)
|
51
|
+
action_name = request.action if request.respond_to?(:action)
|
52
|
+
action_name ||= ""
|
53
|
+
|
54
|
+
return "#{settings.name}:#{controller_name}##{action_name}" unless action_name.empty?
|
55
|
+
|
56
|
+
# Older versions of Padrino work with a route object
|
57
|
+
if request.respond_to?(:route_obj) && request.route_obj
|
58
|
+
return "#{settings.name}:#{request.route_obj.original_path}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Fall back to the application name if we haven't found an action name in
|
62
|
+
# any previous methods.
|
63
|
+
"#{settings.name}#unknown"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Loaders
|
5
|
+
class SinatraLoader < Loader
|
6
|
+
register :sinatra
|
7
|
+
|
8
|
+
def on_load
|
9
|
+
app_settings = ::Sinatra::Application.settings
|
10
|
+
register_config_defaults(
|
11
|
+
:root_path => app_settings.root,
|
12
|
+
:env => app_settings.environment
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_start
|
17
|
+
require "appsignal/rack/sinatra_instrumentation"
|
18
|
+
|
19
|
+
::Sinatra::Base.use(::Rack::Events, [Appsignal::Rack::EventHandler.new])
|
20
|
+
::Sinatra::Base.use(Appsignal::Rack::SinatraBaseInstrumentation)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
# @api private
|
5
|
+
module Loaders
|
6
|
+
class << self
|
7
|
+
def loaders
|
8
|
+
@loaders ||= {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def instances
|
12
|
+
@instances ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(name, klass)
|
16
|
+
loaders[name.to_sym] = klass
|
17
|
+
end
|
18
|
+
|
19
|
+
def registered?(name)
|
20
|
+
loaders.key?(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def unregister(name)
|
24
|
+
loaders.delete(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def load(name_str)
|
28
|
+
name = name_str.to_sym
|
29
|
+
|
30
|
+
unless registered?(name)
|
31
|
+
require_loader(name)
|
32
|
+
unless registered?(name)
|
33
|
+
Appsignal.internal_logger
|
34
|
+
.warn("No loader found with the name '#{name}'.")
|
35
|
+
return
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Appsignal.internal_logger.debug("Loading '#{name}' loader")
|
40
|
+
|
41
|
+
begin
|
42
|
+
loader_klass = loaders[name]
|
43
|
+
loader = loader_klass.new
|
44
|
+
instances[name] = loader
|
45
|
+
loader.on_load if loader.respond_to?(:on_load)
|
46
|
+
rescue => e
|
47
|
+
Appsignal.internal_logger.error(
|
48
|
+
"An error occurred while loading the '#{name}' loader: " \
|
49
|
+
"#{e.class}: #{e.message}\n#{e.backtrace}"
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def start
|
55
|
+
instances.each do |name, instance|
|
56
|
+
Appsignal.internal_logger.debug("Starting '#{name}' loader")
|
57
|
+
begin
|
58
|
+
instance.on_start if instance.respond_to?(:on_start)
|
59
|
+
rescue => e
|
60
|
+
Appsignal.internal_logger.error(
|
61
|
+
"An error occurred while starting the '#{name}' loader: " \
|
62
|
+
"#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def require_loader(name)
|
71
|
+
require "appsignal/loaders/#{name}"
|
72
|
+
rescue LoadError
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Loader
|
78
|
+
class << self
|
79
|
+
attr_reader :loader_name
|
80
|
+
|
81
|
+
def register(name)
|
82
|
+
@loader_name = name
|
83
|
+
Loaders.register(name, self)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def register_config_defaults(options)
|
88
|
+
Appsignal::Config.add_loader_defaults(self.class.loader_name, options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -91,9 +91,10 @@ module Appsignal
|
|
91
91
|
def call_app(env, transaction)
|
92
92
|
status, headers, obody = @app.call(env)
|
93
93
|
body =
|
94
|
-
if
|
94
|
+
if env[Appsignal::Rack::APPSIGNAL_RESPONSE_INSTRUMENTED]
|
95
95
|
obody
|
96
96
|
else
|
97
|
+
env[Appsignal::Rack::APPSIGNAL_RESPONSE_INSTRUMENTED] = true
|
97
98
|
# Instrument response body and closing of the response body
|
98
99
|
Appsignal::Rack::BodyWrapper.wrap(obody, transaction)
|
99
100
|
end
|
@@ -2,11 +2,6 @@
|
|
2
2
|
|
3
3
|
module Appsignal
|
4
4
|
module Rack
|
5
|
-
APPSIGNAL_TRANSACTION = "appsignal.transaction"
|
6
|
-
APPSIGNAL_EVENT_HANDLER_ID = "appsignal.event_handler_id"
|
7
|
-
APPSIGNAL_EVENT_HANDLER_HAS_ERROR = "appsignal.event_handler.error"
|
8
|
-
RACK_AFTER_REPLY = "rack.after_reply"
|
9
|
-
|
10
5
|
# Instrumentation middleware using Rack's Events module.
|
11
6
|
#
|
12
7
|
# We recommend using this in combination with the
|
@@ -56,6 +51,8 @@ module Appsignal
|
|
56
51
|
|
57
52
|
# @api private
|
58
53
|
def on_start(request, _response)
|
54
|
+
return unless Appsignal.active?
|
55
|
+
|
59
56
|
event_handler = self
|
60
57
|
self.class.safe_execution("Appsignal::Rack::EventHandler#on_start") do
|
61
58
|
request.env[APPSIGNAL_EVENT_HANDLER_ID] ||= id
|
@@ -90,6 +87,8 @@ module Appsignal
|
|
90
87
|
|
91
88
|
# @api private
|
92
89
|
def on_error(request, _response, error)
|
90
|
+
return unless Appsignal.active?
|
91
|
+
|
93
92
|
self.class.safe_execution("Appsignal::Rack::EventHandler#on_error") do
|
94
93
|
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
95
94
|
|
@@ -103,6 +102,7 @@ module Appsignal
|
|
103
102
|
|
104
103
|
# @api private
|
105
104
|
def on_finish(request, response)
|
105
|
+
return unless Appsignal.active?
|
106
106
|
return unless request_handler?(request.env[APPSIGNAL_EVENT_HANDLER_ID])
|
107
107
|
|
108
108
|
transaction = request.env[APPSIGNAL_TRANSACTION]
|
data/lib/appsignal/rack.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Appsignal
|
4
4
|
# @api private
|
5
5
|
module Rack
|
6
|
+
APPSIGNAL_TRANSACTION = "appsignal.transaction"
|
7
|
+
APPSIGNAL_EVENT_HANDLER_ID = "appsignal.event_handler_id"
|
8
|
+
APPSIGNAL_EVENT_HANDLER_HAS_ERROR = "appsignal.event_handler.error"
|
9
|
+
APPSIGNAL_RESPONSE_INSTRUMENTED = "appsignal.response_instrumentation_active"
|
10
|
+
RACK_AFTER_REPLY = "rack.after_reply"
|
11
|
+
|
6
12
|
class Utils
|
7
13
|
# Fetch the queue start time from the request environment.
|
8
14
|
#
|
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -22,8 +22,8 @@ module Appsignal
|
|
22
22
|
include Helpers::Instrumentation
|
23
23
|
include Helpers::Metrics
|
24
24
|
|
25
|
-
#
|
26
|
-
#
|
25
|
+
# The loaded AppSignal configuration.
|
26
|
+
# Returns the current AppSignal configuration.
|
27
27
|
#
|
28
28
|
# Can return `nil` if no configuration has been set or automatically loaded
|
29
29
|
# by an automatic integration or by calling {.start}.
|
@@ -31,12 +31,31 @@ module Appsignal
|
|
31
31
|
# @example
|
32
32
|
# Appsignal.config
|
33
33
|
#
|
34
|
-
# @example Setting the configuration
|
35
|
-
# Appsignal.config = Appsignal::Config.new(Dir.pwd, "production")
|
36
|
-
#
|
37
34
|
# @return [Config, nil]
|
35
|
+
# @see configure
|
36
|
+
# @see Config
|
37
|
+
attr_reader :config
|
38
|
+
|
39
|
+
# Set the AppSignal config.
|
40
|
+
#
|
41
|
+
# @deprecated Use {Appsignal.configure} instead.
|
42
|
+
# @param conf [Appsignal::Config]
|
43
|
+
# @return [void]
|
38
44
|
# @see Config
|
39
|
-
|
45
|
+
def config=(conf)
|
46
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
47
|
+
"Configuring AppSignal with `Appsignal.config=` is deprecated. " \
|
48
|
+
"Use `Appsignal.configure { |config| ... }` to configure AppSignal. " \
|
49
|
+
"https://docs.appsignal.com/ruby/configuration.html\n" \
|
50
|
+
"#{caller.first}"
|
51
|
+
@config = conf
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
def _config=(conf)
|
56
|
+
@config = conf
|
57
|
+
end
|
58
|
+
|
40
59
|
# Accessor for toggle if the AppSignal C-extension is loaded.
|
41
60
|
#
|
42
61
|
# Can be `nil` if extension has not been loaded yet. See
|
@@ -87,7 +106,9 @@ module Appsignal
|
|
87
106
|
# Appsignal.start
|
88
107
|
#
|
89
108
|
# @example with custom loaded configuration
|
90
|
-
# Appsignal.
|
109
|
+
# Appsignal.configure(:production) do |config|
|
110
|
+
# config.ignore_actions = ["My action"]
|
111
|
+
# end
|
91
112
|
# Appsignal.start
|
92
113
|
#
|
93
114
|
# @return [void]
|
@@ -109,11 +130,13 @@ module Appsignal
|
|
109
130
|
|
110
131
|
if config.valid?
|
111
132
|
if config.active?
|
133
|
+
@started = true
|
112
134
|
internal_logger.info "Starting AppSignal #{Appsignal::VERSION} " \
|
113
135
|
"(#{$PROGRAM_NAME}, Ruby #{RUBY_VERSION}, #{RUBY_PLATFORM})"
|
114
136
|
config.write_to_environment
|
115
137
|
Appsignal::Extension.start
|
116
138
|
Appsignal::Hooks.load_hooks
|
139
|
+
Appsignal::Loaders.start
|
117
140
|
|
118
141
|
if config[:enable_allocation_tracking] && !Appsignal::System.jruby?
|
119
142
|
Appsignal::Extension.install_allocation_event_hook
|
@@ -147,14 +170,102 @@ module Appsignal
|
|
147
170
|
# @since 1.0.0
|
148
171
|
def stop(called_by = nil)
|
149
172
|
if called_by
|
150
|
-
internal_logger.debug("Stopping
|
173
|
+
internal_logger.debug("Stopping AppSignal (#{called_by})")
|
151
174
|
else
|
152
|
-
internal_logger.debug("Stopping
|
175
|
+
internal_logger.debug("Stopping AppSignal")
|
153
176
|
end
|
154
177
|
Appsignal::Extension.stop
|
155
178
|
Appsignal::Probes.stop
|
156
179
|
end
|
157
180
|
|
181
|
+
# Configure the AppSignal Ruby gem using a DSL.
|
182
|
+
#
|
183
|
+
# Pass a block to the configure method to configure the Ruby gem.
|
184
|
+
#
|
185
|
+
# Each config option defined in our docs can be fetched, set and modified
|
186
|
+
# via a helper method in the given block.
|
187
|
+
#
|
188
|
+
# After AppSignal has started using {start}, the configuration can not be
|
189
|
+
# modified. Any calls to this helper will be ignored.
|
190
|
+
#
|
191
|
+
# This helper should not be used to configure multiple environments, like
|
192
|
+
# done in the YAML file. Configure the environment you want active when the
|
193
|
+
# application starts.
|
194
|
+
#
|
195
|
+
# @example Configure AppSignal for the application
|
196
|
+
# Appsignal.configure do |config|
|
197
|
+
# config.path = "/the/app/path"
|
198
|
+
# config.active = ENV["APP_ACTIVE"] == "true"
|
199
|
+
# config.push_api_key = File.read("appsignal_key.txt").chomp
|
200
|
+
# config.ignore_actions = ENDPOINTS.select { |e| e.public? }.map(&:name)
|
201
|
+
# config.request_headers << "MY_CUSTOM_HEADER"
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# @example Configure AppSignal for the application and select the environment
|
205
|
+
# Appsignal.configure(:production) do |config|
|
206
|
+
# config.active = true
|
207
|
+
# end
|
208
|
+
#
|
209
|
+
# @example Automatically detects the app environment
|
210
|
+
# # Tries to determine the app environment automatically from the
|
211
|
+
# # environment and the libraries it integrates with.
|
212
|
+
# ENV["RACK_ENV"] = "production"
|
213
|
+
#
|
214
|
+
# Appsignal.configure do |config|
|
215
|
+
# config.env # => "production"
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# @example Calling configure multiple times for different environments resets the configuration
|
219
|
+
# Appsignal.configure(:development) do |config|
|
220
|
+
# config.ignore_actions = ["My action"]
|
221
|
+
# end
|
222
|
+
#
|
223
|
+
# Appsignal.configure(:production) do |config|
|
224
|
+
# config.ignore_actions # => []
|
225
|
+
# end
|
226
|
+
#
|
227
|
+
# @example Load config without a block
|
228
|
+
# # This will require either ENV vars being set
|
229
|
+
# # or the config/appsignal.yml being present
|
230
|
+
# Appsignal.configure
|
231
|
+
# # Or for the environment given as an argument
|
232
|
+
# Appsignal.configure(:production)
|
233
|
+
#
|
234
|
+
# @yield [Config] Gives the {Config} instance to the block.
|
235
|
+
# @return [void]
|
236
|
+
# @see config
|
237
|
+
# @see Config
|
238
|
+
# @see https://docs.appsignal.com/ruby/configuration.html Configuration guide
|
239
|
+
# @see https://docs.appsignal.com/ruby/configuration/options.html Configuration options
|
240
|
+
def configure(env = nil)
|
241
|
+
if Appsignal.started?
|
242
|
+
Appsignal.internal_logger
|
243
|
+
.warn("AppSignal is already started. Ignoring `Appsignal.configure` call.")
|
244
|
+
return
|
245
|
+
end
|
246
|
+
|
247
|
+
if config && config.env == env.to_s
|
248
|
+
config
|
249
|
+
else
|
250
|
+
self._config = Appsignal::Config.new(
|
251
|
+
Dir.pwd,
|
252
|
+
env || ENV["APPSIGNAL_APP_ENV"] || ENV["RAILS_ENV"] || ENV.fetch("RACK_ENV", nil),
|
253
|
+
{},
|
254
|
+
Appsignal.internal_logger,
|
255
|
+
nil,
|
256
|
+
false
|
257
|
+
)
|
258
|
+
config.load_config
|
259
|
+
end
|
260
|
+
|
261
|
+
config_dsl = Appsignal::Config::ConfigDSL.new(config)
|
262
|
+
if block_given?
|
263
|
+
yield config_dsl
|
264
|
+
config.merge_dsl_options(config_dsl.dsl_options)
|
265
|
+
end
|
266
|
+
config.validate
|
267
|
+
end
|
268
|
+
|
158
269
|
def forked
|
159
270
|
return unless active?
|
160
271
|
|
@@ -163,6 +274,38 @@ module Appsignal
|
|
163
274
|
Appsignal::Extension.start
|
164
275
|
end
|
165
276
|
|
277
|
+
# Load an AppSignal integration.
|
278
|
+
#
|
279
|
+
# Load one of the supported integrations via our loader system.
|
280
|
+
# This will set config defaults and integratie with the library if
|
281
|
+
# AppSignal is active upon start.
|
282
|
+
#
|
283
|
+
# @example Load Sinatra integrations
|
284
|
+
# # First load the integration
|
285
|
+
# Appsignal.load(:sinatra)
|
286
|
+
# # Start AppSignal
|
287
|
+
# Appsignal.start
|
288
|
+
#
|
289
|
+
# @example Load Sinatra integrations and define custom config
|
290
|
+
# # First load the integration
|
291
|
+
# Appsignal.load(:sinatra)
|
292
|
+
#
|
293
|
+
# # Customize config
|
294
|
+
# Appsignal.configure do |config|
|
295
|
+
# config.ignore_actions = ["GET /ping"]
|
296
|
+
# end
|
297
|
+
#
|
298
|
+
#
|
299
|
+
# # Start AppSignal
|
300
|
+
# Appsignal.start
|
301
|
+
#
|
302
|
+
# @param integration_name [String, Symbol] Name of the integration to load.
|
303
|
+
# @return [void]
|
304
|
+
# @since 3.12.0
|
305
|
+
def load(integration_name)
|
306
|
+
Loaders.load(integration_name)
|
307
|
+
end
|
308
|
+
|
166
309
|
# @api private
|
167
310
|
def get_server_state(key)
|
168
311
|
Appsignal::Extension.get_server_state(key)
|
@@ -238,6 +381,16 @@ module Appsignal
|
|
238
381
|
!!extension_loaded
|
239
382
|
end
|
240
383
|
|
384
|
+
# Returns if {.start} has been called before with a valid config to start
|
385
|
+
# AppSignal.
|
386
|
+
#
|
387
|
+
# @return [Boolean]
|
388
|
+
# @see Extension
|
389
|
+
# @since 3.12.0
|
390
|
+
def started?
|
391
|
+
defined?(@started) ? @started : false
|
392
|
+
end
|
393
|
+
|
241
394
|
# Returns the active state of the AppSignal integration.
|
242
395
|
#
|
243
396
|
# Conditions apply for AppSignal to be marked as active:
|
@@ -314,6 +467,7 @@ module Appsignal
|
|
314
467
|
end
|
315
468
|
end
|
316
469
|
|
470
|
+
require "appsignal/loaders"
|
317
471
|
require "appsignal/environment"
|
318
472
|
require "appsignal/system"
|
319
473
|
require "appsignal/utils"
|
@@ -4,7 +4,7 @@ require "appsignal/cli/diagnose/paths"
|
|
4
4
|
|
5
5
|
describe Appsignal::CLI::Diagnose::Paths do
|
6
6
|
describe "#paths" do
|
7
|
-
before {
|
7
|
+
before { start_agent }
|
8
8
|
|
9
9
|
it "returns gem installation path as package_install_path" do
|
10
10
|
expect(described_class.new.paths[:package_install_path]).to eq(
|
@@ -67,7 +67,6 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
67
67
|
capture_diagnatics_report_request
|
68
68
|
end
|
69
69
|
before(:send_report => :no_cli_option) { options["no-send-report"] = nil }
|
70
|
-
after { Appsignal.config = nil }
|
71
70
|
|
72
71
|
def capture_diagnatics_report_request
|
73
72
|
stub_diagnostics_report_request.to_rack(DiagnosticsReportEndpoint)
|