DI: capture real positional parameter names in non-virtual method probes - #6114
DI: capture real positional parameter names in non-virtual method probes#6114p-datadog wants to merge 11 commits into
Conversation
Method-probe snapshots keyed captured positional arguments as arg1, arg2, ... because the prepend wrapper captures them as *args, losing the declared names. Recover the names at hook time via UnboundMethod#parameters (the same reflection the symbol database extractor uses), thread them through run_method_probe into the serializer, and key each positional argument by its real name. Arguments without an available name (generated methods, values absorbed by a splat, virtual/C methods) keep the arg-N label. Keyword arguments and self are unchanged. This also lets capture expressions reference positional parameters by their real names.
Typing analysisNote: Ignored files are excluded from the next sections.
|
🎉 All green!🧪 All tests passed 🔗 Commit SHA: 1b5b038 | Docs | Datadog PR Page | Give us feedback! |
Omit the explicit StandardError class in the positional-parameter-name extraction rescue (rescue => e), fixing the standard/lint CI failure (bundle exec rubocop -D). Verified under gemfiles/ruby-4.0.gemfile: `bundle exec rubocop -D` reports no offenses and `bundle exec rake standard` passes. Co-Authored-By: Claude <noreply@anthropic.com>
…cs, RBS prefix - extract_positional_param_names: rescue Exception + reraise_if_fatal + telemetry (matches the DI catch-all convention used elsewhere in the file) - combine_args / serialize_args: full YARD param/return docs after signature change - instrumenter.rbs: ::UnboundMethod prefix
BenchmarksBenchmark execution time: 2026-08-12 22:04:07 Comparing candidate commit 1b5b038 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 48 metrics, 1 unstable metrics.
|
…d arg
Keying positional method-probe arguments by their real parameter name let
Serializer#combine_args's `combined.update(kwargs)` overwrite a positional
value when a keyword argument shares the positional's name (e.g.
`def foo(path, **opts)` called `foo('/a', path: 'x')`): the positional value
was silently dropped from the snapshot. Fall back to the arg-N label for a
positional whose name collides with a keyword key so both values are kept.
Also from review:
- serializer_spec: cover the collision fallback and confirm a positional whose
real name is a redacted identifier is now redacted (previously the arg-N
label captured it in the clear).
- instrumenter_spec: cover extract_positional_param_names for an attr_writer-
generated method (nil parameter name) and its rescue branch.
- serializer.rbs: :: prefix on the stdlib types in the changed combine_args /
serialize_args signatures.
…ames When a method already carries a probe, hook_method's instance_method call resolves to the earlier probe's prepended wrapper, whose signature is *args, **kwargs and whose source location is inside instrumenter.rb. A later probe on that method then read empty positional parameter names and labeled captured arguments arg1, arg2, ...; capture expressions naming the real parameters resolved to nil. hook_method now walks target_method through DI wrapper modules via super_method before reading source location and parameter names, so every probe reads the original definition regardless of probe order. Each wrapper module carries InstrumentedMethodMarker; other prepended modules stop the walk and are honored as-is.
Explain the wrapper-resolution mechanism once, on original_target_method; drop the type-only YARD tags it duplicated from the rbs signature and the restating comment at the call site.
combine_args and serialize_args accepted param_names as a defaulted positional argument, mixing positional defaults with keyword parameters (prohibited by the repo's No Mixing Default Positional and Keyword Arguments rule). Change param_names to a keyword argument in both methods, update all call sites in instrumenter.rb and serializer_spec.rb, and add a YARD docstring to the InstrumentedMethodMarker module (required by the repo's every module must have a docstring rule).
What does this PR do?
Captures real positional parameter names in probes on explicitly defined methods (i.e. NOT method_missing / C code).
Motivation:
The
arg1etc. placeholders are not discoverable by customers.Change log entry
Yes. Dynamic Instrumentation: report positional method
argument names for methods explicitly defined in Ruby
Additional Notes:
Virtual methods (method_missing) and C code still doesn't reveal the argument names.
arg1etc. placeholders remain for those.How to test the change?
Unit and integration tests added