-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unify rack middleware integrations #1046
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,59 +6,27 @@ module Appsignal | |
# @api private | ||
module Rack | ||
class RailsInstrumentation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not quite sure what this is doing now, how this would be used, or how it sets errors. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is in progress - like I said, it's a sketch for now (because so many things need to get touched) |
||
def initialize(app, options = {}) | ||
Appsignal.internal_logger.debug "Initializing Appsignal::Rack::RailsInstrumentation" | ||
@app = app | ||
@options = options | ||
def initialize(app, options={}) | ||
super | ||
@options[:request_class] = ActionDispatch::Request | ||
@instrument_span_name = "process_action.rails" | ||
end | ||
|
||
def call(env) | ||
if Appsignal.active? | ||
call_with_appsignal_monitoring(env) | ||
else | ||
nil_transaction = Appsignal::Transaction::NilTransaction.new | ||
status, headers, obody = @app.call(env) | ||
[status, headers, Appsignal::Rack::BodyWrapper.wrap(obody, nil_transaction)] | ||
def set_transaction_attributes_from_request(transaction, request) | ||
controller = request.env["action_controller.instance"] | ||
if controller | ||
transaction.set_action_if_nil("#{controller.class}##{controller.action_name}") | ||
end | ||
super | ||
end | ||
|
||
def call_with_appsignal_monitoring(env) | ||
request = ActionDispatch::Request.new(env) | ||
transaction = Appsignal::Transaction.create( | ||
request_id(env), | ||
def create_transaction_from_request(request) | ||
Appsignal::Transaction.create( | ||
request_id(request.env), | ||
Appsignal::Transaction::HTTP_REQUEST, | ||
request, | ||
:params_method => :filtered_parameters | ||
) | ||
# We need to complete the transaction if there is an exception exception inside the `call` | ||
# of the app. If there isn't one and the app returns us a Rack response triplet, we let | ||
# the BodyWrapper complete the transaction when #close gets called on it | ||
# (guaranteed by the webserver) | ||
complete_transaction_without_body = false | ||
begin | ||
status, headers, obody = @app.call(env) | ||
[status, headers, Appsignal::Rack::BodyWrapper.wrap(obody, transaction)] | ||
rescue Exception => error # rubocop:disable Lint/RescueException | ||
transaction.set_error(error) | ||
complete_transaction_without_body = true | ||
raise error | ||
ensure | ||
controller = env["action_controller.instance"] | ||
if controller | ||
transaction.set_action_if_nil("#{controller.class}##{controller.action_name}") | ||
end | ||
transaction.set_http_or_background_queue_start | ||
transaction.set_metadata("path", request.path) | ||
begin | ||
transaction.set_metadata("method", request.request_method) | ||
rescue => error | ||
Appsignal.internal_logger.error("Unable to report HTTP request method: '#{error}'") | ||
end | ||
|
||
# Transaction gets completed when the body gets read out, except in cases when | ||
# the app failed before returning us the Rack response triplet. | ||
Appsignal::Transaction.complete_current! if complete_transaction_without_body | ||
end | ||
end | ||
|
||
def request_id(env) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope we can move these kinds of checks to the middleware of library they're for. That way the instrumentation of each library is together with all the other instrumentation for that library and easier to find back.
See also my comment on: #329 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is a side-effect of trying to use the
filtered_params
no-matter-what. Ifrequest
may be re-assigned this is moot (and too clever).