Skip to content

Make http-instrumentation-tempo and http-instrumentation-pyroscope instrumentations compatible#154

Merged
mstoykov merged 6 commits intomainfrom
make_tempo_and_pyroscope_compatible
Apr 25, 2025
Merged

Make http-instrumentation-tempo and http-instrumentation-pyroscope instrumentations compatible#154
mstoykov merged 6 commits intomainfrom
make_tempo_and_pyroscope_compatible

Conversation

@andrewslotin
Copy link
Copy Markdown
Contributor

@andrewslotin andrewslotin commented Apr 10, 2025

Description

This PR introduces new versions for Tempo and Pyroscope instrumentation libraries that are compatible with each other. The core change is that http.request and http.asyncRequest in both libraries are now being captured at during the instrumentHTTP() call instead of during the import phase, which ensures that instrumented code wraps the latest, potentially already patched version of the method.

Update: following the discussion with @mstoykov I've added another fix for the Pyroscope instrumentation library, that now preserves the values of baggage header provided to request and appends k6 metadata to it instead of overriding.

Closes #151

  • Use a meaningful title for the Pull Request. Include the name of the jslib added/modified.
  • Fill the description section of the Pull Request.
  • Test the change in your code, and ensure the npm run test command succeeds.
  • Run yarn run generate-homepage locally and verify the new homepage /lib/index.html file looks legit.
  • The Pull Request is labeled with the version bump label.
  • The Pull Request adds a /lib/{jslib_name}/{desired_version} folder.
  • The Pull Request adds a /lib/{jslib_name}/{desired_version}/index.js file containing the jslib's code bundle.
  • The Pull Request updates the supported.json file to contain an entry for the newly added jslib version
  • The Pull Request adds the relevant tests to the /tests/basic.js and /tests/testSuite.js files to ensure that the new version of the jslib is importable and runnable by k6.
  • Merge the Pull Request once it is green. PRs adding new jslib versions do not require to get a review to be merged 🚀.

Comment on lines +73 to +87
// capture the original values late, so that they include any previously made instrumentation changes
const currentRequest = http.request;
const currentAsyncRequest = http.asyncRequest;

const client = new Client(null, currentRequest, currentAsyncRequest);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the main change compared to the previous version. We capture http.request and http.asyncRequest during the instrumentation phase to make sure we use the latest version of their methods.

Comment on lines +180 to +183
// capture the original values late, so that they include any previously made instrumentation changes
const currentRequest = http.request;
const currentAsyncRequest = http.asyncRequest;

const client = new Client(opts, currentRequest, currentAsyncRequest);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Similar to the above, this is the main change compared to the previous version.

Copy link
Copy Markdown
Contributor

@oleiade oleiade left a comment

Choose a reason for hiding this comment

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

🚀

@mstoykov
Copy link
Copy Markdown
Contributor

This would fix the concrete problem, but does introduce now a ... different problem, which might be less problematic in a real situation.

But first - please remember to update the docs in https://grafana.com/docs/k6/latest/javascript-api/jslib/http-instrumentation-tempo/client/ and for pyroscope.

This changes also mean that to use the Client you now need to provide the request and asyncRequest parameters which make it harder to use. I do expect most users to potentially not use that , but still.

But the bigger problem is that now calling instrumentHttp any time after the first time will not have any effect. Well it will call more functions, but then the header will be overriden by the first caller. I do not know if anyone is using this to send different stuff or to change the sampling rate (the more likely case).

But if it isn't going to work, I would propose that we actually throw and exception on second call 🤷

This will also get more complicated if you use both and you call instrumentHTTP for both tempo and pyroscope and then you want ot override one or the other in some different orders.

@andrewslotin
Copy link
Copy Markdown
Contributor Author

@mstoykov, these are fair points! I've pushed changes to retain current signatures of the Client class for both instrumentations. Now both request and asyncRequest are optional and respective values from k6/http will be used as defaults.

Regarding calling instrumentHttp() multiple times, I'd argue this is a user issue and if we want to address it, let's do this outside of the scope of this PR.

@andrewslotin andrewslotin force-pushed the make_tempo_and_pyroscope_compatible branch from 8af00dd to 139339c Compare April 17, 2025 15:20
// event params would be nullish, we'll instantiate
// a new object.
if (args[1] == null) args[1] = {}
args[1].headers = mergeHeaders(args[1].headers || {}, headers)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Another fix to preserve the existing baggage header values. Instead of overriding, we just merge two sets of key-value pairs.

@andrewslotin
Copy link
Copy Markdown
Contributor Author

@mstoykov, PTAL, I've updated Pyroscope instrumentation to preserve baggage header values provided to request and also added proper tests for both instrumentations.

@mstoykov
Copy link
Copy Markdown
Contributor

I am not certain merging baggage is good idea, but I guess if instrumentHttp is nto supposed to be callable multiple times, it wouldn't really matter.

I do think we probably should split this in a new repo if we are going to do more changes to it so we can better track changes. I had to check this out locally and then look at diffs locally between files. In this case arguably the change is big enough that this was worth it , but for some small change it seems a bit much.

@mstoykov mstoykov merged commit 63abede into main Apr 25, 2025
4 checks passed
@andrewslotin andrewslotin deleted the make_tempo_and_pyroscope_compatible branch May 2, 2025 09:25
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.

Tempo instrumentation conflicts with the Pyroscope instrumentation

3 participants