[PROF-7440] Add workaround for incorrect invoke location when logging gem is in use#3183
Conversation
… gem is in use **What does this PR do?** In #2950, we added a fallback for nameless threads: we use their "invoke location", as shown by Ruby in the default `Thread#to_s`. The invoke location is the file and line of the first method of the thread. This fallback has an issue: when thread creation is monkey patched. One common source of this is the `logging` gem. When the `logging` gem monkey patches thread creation, every thread will have the same invoke location, which will point to the `logging` gem. This made the fallback invoke location worse than not having anything. To work around this, this PR changes the profiler so that when the invoke location belongs to the `logging` gem, it's not used, and a simpler `(Unnamed thread)` placeholder is used instead. **Motivation:** This issue came up when testing the timeline feature with some of the internal Ruby apps. **Additional Notes:** In the future we could probably explore a more generic fix (e.g. using `Thread.method(:new).source_location` or something like that to detect redefinition) but doing that from the profiler native code is a bit more work so I decided to go with a simpler approach. **How to test the change?** Change includes test coverage. You can also see the thread name difference on an app by creating a simple thread before/after loading the `logging` gem and see the fallback name for the thread.
Codecov Report
@@ Coverage Diff @@
## master #3183 +/- ##
=======================================
Coverage 98.21% 98.21%
=======================================
Files 1247 1248 +1
Lines 71664 71685 +21
Branches 3329 3330 +1
=======================================
+ Hits 70382 70403 +21
Misses 1282 1282
... and 5 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
ekump
left a comment
There was a problem hiding this comment.
A hacky solution, but LGTM to unblock the 1.15 release. This is better than no fix at all. Might be worth adding a comment to the code indicating that it's likely a temporary solution?
…d with a better option
Thanks for the review + agreed. Documented it in 4ff3cf6. |
What does this PR do?
In #2950, we added a fallback for nameless threads: we use their "invoke location", as shown by Ruby in the default
Thread#to_s. The invoke location is the file and line of the first method of the thread.This fallback has an issue: when thread creation is monkey patched. One common source of this is the
logginggem. When thelogginggem monkey patches thread creation, every thread will have the same invoke location, which will point to thelogginggem.This made the fallback invoke location worse than not having anything.
To work around this, this PR changes the profiler so that when the invoke location belongs to the
logginggem, it's not used, and a simpler(Unnamed thread)placeholder is used instead.Motivation:
This issue came up when testing the timeline feature with some of the internal Ruby apps.
Additional Notes:
In the future we could probably explore a more generic fix (e.g. using
Thread.method(:new).source_locationor something like that to detect redefinition) but doing that from the profiler native code is a bit more work so I decided to go with a simpler approach.How to test the change?
Change includes test coverage. You can also see the thread name difference on an app by creating a simple thread before/after loading the
logginggem and see the fallback name for the thread.For Datadog employees:
credentials of any kind, I've requested a review from
@DataDog/security-design-and-guidance.