lib/appsignal/integrations/padrino.rb
# frozen_string_literal: true
require "appsignal"
module Appsignal
module Integrations
# @api private
module PadrinoPlugin
def self.init
Appsignal.logger.info("Loading Padrino (#{Padrino::VERSION}) integration")
root = Padrino.mounted_root
Appsignal.config = Appsignal::Config.new(root, Padrino.env)
Appsignal.start_logger
Appsignal.start
end
end
end
end
module Padrino::Routing::InstanceMethods
alias route_without_appsignal route!
def route!(base = settings, pass_block = nil)
if !Appsignal.active? || env["sinatra.static_file"]
return route_without_appsignal(base, pass_block)
end
transaction = Appsignal::Transaction.create(
SecureRandom.uuid,
Appsignal::Transaction::HTTP_REQUEST,
request
)
begin
Appsignal.instrument("process_action.padrino") do
route_without_appsignal(base, pass_block)
end
rescue Exception => error # rubocop:disable Lint/RescueException
transaction.set_error(error)
raise error
ensure
transaction.set_action_if_nil(get_payload_action(request))
transaction.set_metadata("path", request.path)
transaction.set_metadata("method", request.request_method)
transaction.set_http_or_background_queue_start
Appsignal::Transaction.complete_current!
end
end
private
def get_payload_action(request)
# Short-circut is there's no request object to obtain information from
return settings.name.to_s unless request
# Newer versions expose the action / controller on the request class.
# Newer versions also still expose a route_obj so we must prioritize the
# action/fullpath methods.
# The `request.action` and `request.controller` values are `nil` when a
# endpoint is not found, `""` if not specified by the user.
controller_name = request.controller if request.respond_to?(:controller)
action_name = request.action if request.respond_to?(:action)
action_name ||= ""
unless action_name.empty?
return "#{settings.name}:#{controller_name}##{action_name}"
end
# Older versions of Padrino work with a route object
if request.respond_to?(:route_obj) && request.route_obj
return "#{settings.name}:#{request.route_obj.original_path}"
end
# Fall back to the application name if we haven't found an action name in
# any previous methods.
"#{settings.name}#unknown"
end
end
Padrino.after_load do
Appsignal::Integrations::PadrinoPlugin.init
end