appsignal 2.1.2 → 2.2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +14 -0
- data/.rubocop_todo.yml +16 -171
- data/.travis.yml +14 -1
- data/.yardopts +8 -0
- data/CHANGELOG.md +21 -3
- data/README.md +20 -2
- data/Rakefile +60 -62
- data/appsignal.gemspec +24 -23
- data/ext/agent.yml +11 -11
- data/ext/appsignal_extension.c +43 -12
- data/ext/extconf.rb +9 -9
- data/gemfiles/padrino.gemfile +1 -1
- data/lib/appsignal.rb +403 -26
- data/lib/appsignal/auth_check.rb +28 -1
- data/lib/appsignal/cli.rb +1 -0
- data/lib/appsignal/cli/demo.rb +40 -0
- data/lib/appsignal/cli/diagnose.rb +345 -89
- data/lib/appsignal/cli/helpers.rb +9 -4
- data/lib/appsignal/cli/install.rb +6 -6
- data/lib/appsignal/cli/notify_of_deploy.rb +58 -0
- data/lib/appsignal/config.rb +40 -38
- data/lib/appsignal/demo.rb +20 -0
- data/lib/appsignal/event_formatter.rb +4 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +1 -0
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +1 -0
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -0
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +2 -1
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +1 -0
- data/lib/appsignal/extension.rb +1 -0
- data/lib/appsignal/garbage_collection_profiler.rb +20 -19
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/hooks/active_support_notifications.rb +1 -0
- data/lib/appsignal/hooks/celluloid.rb +1 -0
- data/lib/appsignal/hooks/data_mapper.rb +1 -0
- data/lib/appsignal/hooks/delayed_job.rb +1 -0
- data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -0
- data/lib/appsignal/hooks/net_http.rb +1 -0
- data/lib/appsignal/hooks/passenger.rb +1 -0
- data/lib/appsignal/hooks/puma.rb +1 -0
- data/lib/appsignal/hooks/rake.rb +1 -0
- data/lib/appsignal/hooks/redis.rb +1 -0
- data/lib/appsignal/hooks/sequel.rb +1 -0
- data/lib/appsignal/hooks/shoryuken.rb +1 -0
- data/lib/appsignal/hooks/sidekiq.rb +1 -0
- data/lib/appsignal/hooks/unicorn.rb +1 -0
- data/lib/appsignal/hooks/webmachine.rb +1 -0
- data/lib/appsignal/integrations/capistrano/appsignal.cap +4 -4
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -0
- data/lib/appsignal/integrations/data_mapper.rb +1 -1
- data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -0
- data/lib/appsignal/integrations/grape.rb +3 -1
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -0
- data/lib/appsignal/integrations/padrino.rb +36 -21
- data/lib/appsignal/integrations/railtie.rb +2 -2
- data/lib/appsignal/integrations/resque.rb +1 -0
- data/lib/appsignal/integrations/resque_active_job.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +27 -24
- data/lib/appsignal/js_exception_transaction.rb +8 -8
- data/lib/appsignal/marker.rb +41 -4
- data/lib/appsignal/minutely.rb +1 -0
- data/lib/appsignal/rack/generic_instrumentation.rb +3 -2
- data/lib/appsignal/rack/js_exception_catcher.rb +55 -15
- data/lib/appsignal/rack/rails_instrumentation.rb +2 -1
- data/lib/appsignal/rack/sinatra_instrumentation.rb +4 -2
- data/lib/appsignal/rack/streaming_listener.rb +4 -2
- data/lib/appsignal/system.rb +5 -31
- data/lib/appsignal/transaction.rb +71 -6
- data/lib/appsignal/transmitter.rb +24 -13
- data/lib/appsignal/utils.rb +18 -11
- data/lib/appsignal/utils/params_sanitizer.rb +2 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/resources/appsignal.yml.erb +1 -1
- data/spec/lib/appsignal/auth_check_spec.rb +64 -22
- data/spec/lib/appsignal/cli/diagnose_spec.rb +539 -81
- data/spec/lib/appsignal/cli/helpers_spec.rb +74 -2
- data/spec/lib/appsignal/cli/install_spec.rb +3 -3
- data/spec/lib/appsignal/config_spec.rb +38 -72
- data/spec/lib/appsignal/demo_spec.rb +2 -2
- data/spec/lib/appsignal/event_formatter_spec.rb +2 -2
- data/spec/lib/appsignal/extension_spec.rb +4 -0
- data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +18 -21
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/redis_spec.rb +34 -44
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/grape_spec.rb +6 -6
- data/spec/lib/appsignal/integrations/padrino_spec.rb +241 -122
- data/spec/lib/appsignal/integrations/railtie_spec.rb +34 -16
- data/spec/lib/appsignal/integrations/resque_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +38 -10
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +2 -2
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +7 -6
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +95 -58
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +9 -6
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +11 -10
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +20 -13
- data/spec/lib/appsignal/system_spec.rb +2 -32
- data/spec/lib/appsignal/transaction_spec.rb +48 -7
- data/spec/lib/appsignal/transmitter_spec.rb +52 -33
- data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +3 -1
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +3 -3
- data/spec/lib/appsignal/utils_spec.rb +49 -6
- data/spec/lib/appsignal_spec.rb +60 -5
- data/spec/spec_helper.rb +4 -3
- data/spec/support/helpers/api_request_helper.rb +1 -4
- data/spec/support/helpers/dependency_helper.rb +4 -0
- data/spec/support/helpers/system_helpers.rb +1 -17
- data/spec/support/helpers/time_helpers.rb +1 -1
- metadata +19 -8
- data/spec/lib/appsignal/system/container_spec.rb +0 -67
- data/spec/lib/appsignal/utils/gzip_spec.rb +0 -10
data/lib/appsignal/hooks.rb
CHANGED
data/lib/appsignal/hooks/puma.rb
CHANGED
data/lib/appsignal/hooks/rake.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
namespace :appsignal do
|
2
2
|
task :deploy do
|
3
|
-
env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env,
|
4
|
-
user = ENV[
|
3
|
+
env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, "production"))))
|
4
|
+
user = ENV["USER"] || ENV["USERNAME"]
|
5
5
|
revision = fetch(:appsignal_revision, fetch(:current_revision))
|
6
6
|
|
7
7
|
appsignal_config = Appsignal::Config.new(
|
8
|
-
ENV[
|
8
|
+
ENV["PWD"],
|
9
9
|
env,
|
10
10
|
fetch(:appsignal_config, {}),
|
11
11
|
Logger.new(StringIO.new)
|
@@ -25,4 +25,4 @@ namespace :appsignal do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
after
|
28
|
+
after "deploy:finished", "appsignal:deploy"
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module Appsignal
|
2
|
+
# @todo Move to sub-namespace
|
3
|
+
# @api private
|
2
4
|
module Grape
|
3
5
|
class Middleware < ::Grape::Middleware::Base
|
4
6
|
def call(env)
|
@@ -37,7 +39,7 @@ module Appsignal
|
|
37
39
|
path = "/#{path}" if path[0] != "/"
|
38
40
|
path = "#{namespace}#{path}"
|
39
41
|
|
40
|
-
transaction.
|
42
|
+
transaction.set_action_if_nil("#{request_method}::#{klass}##{path}")
|
41
43
|
end
|
42
44
|
|
43
45
|
transaction.set_http_or_background_queue_start
|
@@ -1,19 +1,18 @@
|
|
1
1
|
require "appsignal"
|
2
2
|
|
3
|
-
module Appsignal
|
4
|
-
module
|
5
|
-
|
6
|
-
|
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")
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
root,
|
11
|
-
Padrino.env,
|
12
|
-
:log_path => File.join(root, "log")
|
13
|
-
)
|
10
|
+
root = Padrino.mounted_root
|
11
|
+
Appsignal.config = Appsignal::Config.new(root, Padrino.env)
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
Appsignal.start_logger
|
14
|
+
Appsignal.start
|
15
|
+
end
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
@@ -23,8 +22,7 @@ module Padrino::Routing::InstanceMethods
|
|
23
22
|
|
24
23
|
def route!(base = settings, pass_block = nil)
|
25
24
|
if !Appsignal.active? || env["sinatra.static_file"]
|
26
|
-
route_without_appsignal(base, pass_block)
|
27
|
-
return
|
25
|
+
return route_without_appsignal(base, pass_block)
|
28
26
|
end
|
29
27
|
|
30
28
|
transaction = Appsignal::Transaction.create(
|
@@ -40,7 +38,7 @@ module Padrino::Routing::InstanceMethods
|
|
40
38
|
transaction.set_error(error)
|
41
39
|
raise error
|
42
40
|
ensure
|
43
|
-
transaction.
|
41
|
+
transaction.set_action_if_nil(get_payload_action(request))
|
44
42
|
transaction.set_metadata("path", request.path)
|
45
43
|
transaction.set_metadata("method", request.request_method)
|
46
44
|
transaction.set_http_or_background_queue_start
|
@@ -48,19 +46,36 @@ module Padrino::Routing::InstanceMethods
|
|
48
46
|
end
|
49
47
|
end
|
50
48
|
|
49
|
+
private
|
50
|
+
|
51
51
|
def get_payload_action(request)
|
52
52
|
# Short-circut is there's no request object to obtain information from
|
53
|
-
return settings.name.to_s
|
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
|
54
70
|
|
55
71
|
# Older versions of Padrino work with a route object
|
56
|
-
|
57
|
-
if route_obj && route_obj.respond_to?(:original_path)
|
72
|
+
if request.respond_to?(:route_obj) && request.route_obj
|
58
73
|
return "#{settings.name}:#{request.route_obj.original_path}"
|
59
74
|
end
|
60
75
|
|
61
|
-
#
|
62
|
-
|
63
|
-
|
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
|
64
79
|
end
|
65
80
|
end
|
66
81
|
|
@@ -4,6 +4,7 @@ require "appsignal/rack/rails_instrumentation"
|
|
4
4
|
|
5
5
|
module Appsignal
|
6
6
|
module Integrations
|
7
|
+
# @api private
|
7
8
|
class Railtie < ::Rails::Railtie
|
8
9
|
initializer "appsignal.configure_rails_initialization" do |app|
|
9
10
|
Appsignal::Integrations::Railtie.initialize_appsignal(app)
|
@@ -26,8 +27,7 @@ module Appsignal
|
|
26
27
|
Appsignal::Rack::RailsInstrumentation
|
27
28
|
)
|
28
29
|
|
29
|
-
if Appsignal.config
|
30
|
-
Appsignal.config[:enable_frontend_error_catching] == true
|
30
|
+
if Appsignal.config[:enable_frontend_error_catching]
|
31
31
|
app.middleware.insert_before(
|
32
32
|
Appsignal::Rack::RailsInstrumentation,
|
33
33
|
Appsignal::Rack::JSExceptionCatcher
|
@@ -1,32 +1,35 @@
|
|
1
|
-
module Appsignal
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
Appsignal::Transaction
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
module Appsignal
|
2
|
+
module Integrations
|
3
|
+
# @api private
|
4
|
+
module WebmachinePlugin
|
5
|
+
module FSM
|
6
|
+
def run_with_appsignal
|
7
|
+
transaction = Appsignal::Transaction.create(
|
8
|
+
SecureRandom.uuid,
|
9
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
10
|
+
request,
|
11
|
+
:params_method => :query
|
12
|
+
)
|
11
13
|
|
12
|
-
|
14
|
+
transaction.set_action_if_nil("#{resource.class.name}##{request.method}")
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
Appsignal.instrument("process_action.webmachine") do
|
17
|
+
run_without_appsignal
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
Appsignal::Transaction.complete_current!
|
21
|
+
end
|
20
22
|
|
21
|
-
|
23
|
+
private
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def handle_exceptions_with_appsignal
|
26
|
+
handle_exceptions_without_appsignal do
|
27
|
+
begin
|
28
|
+
yield
|
29
|
+
rescue => e
|
30
|
+
Appsignal.set_error(e)
|
31
|
+
raise e
|
32
|
+
end
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
@@ -14,17 +14,17 @@ module Appsignal
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def set_action
|
17
|
-
|
17
|
+
return unless @data["action"]
|
18
|
+
ext.set_action(@data["action"])
|
18
19
|
end
|
19
20
|
|
20
21
|
def set_metadata
|
21
|
-
@
|
22
|
-
|
23
|
-
) if @data["path"]
|
22
|
+
return unless @data["path"]
|
23
|
+
ext.set_metadata("path", @data["path"])
|
24
24
|
end
|
25
25
|
|
26
26
|
def set_error
|
27
|
-
|
27
|
+
ext.set_error(
|
28
28
|
@data["name"],
|
29
29
|
@data["message"] || "",
|
30
30
|
Appsignal::Utils.data_generate(@data["backtrace"] || [])
|
@@ -39,7 +39,7 @@ module Appsignal
|
|
39
39
|
:tags => @data["tags"]
|
40
40
|
}.each do |key, data|
|
41
41
|
next unless data.is_a?(Array) || data.is_a?(Hash)
|
42
|
-
|
42
|
+
ext.set_sample_data(
|
43
43
|
key.to_s,
|
44
44
|
Appsignal::Utils.data_generate(data)
|
45
45
|
)
|
@@ -47,8 +47,8 @@ module Appsignal
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def complete!
|
50
|
-
|
51
|
-
|
50
|
+
ext.finish(0)
|
51
|
+
ext.complete
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/appsignal/marker.rb
CHANGED
@@ -1,23 +1,60 @@
|
|
1
1
|
module Appsignal
|
2
|
+
# Deploy markers are used on AppSignal.com to indicate changes in an
|
3
|
+
# application, "Deploy markers" indicate a deploy of an application.
|
4
|
+
#
|
5
|
+
# Incidents for exceptions and performance issues will be closed and
|
6
|
+
# reopened if they occur again in the new deploy.
|
7
|
+
#
|
8
|
+
# This class will help send a request to the AppSignal Push API to create a
|
9
|
+
# Deploy marker for the application on AppSignal.com.
|
10
|
+
#
|
11
|
+
# @!attribute [r] marker_data
|
12
|
+
# @return [Hash] marker data to send.
|
13
|
+
#
|
14
|
+
# @!attribute [r] config
|
15
|
+
# @return [Appsignal::Config] config to use in the authentication request.
|
16
|
+
# Set config does not override data set in {#marker_data}.
|
17
|
+
#
|
18
|
+
# @see Appsignal::CLI::NotifyOfDeploy
|
19
|
+
# @see http://docs.appsignal.com/appsignal/terminology.html#markers
|
20
|
+
# Terminology: Deploy marker
|
21
|
+
# @api private
|
2
22
|
class Marker
|
23
|
+
# Path used on the AppSignal Push API
|
24
|
+
# https://push.appsignal.com/1/markers
|
25
|
+
ACTION = "markers".freeze
|
26
|
+
|
3
27
|
attr_reader :marker_data, :config
|
4
|
-
ACTION = "markers"
|
5
28
|
|
29
|
+
# @param marker_data [Hash] see {#marker_data}
|
30
|
+
# @option marker_data :environment [String] environment to load
|
31
|
+
# configuration for.
|
32
|
+
# @option marker_data :name [String] name of the application.
|
33
|
+
# @option marker_data :user [String] name of the user that is creating the
|
34
|
+
# marker.
|
35
|
+
# @option marker_data :revision [String] the revision that has been
|
36
|
+
# deployed. E.g. a git commit SHA.
|
37
|
+
# @param config [Appsignal::Config]
|
6
38
|
def initialize(marker_data, config)
|
7
39
|
@marker_data = marker_data
|
8
40
|
@config = config
|
9
41
|
end
|
10
42
|
|
43
|
+
# Send a request to create the marker.
|
44
|
+
#
|
45
|
+
# Prints output to STDOUT.
|
46
|
+
#
|
47
|
+
# @return [void]
|
11
48
|
def transmit
|
12
49
|
transmitter = Transmitter.new(ACTION, config)
|
13
50
|
puts "Notifying AppSignal of deploy with: "\
|
14
51
|
"revision: #{marker_data[:revision]}, user: #{marker_data[:user]}"
|
15
52
|
|
16
|
-
|
17
|
-
if
|
53
|
+
response = transmitter.transmit(marker_data)
|
54
|
+
if response.code == "200"
|
18
55
|
puts "AppSignal has been notified of this deploy!"
|
19
56
|
else
|
20
|
-
raise "#{
|
57
|
+
raise "#{response.code} at #{transmitter.uri}"
|
21
58
|
end
|
22
59
|
rescue => e
|
23
60
|
puts "Something went wrong while trying to notify AppSignal: #{e}"
|