appsignal 2.9.2.alpha.1 → 2.9.18.beta.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 +5 -5
- data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- data/.github/ISSUE_TEMPLATE/chore.md +14 -0
- data/.gitignore +1 -2
- data/.rubocop.yml +3 -0
- data/.travis.yml +25 -27
- data/CHANGELOG.md +632 -535
- data/README.md +8 -3
- data/Rakefile +118 -122
- data/SUPPORT.md +16 -0
- data/appsignal.gemspec +14 -4
- data/build_matrix.yml +16 -8
- data/ext/Rakefile +2 -3
- data/ext/agent.yml +40 -37
- data/ext/base.rb +37 -14
- data/ext/extconf.rb +3 -4
- data/gemfiles/capistrano2.gemfile +5 -0
- data/gemfiles/capistrano3.gemfile +5 -0
- data/gemfiles/grape.gemfile +5 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +5 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/que_beta.gemfile +10 -0
- data/gemfiles/rails-3.2.gemfile +5 -0
- data/gemfiles/rails-4.0.gemfile +5 -0
- data/gemfiles/rails-4.1.gemfile +5 -0
- data/gemfiles/rails-4.2.gemfile +5 -0
- data/gemfiles/rails-6.0.gemfile +1 -1
- data/gemfiles/resque.gemfile +5 -0
- data/lib/appsignal.rb +1 -4
- data/lib/appsignal/cli/demo.rb +5 -2
- data/lib/appsignal/cli/diagnose/utils.rb +2 -0
- data/lib/appsignal/cli/install.rb +34 -10
- data/lib/appsignal/cli/notify_of_deploy.rb +10 -0
- data/lib/appsignal/config.rb +5 -2
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +10 -8
- data/lib/appsignal/helpers/instrumentation.rb +18 -9
- data/lib/appsignal/helpers/metrics.rb +0 -1
- data/lib/appsignal/hooks.rb +3 -1
- data/lib/appsignal/hooks/active_support_notifications.rb +2 -5
- data/lib/appsignal/hooks/puma.rb +15 -13
- data/lib/appsignal/hooks/sequel.rb +1 -1
- data/lib/appsignal/hooks/sidekiq.rb +33 -8
- data/lib/appsignal/integrations/que.rb +9 -8
- data/lib/appsignal/minutely.rb +38 -19
- data/lib/appsignal/transaction.rb +5 -0
- data/lib/appsignal/utils/rails_helper.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/puma/plugin/appsignal.rb +26 -0
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +40 -0
- data/spec/lib/appsignal/cli/install_spec.rb +51 -7
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +10 -0
- data/spec/lib/appsignal/config_spec.rb +13 -8
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +38 -28
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +104 -25
- data/spec/lib/appsignal/hooks/puma_spec.rb +69 -39
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +65 -3
- data/spec/lib/appsignal/hooks_spec.rb +4 -0
- data/spec/lib/appsignal/minutely_spec.rb +150 -88
- data/spec/lib/appsignal/transaction_spec.rb +27 -4
- data/spec/lib/appsignal_spec.rb +62 -11
- data/spec/lib/puma/appsignal_spec.rb +91 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/application.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/appsignal.yml +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/development.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/production.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/test.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/log/.gitkeep +0 -0
- data/spec/support/helpers/config_helpers.rb +1 -1
- data/spec/support/helpers/wait_for_helper.rb +28 -0
- data/spec/support/mocks/mock_probe.rb +11 -0
- metadata +38 -30
- data/spec/support/fixtures/containers/cgroups/docker +0 -14
- data/spec/support/fixtures/containers/cgroups/docker_systemd +0 -8
- data/spec/support/fixtures/containers/cgroups/lxc +0 -10
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +0 -1
|
@@ -60,6 +60,8 @@ module Appsignal
|
|
|
60
60
|
# Terminology: Deploy marker
|
|
61
61
|
class NotifyOfDeploy
|
|
62
62
|
class << self
|
|
63
|
+
include Appsignal::Utils::DeprecationMessage
|
|
64
|
+
|
|
63
65
|
# @param options [Hash]
|
|
64
66
|
# @option options :environment [String] environment to load
|
|
65
67
|
# configuration for.
|
|
@@ -85,6 +87,14 @@ module Appsignal
|
|
|
85
87
|
},
|
|
86
88
|
config
|
|
87
89
|
).transmit
|
|
90
|
+
|
|
91
|
+
puts
|
|
92
|
+
message = "This command (appsignal notify_of_deploy) has been " \
|
|
93
|
+
"deprecated in favor of the `revision` config option. Please " \
|
|
94
|
+
"see our documentation for more information on the recommended " \
|
|
95
|
+
"method: " \
|
|
96
|
+
"https://docs.appsignal.com/application/markers/deploy-markers.html"
|
|
97
|
+
deprecation_message message, Appsignal.logger
|
|
88
98
|
end
|
|
89
99
|
|
|
90
100
|
private
|
data/lib/appsignal/config.rb
CHANGED
|
@@ -39,7 +39,8 @@ module Appsignal
|
|
|
39
39
|
:enable_minutely_probes => true,
|
|
40
40
|
:ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__),
|
|
41
41
|
:dns_servers => [],
|
|
42
|
-
:files_world_accessible => true
|
|
42
|
+
:files_world_accessible => true,
|
|
43
|
+
:transaction_debug_mode => false
|
|
43
44
|
}.freeze
|
|
44
45
|
|
|
45
46
|
ENV_TO_KEY_MAPPING = {
|
|
@@ -75,6 +76,7 @@ module Appsignal
|
|
|
75
76
|
"APPSIGNAL_DNS_SERVERS" => :dns_servers,
|
|
76
77
|
"APPSIGNAL_FILES_WORLD_ACCESSIBLE" => :files_world_accessible,
|
|
77
78
|
"APPSIGNAL_REQUEST_HEADERS" => :request_headers,
|
|
79
|
+
"APPSIGNAL_TRANSACTION_DEBUG_MODE" => :transaction_debug_mode,
|
|
78
80
|
"APP_REVISION" => :revision
|
|
79
81
|
}.freeze
|
|
80
82
|
|
|
@@ -219,6 +221,7 @@ module Appsignal
|
|
|
219
221
|
ENV["_APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
|
|
220
222
|
ENV["_APPSIGNAL_DNS_SERVERS"] = config_hash[:dns_servers].join(",")
|
|
221
223
|
ENV["_APPSIGNAL_FILES_WORLD_ACCESSIBLE"] = config_hash[:files_world_accessible].to_s
|
|
224
|
+
ENV["_APPSIGNAL_TRANSACTION_DEBUG_MODE"] = config_hash[:transaction_debug_mode].to_s
|
|
222
225
|
ENV["_APP_REVISION"] = config_hash[:revision].to_s
|
|
223
226
|
end
|
|
224
227
|
|
|
@@ -324,7 +327,7 @@ module Appsignal
|
|
|
324
327
|
APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION
|
|
325
328
|
APPSIGNAL_RUNNING_IN_CONTAINER APPSIGNAL_ENABLE_HOST_METRICS
|
|
326
329
|
APPSIGNAL_SEND_PARAMS APPSIGNAL_ENABLE_MINUTELY_PROBES
|
|
327
|
-
APPSIGNAL_FILES_WORLD_ACCESSIBLE].each do |var|
|
|
330
|
+
APPSIGNAL_FILES_WORLD_ACCESSIBLE APPSIGNAL_TRANSACTION_DEBUG_MODE].each do |var|
|
|
328
331
|
env_var = ENV[var]
|
|
329
332
|
next unless env_var
|
|
330
333
|
config[ENV_TO_KEY_MAPPING[var]] = env_var.casecmp("true").zero?
|
|
@@ -22,11 +22,13 @@ module Appsignal
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
if defined?(Rails)
|
|
26
|
+
Appsignal::EventFormatter.register(
|
|
27
|
+
"render_partial.action_view",
|
|
28
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
|
29
|
+
)
|
|
30
|
+
Appsignal::EventFormatter.register(
|
|
31
|
+
"render_template.action_view",
|
|
32
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
|
33
|
+
)
|
|
34
|
+
end
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module Helpers
|
|
5
|
-
# @api private
|
|
6
5
|
module Instrumentation # rubocop:disable Metrics/ModuleLength
|
|
7
6
|
# Creates an AppSignal transaction for the given block.
|
|
8
7
|
#
|
|
@@ -57,8 +56,9 @@ module Appsignal
|
|
|
57
56
|
# @return [Object] the value of the given block is returned.
|
|
58
57
|
# @since 0.10.0
|
|
59
58
|
def monitor_transaction(name, env = {})
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
# Always verify input, even when Appsignal is not active.
|
|
60
|
+
# This makes it more likely invalid arguments get flagged in test/dev
|
|
61
|
+
# environments.
|
|
62
62
|
if name.start_with?("perform_job".freeze)
|
|
63
63
|
namespace = Appsignal::Transaction::BACKGROUND_JOB
|
|
64
64
|
request = Appsignal::Transaction::GenericRequest.new(env)
|
|
@@ -66,9 +66,14 @@ module Appsignal
|
|
|
66
66
|
namespace = Appsignal::Transaction::HTTP_REQUEST
|
|
67
67
|
request = ::Rack::Request.new(env)
|
|
68
68
|
else
|
|
69
|
-
logger.error
|
|
70
|
-
|
|
69
|
+
logger.error "Unrecognized name '#{name}': names must start with " \
|
|
70
|
+
"either 'perform_job' (for jobs and tasks) or 'process_action' " \
|
|
71
|
+
"(for HTTP requests)"
|
|
72
|
+
return yield
|
|
71
73
|
end
|
|
74
|
+
|
|
75
|
+
return yield unless active?
|
|
76
|
+
|
|
72
77
|
transaction = Appsignal::Transaction.create(
|
|
73
78
|
SecureRandom.uuid,
|
|
74
79
|
namespace,
|
|
@@ -196,7 +201,8 @@ module Appsignal
|
|
|
196
201
|
)
|
|
197
202
|
return unless active?
|
|
198
203
|
unless error.is_a?(Exception)
|
|
199
|
-
logger.error
|
|
204
|
+
logger.error "Appsignal.send_error: Cannot send error. The given " \
|
|
205
|
+
"value is not an exception: #{error.inspect}"
|
|
200
206
|
return
|
|
201
207
|
end
|
|
202
208
|
transaction = Appsignal::Transaction.new(
|
|
@@ -251,9 +257,12 @@ module Appsignal
|
|
|
251
257
|
# Exception handling guide
|
|
252
258
|
# @since 0.6.6
|
|
253
259
|
def set_error(exception, tags = nil, namespace = nil)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
exception.
|
|
260
|
+
unless exception.is_a?(Exception)
|
|
261
|
+
logger.error "Appsignal.set_error: Cannot set error. The given " \
|
|
262
|
+
"value is not an exception: #{exception.inspect}"
|
|
263
|
+
return
|
|
264
|
+
end
|
|
265
|
+
return if !active? || Appsignal::Transaction.current.nil?
|
|
257
266
|
transaction = Appsignal::Transaction.current
|
|
258
267
|
transaction.set_error(exception)
|
|
259
268
|
transaction.set_tags(tags) if tags
|
data/lib/appsignal/hooks.rb
CHANGED
|
@@ -37,7 +37,9 @@ module Appsignal
|
|
|
37
37
|
install
|
|
38
38
|
@installed = true
|
|
39
39
|
rescue => ex
|
|
40
|
-
Appsignal.logger
|
|
40
|
+
logger = Appsignal.logger
|
|
41
|
+
logger.error("Error while installing #{name} hook: #{ex}")
|
|
42
|
+
logger.debug ex.backtrace.join("\n")
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -30,16 +30,13 @@ module Appsignal
|
|
|
30
30
|
# Events that start with a bang are internal to Rails
|
|
31
31
|
instrument_this = name[0] != BANG
|
|
32
32
|
|
|
33
|
-
if instrument_this
|
|
34
|
-
transaction = Appsignal::Transaction.current
|
|
35
|
-
transaction.start_event
|
|
36
|
-
end
|
|
33
|
+
Appsignal::Transaction.current.start_event if instrument_this
|
|
37
34
|
|
|
38
35
|
instrument_without_appsignal(name, payload, &block)
|
|
39
36
|
ensure
|
|
40
37
|
if instrument_this
|
|
41
38
|
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
|
|
42
|
-
|
|
39
|
+
Appsignal::Transaction.current.finish_event(
|
|
43
40
|
name.to_s,
|
|
44
41
|
title,
|
|
45
42
|
body,
|
data/lib/appsignal/hooks/puma.rb
CHANGED
|
@@ -11,22 +11,24 @@ module Appsignal
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def install
|
|
14
|
-
if ::Puma.respond_to?(:stats)
|
|
14
|
+
if ::Puma.respond_to?(:stats) && !defined?(APPSIGNAL_PUMA_PLUGIN_LOADED)
|
|
15
|
+
# Only install the minutely probe if a user isn't using our Puma
|
|
16
|
+
# plugin, which lives in `lib/puma/appsignal.rb`. This plugin defines
|
|
17
|
+
# the {APPSIGNAL_PUMA_PLUGIN_LOADED} constant.
|
|
18
|
+
#
|
|
19
|
+
# We prefer people use the AppSignal Puma plugin. This fallback is
|
|
20
|
+
# only there when users relied on our *magic* integration.
|
|
21
|
+
#
|
|
22
|
+
# Using the Puma plugin, the minutely probe thread will still run in
|
|
23
|
+
# Puma workers, for other non-Puma probes, but the Puma probe only
|
|
24
|
+
# runs in the Puma main process.
|
|
25
|
+
# For more information:
|
|
26
|
+
# https://docs.appsignal.com/ruby/integrations/puma.html
|
|
15
27
|
Appsignal::Minutely.probes.register :puma, PumaProbe
|
|
16
28
|
end
|
|
17
29
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
::Puma.cli_config.options[:before_worker_boot] << proc do |_id|
|
|
21
|
-
Appsignal.forked
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
::Puma.cli_config.options[:before_worker_shutdown] ||= []
|
|
25
|
-
::Puma.cli_config.options[:before_worker_shutdown] << proc do |_id|
|
|
26
|
-
Appsignal.stop("puma before_worker_shutdown")
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
+
return unless defined?(::Puma::Cluster)
|
|
31
|
+
# For clustered mode with multiple workers
|
|
30
32
|
::Puma::Cluster.class_eval do
|
|
31
33
|
alias stop_workers_without_appsignal stop_workers
|
|
32
34
|
|
|
@@ -42,7 +42,7 @@ module Appsignal
|
|
|
42
42
|
|
|
43
43
|
def install
|
|
44
44
|
# Register the extension...
|
|
45
|
-
if ::Sequel::MAJOR >= 4 && ::Sequel::MINOR >= 35
|
|
45
|
+
if (::Sequel::MAJOR >= 4 && ::Sequel::MINOR >= 35) || ::Sequel::MAJOR >= 5
|
|
46
46
|
::Sequel::Database.register_extension(
|
|
47
47
|
:appsignal_integration,
|
|
48
48
|
Appsignal::Hooks::SequelLogConnectionExtension
|
|
@@ -25,20 +25,42 @@ module Appsignal
|
|
|
25
25
|
class SidekiqProbe
|
|
26
26
|
attr_reader :config
|
|
27
27
|
|
|
28
|
+
def self.dependencies_present?
|
|
29
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
def initialize(config = {})
|
|
29
33
|
@config = config
|
|
30
34
|
@cache = {}
|
|
35
|
+
config_string = " with config: #{config}" unless config.empty?
|
|
36
|
+
Appsignal.logger.debug("Initializing Sidekiq probe#{config_string}")
|
|
31
37
|
require "sidekiq/api"
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
def call
|
|
35
|
-
|
|
41
|
+
track_redis_info
|
|
42
|
+
track_stats
|
|
43
|
+
track_queues
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
attr_reader :cache
|
|
49
|
+
|
|
50
|
+
def track_redis_info
|
|
51
|
+
return unless ::Sidekiq.respond_to?(:redis_info)
|
|
36
52
|
redis_info = ::Sidekiq.redis_info
|
|
37
|
-
|
|
38
|
-
gauge "process_count", stats.processes_size
|
|
53
|
+
|
|
39
54
|
gauge "connection_count", redis_info.fetch("connected_clients")
|
|
40
55
|
gauge "memory_usage", redis_info.fetch("used_memory")
|
|
41
56
|
gauge "memory_usage_rss", redis_info.fetch("used_memory_rss")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def track_stats
|
|
60
|
+
stats = ::Sidekiq::Stats.new
|
|
61
|
+
|
|
62
|
+
gauge "worker_count", stats.workers_size
|
|
63
|
+
gauge "process_count", stats.processes_size
|
|
42
64
|
gauge_delta :jobs_processed, "job_count", stats.processed,
|
|
43
65
|
:status => :processed
|
|
44
66
|
gauge_delta :jobs_failed, "job_count", stats.failed, :status => :failed
|
|
@@ -46,17 +68,16 @@ module Appsignal
|
|
|
46
68
|
gauge_delta :jobs_dead, "job_count", stats.dead_size, :status => :died
|
|
47
69
|
gauge "job_count", stats.scheduled_size, :status => :scheduled
|
|
48
70
|
gauge "job_count", stats.enqueued, :status => :enqueued
|
|
71
|
+
end
|
|
49
72
|
|
|
73
|
+
def track_queues
|
|
50
74
|
::Sidekiq::Queue.all.each do |queue|
|
|
51
75
|
gauge "queue_length", queue.size, :queue => queue.name
|
|
52
|
-
|
|
76
|
+
# Convert latency from seconds to milliseconds
|
|
77
|
+
gauge "queue_latency", queue.latency * 1_000.0, :queue => queue.name
|
|
53
78
|
end
|
|
54
79
|
end
|
|
55
80
|
|
|
56
|
-
private
|
|
57
|
-
|
|
58
|
-
attr_reader :cache
|
|
59
|
-
|
|
60
81
|
# Track a gauge metric with the `sidekiq_` prefix
|
|
61
82
|
def gauge(key, value, tags = {})
|
|
62
83
|
tags[:hostname] = hostname if hostname
|
|
@@ -86,11 +107,15 @@ module Appsignal
|
|
|
86
107
|
return @hostname if defined?(@hostname)
|
|
87
108
|
if config.key?(:hostname)
|
|
88
109
|
@hostname = config[:hostname]
|
|
110
|
+
Appsignal.logger.debug "Sidekiq probe: Using hostname config " \
|
|
111
|
+
"option #{@hostname.inspect} as hostname"
|
|
89
112
|
return @hostname
|
|
90
113
|
end
|
|
91
114
|
|
|
92
115
|
host = nil
|
|
93
116
|
::Sidekiq.redis { |c| host = c.connection[:host] }
|
|
117
|
+
Appsignal.logger.debug "Sidekiq probe: Using Redis server hostname " \
|
|
118
|
+
"#{host.inspect} as hostname"
|
|
94
119
|
@hostname = host
|
|
95
120
|
end
|
|
96
121
|
end
|
|
@@ -5,16 +5,17 @@ module Appsignal
|
|
|
5
5
|
module QuePlugin
|
|
6
6
|
def self.included(base)
|
|
7
7
|
base.class_eval do
|
|
8
|
-
def _run_with_appsignal
|
|
8
|
+
def _run_with_appsignal(*)
|
|
9
|
+
local_attrs = respond_to?(:que_attrs) ? que_attrs : attrs
|
|
9
10
|
env = {
|
|
10
11
|
:metadata => {
|
|
11
|
-
:id =>
|
|
12
|
-
:queue =>
|
|
13
|
-
:run_at =>
|
|
14
|
-
:priority =>
|
|
15
|
-
:attempts =>
|
|
12
|
+
:id => local_attrs[:job_id] || local_attrs[:id],
|
|
13
|
+
:queue => local_attrs[:queue],
|
|
14
|
+
:run_at => local_attrs[:run_at].to_s,
|
|
15
|
+
:priority => local_attrs[:priority],
|
|
16
|
+
:attempts => local_attrs[:error_count].to_i
|
|
16
17
|
},
|
|
17
|
-
:params =>
|
|
18
|
+
:params => local_attrs[:args]
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
request = Appsignal::Transaction::GenericRequest.new(env)
|
|
@@ -31,7 +32,7 @@ module Appsignal
|
|
|
31
32
|
transaction.set_error(error)
|
|
32
33
|
raise error
|
|
33
34
|
ensure
|
|
34
|
-
transaction.set_action "#{
|
|
35
|
+
transaction.set_action "#{local_attrs[:job_class]}#run"
|
|
35
36
|
Appsignal::Transaction.complete_current!
|
|
36
37
|
end
|
|
37
38
|
end
|
data/lib/appsignal/minutely.rb
CHANGED
|
@@ -135,20 +135,22 @@ module Appsignal
|
|
|
135
135
|
# @api private
|
|
136
136
|
def start
|
|
137
137
|
stop
|
|
138
|
-
initialize_probes
|
|
139
138
|
@@thread = Thread.new do
|
|
139
|
+
sleep initial_wait_time
|
|
140
|
+
initialize_probes
|
|
140
141
|
loop do
|
|
141
142
|
logger = Appsignal.logger
|
|
142
|
-
logger.debug("Gathering minutely metrics with #{
|
|
143
|
+
logger.debug("Gathering minutely metrics with #{probe_instances.count} probes")
|
|
143
144
|
probe_instances.each do |name, probe|
|
|
144
145
|
begin
|
|
145
146
|
logger.debug("Gathering minutely metrics with '#{name}' probe")
|
|
146
147
|
probe.call
|
|
147
148
|
rescue => ex
|
|
148
|
-
logger.error
|
|
149
|
+
logger.error "Error in minutely probe '#{name}': #{ex}"
|
|
150
|
+
logger.debug ex.backtrace.join("\n")
|
|
149
151
|
end
|
|
150
152
|
end
|
|
151
|
-
sleep
|
|
153
|
+
sleep wait_time
|
|
152
154
|
end
|
|
153
155
|
end
|
|
154
156
|
end
|
|
@@ -164,30 +166,47 @@ module Appsignal
|
|
|
164
166
|
60 - Time.now.sec
|
|
165
167
|
end
|
|
166
168
|
|
|
167
|
-
# @api private
|
|
168
|
-
def register_garbage_collection_probe
|
|
169
|
-
probes.register :garbage_collection, GCProbe.new
|
|
170
|
-
end
|
|
171
|
-
|
|
172
169
|
private
|
|
173
170
|
|
|
171
|
+
def initial_wait_time
|
|
172
|
+
remaining_seconds = 60 - Time.now.sec
|
|
173
|
+
return remaining_seconds if remaining_seconds > 30
|
|
174
|
+
remaining_seconds + 60
|
|
175
|
+
end
|
|
176
|
+
|
|
174
177
|
def initialize_probes
|
|
175
178
|
probes.each do |name, probe|
|
|
176
|
-
|
|
177
|
-
probe_instances[name] = instance
|
|
179
|
+
initialize_probe(name, probe)
|
|
178
180
|
end
|
|
179
181
|
end
|
|
180
182
|
|
|
181
|
-
def
|
|
182
|
-
|
|
183
|
+
def initialize_probe(name, probe)
|
|
184
|
+
if probe.respond_to? :new
|
|
185
|
+
instance = probe.new
|
|
186
|
+
klass = probe
|
|
187
|
+
else
|
|
188
|
+
instance = probe
|
|
189
|
+
klass = instance.class
|
|
190
|
+
end
|
|
191
|
+
unless dependencies_present?(klass)
|
|
192
|
+
Appsignal.logger.debug "Skipping '#{name}' probe, " \
|
|
193
|
+
"#{klass}.dependency_present? returned falsy"
|
|
194
|
+
return
|
|
195
|
+
end
|
|
196
|
+
probe_instances[name] = instance
|
|
197
|
+
rescue => error
|
|
198
|
+
logger = Appsignal.logger
|
|
199
|
+
logger.error "Error while initializing minutely probe '#{name}': #{error}"
|
|
200
|
+
logger.debug error.backtrace.join("\n")
|
|
183
201
|
end
|
|
184
|
-
end
|
|
185
202
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
203
|
+
def dependencies_present?(probe)
|
|
204
|
+
return true unless probe.respond_to? :dependencies_present?
|
|
205
|
+
probe.dependencies_present?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def probe_instances
|
|
209
|
+
@@probe_instances ||= {}
|
|
191
210
|
end
|
|
192
211
|
end
|
|
193
212
|
end
|
|
@@ -264,6 +264,11 @@ module Appsignal
|
|
|
264
264
|
end
|
|
265
265
|
|
|
266
266
|
def set_error(error)
|
|
267
|
+
unless error.is_a?(Exception)
|
|
268
|
+
Appsignal.logger.error "Appsignal::Transaction#set_error: Cannot set error. " \
|
|
269
|
+
"The given value is not an exception: #{error.inspect}"
|
|
270
|
+
return
|
|
271
|
+
end
|
|
267
272
|
return unless error
|
|
268
273
|
return unless Appsignal.active?
|
|
269
274
|
|