Skip to content
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

Improve support for nested Rack middlewares #1100

Merged
merged 1 commit into from
Jun 21, 2024

Conversation

tombruijn
Copy link
Member

@tombruijn tombruijn commented Jun 19, 2024

When more of our Rack, Rails and Sinatra middlewares are nested in one app, improve reporting for those requests. This follows PRs #1089 for Rails and #1097 for Sinatra. This change improves this reporting for Rack apps using the GenericInstrumentation middleware. Other than supporting this scenario better, no one should notice this change.

Refactor details

I've refactored the SinatraInstrumentation middleware to inherit from a new AbstractMiddleware which includes much of the behavior from the GenericInstrumentation and previous SinatraInstrumentation implementations.
All the logic for nested instrumentation middlewares are now handled in this AbstractMiddleware.

Subclasses of AbstractMiddleware can set their library's specific metadata using the add_transaction_metadata_before and add_transaction_metadata_after methods, along with specifying the request_class, params_method and instrument_span_name settings.

This already works with the EventHandler, as both set the transaction on the request env to detect nested instrumentation. An app could add both the EventHandler and a subclass of the AbstractMiddleware, and it would report the request transaction properly.

GenericInstrumentation

I've kept the GenericInstrumentation middleware. The only thing it really does different that we don't want to put in the AbstractMiddleware is the fallback to the "unknown" action name. I didn't want to break existing behavior, so that is all it still does.

If we move the GenericInstrumentation action name fallback to the AbstractMiddleware, we may be reporting more requests than we want for other middlewares that inherit from it. For example, for Rails app, I also want to use this AbstractMiddleware, and it relies on asset requests having no action name so the extension can drop them. That way we don't report transactions for asset requests.

Next steps

If this change is approved, I will update the other Rack instrumentations, like Rails, Grape and Padrino.

Part of #329

When more of our Rack, Rails and Sinatra middlewares are nested in one
app, improve reporting for those requests. This follows PRs #1089 for
Rails and #1097 for Sinatra. This change improves this reporting for
Rack apps using the GenericInstrumentation middleware. Other than
supporting this scenario better, no one should notice this change.

## Refactor details

I've refactored the SinatraInstrumentation middleware to inherit from a
new AbstractMiddleware which includes much of the behavior from the
GenericInstrumentation and previous SinatraInstrumentation
implementations.
All the logic for nested instrumentation middlewares are now handled in
this AbstractMiddleware.

Subclasses of AbstractMiddleware can set their library's specific
metadata using the `add_transaction_metadata_before` and
`add_transaction_metadata_after` methods, along with specifying the
`request_class`, `params_method` and `instrument_span_name` settings.

This already works with the EventHandler, as both set the transaction on
the request env to detect nested instrumentation. An app could add both
the EventHandler and a subclass of the AbstractMiddleware, and it would
report the request transaction properly.

## GenericInstrumentation

I've kept the GenericInstrumentation middleware. The only thing it
really does different that we don't want to put in the
AbstractMiddleware is the fallback to the "unknown" action name. I
didn't want to break existing behavior, so that is all it still does.

If we move the GenericInstrumentation action name fallback to the
AbstractMiddleware, we may be reporting more requests than we want for
other middlewares that inherit from it. For example, for Rails app, I
also want to use this AbstractMiddleware, and it relies on asset
requests having no action name so the extension can drop them. That way
we don't report transactions for asset requests.

## Next steps

If this change is approved, I will update the other Rack
instrumentations, like Rails, Grape and Padrino.
@tombruijn tombruijn self-assigned this Jun 19, 2024
@tombruijn tombruijn changed the title Improve supported for nested Rack middlewares Improve support for nested Rack middlewares Jun 19, 2024
@tombruijn tombruijn mentioned this pull request Jun 20, 2024
36 tasks
Copy link
Member

@luismiramirez luismiramirez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appsignal.internal_logger.debug "Initializing Appsignal::Rack::GenericInstrumentation"
@app = app
@options = options
options[:instrument_span_name] ||= "process_action.generic"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could use .rack as the category group, which already has a defined color.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to go through all these event names some time later, because they report process_action which makes no sense for a rack middleware. The generic group isn't a good name either, we can change it to rack, but I'd rather do that later.

@tombruijn tombruijn merged commit 7382afa into main Jun 21, 2024
16 checks passed
@tombruijn tombruijn deleted the rack-nested-instrumentation branch July 10, 2024 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants