Skip to content

Fix tracing of async cursors for psycopg #3324

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ibash
Copy link

@ibash ibash commented Mar 4, 2025

Description

This copies the traced_execution of AsyncCursorTracer except query_method is awaited within the span.

Fixes #2486

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

I ran this locally by making the corresponding changes in my site-packages folder. Then I checked logfire (what we're using for opentelemetry) to confirm that sql queries now had non-zero timings.

Also ran the tox command to run tests.

Happy to build and test the built package if you tell me how to build!

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • [-] Changelogs have been updated
  • [-] Unit tests have been added
  • [-] Documentation has been updated

Copy link

linux-foundation-easycla bot commented Mar 4, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@ibash
Copy link
Author

ibash commented Mar 5, 2025

@federicobond would love a review when you get a chance!

Copy link

@emilingerslev emilingerslev left a comment

Choose a reason for hiding this comment

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

I've validated that this indeed solves the problem. Only concern here is minor; The override of traced_execution changes the signature from sync to async, effectively also changing the return type. Another option is to extend CursorTracer with a traced_execution_async method, keeping it all in one class, but supporting both.

But as I said this works ✅

This copies the traced_execution of AsyncCursorTracer except
query_method is awaited within the span.

Fixes open-telemetry#2486
@ibash ibash force-pushed the ibash/async_tracing branch from ecea87a to 71f50a7 Compare March 25, 2025 18:20
@xrmx
Copy link
Contributor

xrmx commented Mar 27, 2025

I've validated that this indeed solves the problem. Only concern here is minor; The override of traced_execution changes the signature from sync to async, effectively also changing the return type. Another option is to extend CursorTracer with a traced_execution_async method, keeping it all in one class, but supporting both.

Thanks for testing. Not sure I follow the return type concern, AFAIU the users of that _cursor_tracer are awaiting it so the fact it was not an async function was the issue?

Copy link
Contributor

@xrmx xrmx left a comment

Choose a reason for hiding this comment

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

I think we are missing tests to avoid regressions in the future

@ibash
Copy link
Author

ibash commented Apr 7, 2025

@xrmx sorry for the delay here -- added a regression test. Please let me know if there's a better way to assert this behavior.

@ibash ibash requested a review from xrmx April 7, 2025 17:16
async def test_tracing_is_async(self):
PsycopgInstrumentor().instrument()

# before this async fix cursor.execute would take 14000 ns, delaying for
Copy link
Contributor

@xrmx xrmx Apr 10, 2025

Choose a reason for hiding this comment

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

I don't understand why we need a delay and an inner test_async_connection. Also since you had to update it, aren't we testing MockAsyncCursor?

Copy link
Author

Choose a reason for hiding this comment

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

I wasn't sure how to assert that the coroutine was await otherwise. (versus the span completing before execution is finished).

This does use MockAsyncCursor, but it's testing that AsyncCursorTracer is awaiting the result of MockAsyncCursor.execute.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, but here we are testing the mocks and not the real code. Would it be possible to test the connection cursor_factory we get from instrument_connection ?

Copy link
Author

Choose a reason for hiding this comment

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

This tests the real code. The test is for the tracer class AsyncCursorTracer. It doesn’t matter what Cursor class the test uses.

@ibash ibash requested review from xrmx and emilingerslev April 16, 2025 22:21
else:
# no sqlcomment anywhere
self._populate_span(span, cursor, *args)
return await query_method(*args, **kwargs)
Copy link
Author

Choose a reason for hiding this comment

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

@xrmx this is what the bugfix is for, the await was missing before

@jwilm
Copy link

jwilm commented May 19, 2025

Thanks @ibash for this PR and @xrmx for your reviews. I'm eager to see this PR land and published; is there anything I can do to help?

@ibash
Copy link
Author

ibash commented May 19, 2025

@jwilm not ideal but I did publish the patched version to github, in our requirements.txt we use:

opentelemetry-instrumentation-fastapi==0.52b1
opentelemetry-instrumentation-psycopg @ https://github.com/ibash/opentelemetry-python-contrib/releases/download/v52b1/opentelemetry_instrumentation_psycopg-0.52b1-py3-none-any.whl

Adds a test to check that the async tracer is actually awaiting
cursor.execute.

On my machine, with the bug present, the duration is 14000ns. With the
bug patched the the duration is orders of magnitude larger.
@ibash ibash force-pushed the ibash/async_tracing branch from 2fcd49d to 0d8cd74 Compare June 2, 2025 18:03
@ibash
Copy link
Author

ibash commented Jun 2, 2025

@xrmx fixed the formatting issue -- any chance this can get reviewed / merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

opentelemetry-instrumentation-psycopg claims to work for async queries, but doesn't record time
5 participants