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

Fix Ruby VM statistics broken and causing errors on Ruby 3.2 #2600

Merged
merged 5 commits into from
Feb 7, 2023

Conversation

ivoanjo
Copy link
Member

@ivoanjo ivoanjo commented Feb 7, 2023

What does this PR do?:

This PR fixes #2534 by:

a. Making sure we don't try to report non-existing statistics on Ruby 3.2
b. Adding reporting of the new Ruby 3.2 statistics

It also includes a few cleanups to get us in better shape to support Ruby 3.2.

Motivation:

dd-trace-rb should definitely not get in the way of our awesome customers using Ruby 3.2.

Additional Notes

The newly-reported metrics will not show up in the Datadog UX yet, I'm preparing a separate PR to the Datadog UX and default Ruby Runtime Metrics dashboard to show them.

How to test the change?:

We are not yet running Ruby 3.2 in CI (I'm preparing a follow-up PR for this), so you'll need to run the test suite locally to validate this.


Fixes #2534

`Tracer#initialize` only takes keyword arguments so I did the simple fix
rather than the full `ruby2_keywords` thing.
ddtrace will now report the new stats, as well as not try to report
stats that are nil, so that in the future as Ruby evolves we won't
break again as we did in #2534.

Fixes #2534
@ivoanjo ivoanjo requested a review from a team February 7, 2023 09:28
@github-actions github-actions bot added the core Involves Datadog core libraries label Feb 7, 2023
Comment on lines -31 to +42
context 'with Ruby < 3', if: RUBY_VERSION < '3.0.0' do
context 'on Ruby 2.x' do
before { skip('Test only runs on Ruby 2.x') unless RUBY_VERSION.start_with?('2.') }
Copy link
Member Author

Choose a reason for hiding this comment

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

Why replace if: RUBY_VERSION < '3.0.0' with the explicit skip?

I like the explicit skip when some test is not running, because it shows up in the rspec output that the testcase was skipped.

Otherwise, it's easy to do a change, run RSpec, it says all tests passed and you just broke some other Ruby version which is being skipped. Yes CI would catch it, but I still favor the more explicit style.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like this approach as well.

Copy link
Contributor

@lloeki lloeki left a comment

Choose a reason for hiding this comment

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

Approved, but left a few open questions that may be resolved later.

@@ -57,15 +57,27 @@ def flush

try_flush do
if Core::Environment::VMCache.available?
gauge(
# Only on Ruby < 3.2
gauge_if_not_nil(
Copy link
Contributor

Choose a reason for hiding this comment

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

Pondering about this nil check + comments.

  • WDYT about an explicit version check? (if or case RUBY_VERSION when ...). That would make the code self-explanatory, and materialise the else case.
  • WDYT about a feature check? something like if Core::Utils::Features::Ruby.vmcache_global_constant_state?

Copy link
Member Author

Choose a reason for hiding this comment

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

WDYT about an explicit version check? (if or case RUBY_VERSION when ...). That would make the code self-explanatory, and materialise the else case.

I chose not to do the explicit version check so that in the future we wouldn't get bitten by the same issue: let's say Ruby 3.5 removes some of the new metrics, and again we would break if we checked the Ruby version and not the underlying data.

It's true that our comments could become inaccurate in that situation, but since our tests validate the expected results, we would have an indication that there's something we need to fix -- while still not breaking released dd-trace-rb versions.

WDYT about a feature check? something like if Core::Utils::Features::Ruby.vmcache_global_constant_state?

A feature check per metric would mean more code + more tests to replace the current nil check. I wouldn't oppose such a change, but I'm not particularly convinced it's worth the extra complexity either.

Comment on lines +71 to +72
allow(Datadog::Tracing::Tracer).to receive(:new).and_wrap_original do |method, **args, &block|
instance = method.call(**args, &block)
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: make it explicit that this is keyword arguments now.

Suggested change
allow(Datadog::Tracing::Tracer).to receive(:new).and_wrap_original do |method, **args, &block|
instance = method.call(**args, &block)
allow(Datadog::Tracing::Tracer).to receive(:new).and_wrap_original do |method, **kwargs, &block|
instance = method.call(**kwargs, &block)

Also, wondering what happened to *args: is is not needed anymore?

My spider-sense is tingling here WRT the argument changes that happened between 2.6, 2.7, 3.0+3.1, and 3.2.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that this is a specific simpler fix for the Tracer class only -- if this was something on some outside gem we'd need to sprinkle our friend ruby2_keywords instead ;)

What happened here is that on dd-trace-rb 0.x, this used to be the classic options = {}:

https://github.com/DataDog/dd-trace-rb/blob/v0.54.2/lib/ddtrace/tracer.rb#L76

...but on 1.0 it was moved to use real keyword arguments:

https://github.com/DataDog/dd-trace-rb/blob/v1.0.0/lib/datadog/tracing/tracer.rb#L50

Up to 3.2, the forwarding we were doing here still worked, but it stopped working in 3.2. And for all the others, this change works because the class gets keyword arguments.

@ivoanjo ivoanjo merged commit 37b5e3f into master Feb 7, 2023
@ivoanjo ivoanjo deleted the ivoanjo/ruby-3.2-fixes branch February 7, 2023 11:32
@github-actions github-actions bot added this to the 1.10.0 milestone Feb 7, 2023
@TonyCTHsu TonyCTHsu mentioned this pull request Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Involves Datadog core libraries
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ruby 3.2.0 gauge error for the RubyVM.stat API changes
2 participants