Skip to content

Conversation

tcannonfodder
Copy link

What does this PR do?

Add view_component integration for Datadog::Tracing

  • ViewComponent supports instrumentation through ActiveSupport notifications, and having the ability to trace a ViewComponent using Datadog's APM provides a similar level of debugging ease that tracing ActionView template and partial rendering provides
  • This tracing component was based on Datadog::Tracing::Contrib::ActionView, with some key differences:
    • There is only one action available for instrumentation: render
    • ViewComponent is technically its own component, not part of Rails itself
      • Therefore, it uses Contrib::Integration#auto_instrument? rather than checking the Railtie
    • The span.resource is the name of the component (MyComponent), not its identifier (my_component.rb), for a better user experience

WIP: Add view_component build matricies in appraisal

  • I was not able to get the docker compose setup running on my machine due to the inability to pull the ddapm-test-agent
    • Therefore, I was not able to spool up containers for each version of Ruby to generate their gemfiles/
  • While I tested this locally with ruby-3.3, I did not commit the changes since I was not able to follow the containerized setup

Motivation:

I'm using ViewComponent in my apps, and wanted to be able to debug performance issues inside of a ViewComponent.

Change log entry

Additional Notes:

Example screenshot:

image

How to test the change?

Tests have been added based on the action_view integration

* `ViewComponent` supports instrumentation through `ActiveSupport`
	notifications, and having the ability to trace a ViewComponent
	using Datadog's APM provides a similar level of debugging ease that
	tracing `ActionView` template and partial rendering provides
* This tracing component was based on
	`Datadog::Tracing::Contrib::ActionView`, with some key differences:
	* There is only one action available for instrumentation: `render`
	* ViewComponent is technically its own component, not part of Rails
		itself
		* Therefore, it uses `Contrib::Integration#auto_instrument?`
			rather than checking the Railtie
	* The `span.resource` is the name of the component
		(`MyComponent`), not its identifier (`my_component.rb`), for a
		better  user experience
* Added tests, but need to update the Matrixfile and appraisals
* I was not able to get the `docker compose` setup running on my
	machine due to the inability to pull the `ddapm-test-agent`
	* Therefore, I was not able to spool up containers for each version
		of Ruby to generate their `gemfiles/`
* While I tested this locally with `ruby-3.3`, I did not commit the
	changes since I was not able to follow the containerized setup
@tcannonfodder tcannonfodder requested review from a team as code owners October 14, 2025 11:49
@tcannonfodder tcannonfodder requested a review from vpellan October 14, 2025 11:49
@github-actions github-actions bot added integrations Involves tracing integrations tracing labels Oct 14, 2025
Copy link
Member

@y9v y9v left a comment

Choose a reason for hiding this comment

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

@tcannonfodder thank you for your contribution!

I left some small remarks, and I think it would make sense to add an integration test for this feature. If you need some help with the integration test, please let me know.

end

option :service_name
option :component_base_path do |o|
Copy link
Member

Choose a reason for hiding this comment

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

Would components_base_path be better? Since it's a path containing multiple components.

Copy link
Member

Choose a reason for hiding this comment

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

I also think we would need to ensure the correct format here - when calculating the component identifier, we are relying that this path will end with /, otherwise component identifiers will start with a /

Copy link
Author

Choose a reason for hiding this comment

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

Both this (and the comment below) are essentially straight ports from the action_view integration; which felt like the right approach to take here because these components are run together (you often render ViewComponents inside ActionView), so it feels right that they are configured and behave similarly.

But! Y’all have the final say here; so just lemme know what makes sense for the repo. :) I just wanted to explain my reasoning for these decisions.

References: https://github.com/DataDog/dd-trace-rb/blob/master/lib/datadog/tracing/contrib/action_view/configuration/settings.rb#L34-L37

sections_view = identifier.split(base_path)

if sections_view.length == 1
identifier.split('/')[-1]
Copy link
Member

Choose a reason for hiding this comment

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

I think this won't work if the components base path is repeated somewhere in the filename:

> 'some/path/components/admin/components/sidebar_component.rb'.split('components/')[-1]
=> "sidebar_component.rb"

span.set_tag(Ext::TAG_COMPONENT_NAME, payload[:name])

if (identifier = Utils.normalize_component_identifier(payload[:identifier]))
span.set_tag(Ext::TAG_COMPONENT_IDENTIFIER, identifier)
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this really is an identifier, since it's basically a partial file path. Do we want to name it something like component_path?

Copy link
Author

Choose a reason for hiding this comment

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

We definitely could; I had based the name component on the value that's passed in the ActiveSupport's payload; so that the APM telemetry matched the instrumentation data. But if you'd like me to change it; just let me know.

Reference: https://viewcomponent.org/guide/instrumentation.html

@tcannonfodder
Copy link
Author

I left some small remarks, and I think it would make sense to add an integration test for this feature. If you need some help with the integration test, please let me know.

Thanks so much for reviewing it! Eager to get this merged in 😄 . I left some additional contextual comments for why I’d made those decisions; just let me know which approaches you’d like me to take.

I’ll try writing an integration test; and I’ll make a new comment with a WIP commit if I get stuck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integrations Involves tracing integrations tracing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants