appsignal 2.5.0.alpha.1-java
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 +7 -0
- data/.gitignore +33 -0
- data/.rspec +4 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +124 -0
- data/.travis.yml +72 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +639 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +264 -0
- data/Rakefile +214 -0
- data/appsignal.gemspec +42 -0
- data/benchmark.rake +77 -0
- data/bin/appsignal +13 -0
- data/ext/Rakefile +27 -0
- data/ext/agent.yml +64 -0
- data/ext/appsignal_extension.c +692 -0
- data/ext/base.rb +79 -0
- data/ext/extconf.rb +35 -0
- data/gemfiles/capistrano2.gemfile +7 -0
- data/gemfiles/capistrano3.gemfile +7 -0
- data/gemfiles/grape.gemfile +7 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +7 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/rails-3.2.gemfile +6 -0
- data/gemfiles/rails-4.0.gemfile +6 -0
- data/gemfiles/rails-4.1.gemfile +6 -0
- data/gemfiles/rails-4.2.gemfile +10 -0
- data/gemfiles/rails-5.0.gemfile +5 -0
- data/gemfiles/rails-5.1.gemfile +5 -0
- data/gemfiles/resque.gemfile +12 -0
- data/gemfiles/sequel-435.gemfile +11 -0
- data/gemfiles/sequel.gemfile +11 -0
- data/gemfiles/sinatra.gemfile +6 -0
- data/gemfiles/webmachine.gemfile +5 -0
- data/lib/appsignal.rb +804 -0
- data/lib/appsignal/auth_check.rb +65 -0
- data/lib/appsignal/capistrano.rb +10 -0
- data/lib/appsignal/cli.rb +108 -0
- data/lib/appsignal/cli/demo.rb +63 -0
- data/lib/appsignal/cli/diagnose.rb +500 -0
- data/lib/appsignal/cli/helpers.rb +72 -0
- data/lib/appsignal/cli/install.rb +277 -0
- data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
- data/lib/appsignal/config.rb +287 -0
- data/lib/appsignal/demo.rb +107 -0
- data/lib/appsignal/event_formatter.rb +74 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
- data/lib/appsignal/extension.rb +63 -0
- data/lib/appsignal/extension/jruby.rb +460 -0
- data/lib/appsignal/garbage_collection_profiler.rb +48 -0
- data/lib/appsignal/hooks.rb +105 -0
- data/lib/appsignal/hooks/action_cable.rb +113 -0
- data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
- data/lib/appsignal/hooks/celluloid.rb +30 -0
- data/lib/appsignal/hooks/data_mapper.rb +18 -0
- data/lib/appsignal/hooks/delayed_job.rb +19 -0
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
- data/lib/appsignal/hooks/net_http.rb +29 -0
- data/lib/appsignal/hooks/passenger.rb +22 -0
- data/lib/appsignal/hooks/puma.rb +35 -0
- data/lib/appsignal/hooks/que.rb +21 -0
- data/lib/appsignal/hooks/rake.rb +39 -0
- data/lib/appsignal/hooks/redis.rb +30 -0
- data/lib/appsignal/hooks/sequel.rb +60 -0
- data/lib/appsignal/hooks/shoryuken.rb +43 -0
- data/lib/appsignal/hooks/sidekiq.rb +144 -0
- data/lib/appsignal/hooks/unicorn.rb +40 -0
- data/lib/appsignal/hooks/webmachine.rb +23 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
- data/lib/appsignal/integrations/data_mapper.rb +33 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
- data/lib/appsignal/integrations/grape.rb +53 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
- data/lib/appsignal/integrations/object.rb +35 -0
- data/lib/appsignal/integrations/padrino.rb +84 -0
- data/lib/appsignal/integrations/que.rb +43 -0
- data/lib/appsignal/integrations/railtie.rb +41 -0
- data/lib/appsignal/integrations/rake.rb +2 -0
- data/lib/appsignal/integrations/resque.rb +20 -0
- data/lib/appsignal/integrations/resque_active_job.rb +30 -0
- data/lib/appsignal/integrations/sinatra.rb +17 -0
- data/lib/appsignal/integrations/webmachine.rb +38 -0
- data/lib/appsignal/js_exception_transaction.rb +54 -0
- data/lib/appsignal/marker.rb +63 -0
- data/lib/appsignal/minutely.rb +42 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
- data/lib/appsignal/rack/streaming_listener.rb +73 -0
- data/lib/appsignal/system.rb +81 -0
- data/lib/appsignal/transaction.rb +498 -0
- data/lib/appsignal/transmitter.rb +107 -0
- data/lib/appsignal/utils.rb +127 -0
- data/lib/appsignal/utils/params_sanitizer.rb +59 -0
- data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
- data/lib/appsignal/version.rb +3 -0
- data/lib/sequel/extensions/appsignal_integration.rb +3 -0
- data/resources/appsignal.yml.erb +39 -0
- data/resources/cacert.pem +3866 -0
- data/spec/.rubocop.yml +7 -0
- data/spec/lib/appsignal/auth_check_spec.rb +80 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
- data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
- data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
- data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
- data/spec/lib/appsignal/cli/install_spec.rb +632 -0
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
- data/spec/lib/appsignal/cli_spec.rb +56 -0
- data/spec/lib/appsignal/config_spec.rb +637 -0
- data/spec/lib/appsignal/demo_spec.rb +87 -0
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
- data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
- data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
- data/spec/lib/appsignal/extension_spec.rb +137 -0
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
- data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
- data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
- data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
- data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
- data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
- data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
- data/spec/lib/appsignal/hooks_spec.rb +195 -0
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
- data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
- data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
- data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
- data/spec/lib/appsignal/marker_spec.rb +51 -0
- data/spec/lib/appsignal/minutely_spec.rb +50 -0
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
- data/spec/lib/appsignal/system_spec.rb +131 -0
- data/spec/lib/appsignal/transaction_spec.rb +1146 -0
- data/spec/lib/appsignal/transmitter_spec.rb +152 -0
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
- data/spec/lib/appsignal/utils_spec.rb +150 -0
- data/spec/lib/appsignal_spec.rb +1049 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/support/fixtures/containers/cgroups/docker +14 -0
- data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
- data/spec/support/fixtures/containers/cgroups/lxc +10 -0
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +1 -0
- data/spec/support/fixtures/generated_config.yml +24 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/helpers/api_request_helper.rb +19 -0
- data/spec/support/helpers/cli_helpers.rb +26 -0
- data/spec/support/helpers/config_helpers.rb +21 -0
- data/spec/support/helpers/dependency_helper.rb +73 -0
- data/spec/support/helpers/directory_helper.rb +27 -0
- data/spec/support/helpers/env_helpers.rb +33 -0
- data/spec/support/helpers/example_exception.rb +13 -0
- data/spec/support/helpers/example_standard_error.rb +13 -0
- data/spec/support/helpers/log_helpers.rb +22 -0
- data/spec/support/helpers/std_streams_helper.rb +66 -0
- data/spec/support/helpers/system_helpers.rb +8 -0
- data/spec/support/helpers/time_helpers.rb +11 -0
- data/spec/support/helpers/transaction_helpers.rb +37 -0
- data/spec/support/matchers/contains_log.rb +7 -0
- data/spec/support/mocks/fake_gc_profiler.rb +19 -0
- data/spec/support/mocks/mock_extension.rb +6 -0
- data/spec/support/project_fixture/config/application.rb +0 -0
- data/spec/support/project_fixture/config/appsignal.yml +32 -0
- data/spec/support/project_fixture/config/environments/development.rb +0 -0
- data/spec/support/project_fixture/config/environments/production.rb +0 -0
- data/spec/support/project_fixture/config/environments/test.rb +0 -0
- data/spec/support/project_fixture/log/.gitkeep +0 -0
- data/spec/support/rails/my_app.rb +6 -0
- data/spec/support/shared_examples/instrument.rb +43 -0
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +483 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
# @todo Move to sub-namespace
|
|
3
|
+
# @api private
|
|
4
|
+
class Capistrano
|
|
5
|
+
def self.tasks(config)
|
|
6
|
+
config.load do # rubocop:disable Metrics/BlockLength
|
|
7
|
+
after "deploy", "appsignal:deploy"
|
|
8
|
+
after "deploy:migrations", "appsignal:deploy"
|
|
9
|
+
|
|
10
|
+
namespace :appsignal do
|
|
11
|
+
task :deploy do
|
|
12
|
+
env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
|
|
13
|
+
user = fetch(:appsignal_user, ENV["USER"] || ENV["USERNAME"])
|
|
14
|
+
revision = fetch(:appsignal_revision, fetch(:current_revision))
|
|
15
|
+
|
|
16
|
+
appsignal_config = Appsignal::Config.new(
|
|
17
|
+
ENV["PWD"],
|
|
18
|
+
env,
|
|
19
|
+
{},
|
|
20
|
+
Logger.new(StringIO.new)
|
|
21
|
+
).tap do |c|
|
|
22
|
+
fetch(:appsignal_config, {}).each do |key, value|
|
|
23
|
+
c[key] = value
|
|
24
|
+
end
|
|
25
|
+
c.validate
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if appsignal_config && appsignal_config.active?
|
|
29
|
+
marker_data = {
|
|
30
|
+
:revision => revision,
|
|
31
|
+
:user => user
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
marker = Marker.new(marker_data, appsignal_config)
|
|
35
|
+
if config.dry_run
|
|
36
|
+
puts "Dry run: AppSignal deploy marker not actually sent."
|
|
37
|
+
else
|
|
38
|
+
marker.transmit
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
puts "Not notifying of deploy, config is not active for environment: #{env}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if ::Capistrano::Configuration.instance
|
|
51
|
+
Appsignal::Capistrano.tasks(::Capistrano::Configuration.instance)
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
module DataMapperLogListener
|
|
4
|
+
SQL_CLASSES = [
|
|
5
|
+
"DataObjects::SqlServer::Connection",
|
|
6
|
+
"DataObjects::Sqlite3::Connection",
|
|
7
|
+
"DataObjects::Mysql::Connection",
|
|
8
|
+
"DataObjects::Postgres::Connection"
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
def log(message)
|
|
12
|
+
# If scheme is SQL-like, try to sanitize it, otherwise clear the body
|
|
13
|
+
if SQL_CLASSES.include?(self.class.to_s)
|
|
14
|
+
body_content = message.query
|
|
15
|
+
body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT
|
|
16
|
+
else
|
|
17
|
+
body_content = ""
|
|
18
|
+
body_format = Appsignal::EventFormatter::DEFAULT
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Record event
|
|
22
|
+
Appsignal::Transaction.current.record_event(
|
|
23
|
+
"query.data_mapper",
|
|
24
|
+
"DataMapper Query",
|
|
25
|
+
body_content,
|
|
26
|
+
message.duration,
|
|
27
|
+
body_format
|
|
28
|
+
)
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class DelayedJobPlugin < ::Delayed::Plugin
|
|
5
|
+
extend Appsignal::Hooks::Helpers
|
|
6
|
+
|
|
7
|
+
callbacks do |lifecycle|
|
|
8
|
+
lifecycle.around(:invoke_job) do |job, &block|
|
|
9
|
+
invoke_with_instrumentation(job, block)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
lifecycle.after(:execute) do |_execute|
|
|
13
|
+
Appsignal.stop("delayed job")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.invoke_with_instrumentation(job, block)
|
|
18
|
+
payload = job.payload_object
|
|
19
|
+
|
|
20
|
+
if payload.respond_to? :job_data
|
|
21
|
+
# ActiveJob
|
|
22
|
+
job_data = payload.job_data
|
|
23
|
+
args = job_data.fetch("arguments", {})
|
|
24
|
+
class_name = job_data["job_class"]
|
|
25
|
+
method_name = "perform"
|
|
26
|
+
else
|
|
27
|
+
# Delayed Job
|
|
28
|
+
args = extract_value(job.payload_object, :args, {})
|
|
29
|
+
class_and_method_name = extract_value(job.payload_object, :appsignal_name, job.name)
|
|
30
|
+
class_name, method_name = class_and_method_name.split("#")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
params = Appsignal::Utils::ParamsSanitizer.sanitize args,
|
|
34
|
+
:filter_parameters => Appsignal.config[:filter_parameters]
|
|
35
|
+
|
|
36
|
+
Appsignal.monitor_transaction(
|
|
37
|
+
"perform_job.delayed_job",
|
|
38
|
+
:class => class_name,
|
|
39
|
+
:method => method_name,
|
|
40
|
+
:metadata => {
|
|
41
|
+
:id => extract_value(job, :id, nil, true),
|
|
42
|
+
:queue => extract_value(job, :queue),
|
|
43
|
+
:priority => extract_value(job, :priority, 0),
|
|
44
|
+
:attempts => extract_value(job, :attempts, 0)
|
|
45
|
+
},
|
|
46
|
+
:params => params,
|
|
47
|
+
:queue_start => extract_value(job, :run_at)
|
|
48
|
+
) do
|
|
49
|
+
block.call(job)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
# @todo Move to sub-namespace
|
|
3
|
+
# @api private
|
|
4
|
+
module Grape
|
|
5
|
+
class Middleware < ::Grape::Middleware::Base
|
|
6
|
+
def call(env)
|
|
7
|
+
if Appsignal.active?
|
|
8
|
+
call_with_appsignal_monitoring(env)
|
|
9
|
+
else
|
|
10
|
+
app.call(env)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call_with_appsignal_monitoring(env)
|
|
15
|
+
request = ::Rack::Request.new(env)
|
|
16
|
+
transaction = Appsignal::Transaction.create(
|
|
17
|
+
SecureRandom.uuid,
|
|
18
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
|
19
|
+
request
|
|
20
|
+
)
|
|
21
|
+
begin
|
|
22
|
+
app.call(env)
|
|
23
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
24
|
+
transaction.set_error(error)
|
|
25
|
+
raise error
|
|
26
|
+
ensure
|
|
27
|
+
request_method = request.request_method.to_s.upcase
|
|
28
|
+
path = request.path # Path without namespaces
|
|
29
|
+
endpoint = env["api.endpoint"]
|
|
30
|
+
|
|
31
|
+
if endpoint && endpoint.options
|
|
32
|
+
options = endpoint.options
|
|
33
|
+
request_method = options[:method].first.to_s.upcase
|
|
34
|
+
klass = options[:for]
|
|
35
|
+
namespace = endpoint.namespace
|
|
36
|
+
namespace = "" if namespace == "/"
|
|
37
|
+
|
|
38
|
+
path = options[:path].first.to_s
|
|
39
|
+
path = "/#{path}" if path[0] != "/"
|
|
40
|
+
path = "#{namespace}#{path}"
|
|
41
|
+
|
|
42
|
+
transaction.set_action_if_nil("#{request_method}::#{klass}##{path}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
transaction.set_http_or_background_queue_start
|
|
46
|
+
transaction.set_metadata("path", path)
|
|
47
|
+
transaction.set_metadata("method", request_method)
|
|
48
|
+
Appsignal::Transaction.complete_current!
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
class Hooks
|
|
3
|
+
# @api private
|
|
4
|
+
class MongoMonitorSubscriber
|
|
5
|
+
# Called by Mongo::Monitor when query starts
|
|
6
|
+
def started(event)
|
|
7
|
+
transaction = Appsignal::Transaction.current
|
|
8
|
+
return if transaction.nil_transaction?
|
|
9
|
+
return if transaction.paused?
|
|
10
|
+
|
|
11
|
+
# Format the command
|
|
12
|
+
command = Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter
|
|
13
|
+
.format(event.command_name, event.command)
|
|
14
|
+
|
|
15
|
+
# Store the query on the transaction, we need it when the event finishes
|
|
16
|
+
store = transaction.store("mongo_driver")
|
|
17
|
+
store[event.request_id] = command
|
|
18
|
+
|
|
19
|
+
# Start this event
|
|
20
|
+
transaction.start_event
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Called by Mongo::Monitor when query succeeds
|
|
24
|
+
def succeeded(event)
|
|
25
|
+
# Finish the event as succeeded
|
|
26
|
+
finish("SUCCEEDED", event)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Called by Mongo::Monitor when query fails
|
|
30
|
+
def failed(event)
|
|
31
|
+
# Finish the event as failed
|
|
32
|
+
finish("FAILED", event)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Finishes the event in the AppSignal extension
|
|
36
|
+
def finish(result, event)
|
|
37
|
+
transaction = Appsignal::Transaction.current
|
|
38
|
+
return if transaction.nil_transaction?
|
|
39
|
+
return if transaction.paused?
|
|
40
|
+
|
|
41
|
+
# Get the query from the transaction store
|
|
42
|
+
store = transaction.store("mongo_driver")
|
|
43
|
+
command = store.delete(event.request_id) || {}
|
|
44
|
+
|
|
45
|
+
# Finish the event in the extension.
|
|
46
|
+
transaction.finish_event(
|
|
47
|
+
"query.mongodb",
|
|
48
|
+
"#{event.command_name} | #{event.database_name} | #{result}",
|
|
49
|
+
Appsignal::Utils.data_generate(command),
|
|
50
|
+
Appsignal::EventFormatter::DEFAULT
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
def self.appsignal_instrument_class_method(method_name, options = {})
|
|
3
|
+
singleton_class.send \
|
|
4
|
+
:alias_method, "appsignal_uninstrumented_#{method_name}", method_name
|
|
5
|
+
singleton_class.send(:define_method, method_name) do |*args, &block|
|
|
6
|
+
name = options.fetch(:name) do
|
|
7
|
+
"#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
|
|
8
|
+
end
|
|
9
|
+
Appsignal.instrument name do
|
|
10
|
+
send "appsignal_uninstrumented_#{method_name}", *args, &block
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.appsignal_instrument_method(method_name, options = {})
|
|
16
|
+
alias_method "appsignal_uninstrumented_#{method_name}", method_name
|
|
17
|
+
define_method method_name do |*args, &block|
|
|
18
|
+
name = options.fetch(:name) do
|
|
19
|
+
"#{method_name}.#{appsignal_reverse_class_name}.other"
|
|
20
|
+
end
|
|
21
|
+
Appsignal.instrument name do
|
|
22
|
+
send "appsignal_uninstrumented_#{method_name}", *args, &block
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.appsignal_reverse_class_name
|
|
28
|
+
return "AnonymousClass" unless name
|
|
29
|
+
name.split("::").reverse.join(".")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def appsignal_reverse_class_name
|
|
33
|
+
self.class.appsignal_reverse_class_name
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require "appsignal"
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
module Integrations
|
|
5
|
+
# @api private
|
|
6
|
+
module PadrinoPlugin
|
|
7
|
+
def self.init
|
|
8
|
+
Appsignal.logger.info("Loading Padrino (#{Padrino::VERSION}) integration")
|
|
9
|
+
|
|
10
|
+
root = Padrino.mounted_root
|
|
11
|
+
Appsignal.config = Appsignal::Config.new(root, Padrino.env)
|
|
12
|
+
|
|
13
|
+
Appsignal.start_logger
|
|
14
|
+
Appsignal.start
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module Padrino::Routing::InstanceMethods
|
|
21
|
+
alias route_without_appsignal route!
|
|
22
|
+
|
|
23
|
+
def route!(base = settings, pass_block = nil)
|
|
24
|
+
if !Appsignal.active? || env["sinatra.static_file"]
|
|
25
|
+
return route_without_appsignal(base, pass_block)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
transaction = Appsignal::Transaction.create(
|
|
29
|
+
SecureRandom.uuid,
|
|
30
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
|
31
|
+
request
|
|
32
|
+
)
|
|
33
|
+
begin
|
|
34
|
+
Appsignal.instrument("process_action.padrino") do
|
|
35
|
+
route_without_appsignal(base, pass_block)
|
|
36
|
+
end
|
|
37
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
38
|
+
transaction.set_error(error)
|
|
39
|
+
raise error
|
|
40
|
+
ensure
|
|
41
|
+
transaction.set_action_if_nil(get_payload_action(request))
|
|
42
|
+
transaction.set_metadata("path", request.path)
|
|
43
|
+
transaction.set_metadata("method", request.request_method)
|
|
44
|
+
transaction.set_http_or_background_queue_start
|
|
45
|
+
Appsignal::Transaction.complete_current!
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def get_payload_action(request)
|
|
52
|
+
# Short-circut is there's no request object to obtain information from
|
|
53
|
+
return settings.name.to_s unless request
|
|
54
|
+
|
|
55
|
+
# Newer versions expose the action / controller on the request class.
|
|
56
|
+
# Newer versions also still expose a route_obj so we must prioritize the
|
|
57
|
+
# action/fullpath methods.
|
|
58
|
+
# The `request.action` and `request.controller` values are `nil` when a
|
|
59
|
+
# endpoint is not found, `""` if not specified by the user.
|
|
60
|
+
controller_name = request.controller if request.respond_to?(:controller)
|
|
61
|
+
action_name = request.action if request.respond_to?(:action)
|
|
62
|
+
action_name ||= ""
|
|
63
|
+
if action_name.empty? && request.respond_to?(:fullpath)
|
|
64
|
+
action_name = request.fullpath
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
unless action_name.empty?
|
|
68
|
+
return "#{settings.name}:#{controller_name}##{action_name}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Older versions of Padrino work with a route object
|
|
72
|
+
if request.respond_to?(:route_obj) && request.route_obj
|
|
73
|
+
return "#{settings.name}:#{request.route_obj.original_path}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Fall back to the application name if we haven't found an action name in
|
|
77
|
+
# any previous methods.
|
|
78
|
+
settings.name.to_s
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
Padrino.after_load do
|
|
83
|
+
Appsignal::Integrations::PadrinoPlugin.init
|
|
84
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Appsignal
|
|
2
|
+
module Integrations
|
|
3
|
+
module QuePlugin
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.class_eval do
|
|
6
|
+
def _run_with_appsignal
|
|
7
|
+
env = {
|
|
8
|
+
:metadata => {
|
|
9
|
+
:id => attrs[:job_id],
|
|
10
|
+
:queue => attrs[:queue],
|
|
11
|
+
:run_at => attrs[:run_at].to_s,
|
|
12
|
+
:priority => attrs[:priority],
|
|
13
|
+
:attempts => attrs[:error_count].to_i
|
|
14
|
+
},
|
|
15
|
+
:params => attrs[:args]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
request = Appsignal::Transaction::GenericRequest.new(env)
|
|
19
|
+
|
|
20
|
+
transaction = Appsignal::Transaction.create(
|
|
21
|
+
SecureRandom.uuid,
|
|
22
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
|
23
|
+
request
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
begin
|
|
27
|
+
Appsignal.instrument("perform_job.que") { _run_without_appsignal }
|
|
28
|
+
rescue Exception => error # rubocop:disable Lint/RescueException
|
|
29
|
+
transaction.set_error(error)
|
|
30
|
+
raise error
|
|
31
|
+
ensure
|
|
32
|
+
transaction.set_action "#{attrs[:job_class]}#run"
|
|
33
|
+
Appsignal::Transaction.complete_current!
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
alias_method :_run_without_appsignal, :_run
|
|
38
|
+
alias_method :_run, :_run_with_appsignal
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Appsignal.logger.info("Loading Rails (#{Rails.version}) integration")
|
|
2
|
+
|
|
3
|
+
require "appsignal/rack/rails_instrumentation"
|
|
4
|
+
|
|
5
|
+
module Appsignal
|
|
6
|
+
module Integrations
|
|
7
|
+
# @api private
|
|
8
|
+
class Railtie < ::Rails::Railtie
|
|
9
|
+
initializer "appsignal.configure_rails_initialization" do |app|
|
|
10
|
+
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.initialize_appsignal(app)
|
|
14
|
+
# Load config
|
|
15
|
+
Appsignal.config = Appsignal::Config.new(
|
|
16
|
+
Rails.root,
|
|
17
|
+
Rails.env,
|
|
18
|
+
:name => Rails.application.class.parent_name,
|
|
19
|
+
:log_path => Rails.root.join("log")
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Start logger
|
|
23
|
+
Appsignal.start_logger
|
|
24
|
+
|
|
25
|
+
app.middleware.insert_after(
|
|
26
|
+
ActionDispatch::DebugExceptions,
|
|
27
|
+
Appsignal::Rack::RailsInstrumentation
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if Appsignal.config[:enable_frontend_error_catching]
|
|
31
|
+
app.middleware.insert_before(
|
|
32
|
+
Appsignal::Rack::RailsInstrumentation,
|
|
33
|
+
Appsignal::Rack::JSExceptionCatcher
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Appsignal.start
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|