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

Adding psycopg2 integration #298

Merged
merged 11 commits into from
Jan 22, 2020

Conversation

hectorhdzg
Copy link
Member

Took OpenCensus implementation as starting point for this one, we store more properties in traces now and we use tracer provided during trace_integration method

https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-postgresql

psycopg docs
http://initd.org/psycopg/docs/index.html

#265


wrapt.wrap_function_wrapper(psycopg2, "connect", wrap)

class TraceCursor(pgcursor):
Copy link
Member

Choose a reason for hiding this comment

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

Why doesn't this use opentelemetry-ext-dbapi from #264? Did you run into the issue I described in https://github.com/open-telemetry/opentelemetry-python/pull/264/files#r348452864? In any case, instead of deriving from pgcursor, you might want to use a wrapt ObjectProxy https://wrapt.readthedocs.io/en/latest/wrappers.html#object-proxy. That way, you could implement a generic solution. Or you could add support for such cursor_factory instrumentations to ext-dbapi.

Another question: What happens if the user manually specifies/sets cursor_factory? Will either our or the user's cursor_factory be ignored?

Copy link
Member Author

@hectorhdzg hectorhdzg Nov 20, 2019

Choose a reason for hiding this comment

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

I based this in current OpenCensus implementation and started working with this before adding dbapi in other PR, makes sense to reuse it as much as possible, cursor_factory in fact will be overriden like you mentioned and is current behavior in OpenCensus, filed a bug for it in OpenCensus and ensure it doesn't happen here

census-instrumentation/opencensus-python#821

Copy link
Member Author

@hectorhdzg hectorhdzg Nov 20, 2019

Choose a reason for hiding this comment

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

cursor_factory is a not thing in the Python DB API specification, so I guess it doesn't makes sense to add it in dbapi ext, dbapi ext is currently wrapping connect method, the actual connection and the cursor, in psycopg all of these are implemented in C except connect, that is why we are hooking up to the cursor_factory, so I'm still not sure how we can reuse dbapi ext here, any suggestion would be appreciated.

Using ObjectProxy instead of pgcursor sounds like a good approach

Copy link
Member

Choose a reason for hiding this comment

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

I think this could be an extension of the DBAPI PR. looking at the chunk that actually starts a span and sets values, it's very similar to the DBApi functionality.

Although one caveat as a con is the fact that the API is slightly different in that psycopg2 accepts sql.SQL objects rather than just strings, but that could reconciled with a light wrapper on all of them.

ultimately this is an auto-instrumentation though, so as long as we don't expose APIs that people may rely on, we can probably feel safe marking this as a potential refactor.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated the code to use dbapi ext as much as possible, including span attributes related to connection population and actual span creation functionality

@a-feld a-feld removed their request for review December 10, 2019 00:54
@hectorhdzg hectorhdzg added the WIP Work in progress label Dec 12, 2019
@hectorhdzg
Copy link
Member Author

I would like to reuse dbapi package being added here #264, I will update this PR once is available

Copy link
Member

@toumorokoshi toumorokoshi left a comment

Choose a reason for hiding this comment

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

Overall code looks good, things that are blockers IMO are:

  • no basic unit test
  • no handling of more complex objects as the first argument of the execute call, which will lead to a casting exception.

# limitations under the License.
#
[metadata]
name = opentelemetry-ext-postgresql
Copy link
Member

Choose a reason for hiding this comment

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

is this the right name for the package? I guess there's a few different DBAPI options available: https://docs.sqlalchemy.org/en/13/dialects/postgresql.html

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated to psycopg2


wrapt.wrap_function_wrapper(psycopg2, "connect", wrap)

class TraceCursor(pgcursor):
Copy link
Member

Choose a reason for hiding this comment

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

I think this could be an extension of the DBAPI PR. looking at the chunk that actually starts a span and sets values, it's very similar to the DBApi functionality.

Although one caveat as a con is the fact that the API is slightly different in that psycopg2 accepts sql.SQL objects rather than just strings, but that could reconciled with a light wrapper on all of them.

ultimately this is an auto-instrumentation though, so as long as we don't expose APIs that people may rely on, we can probably feel safe marking this as a potential refactor.

@hectorhdzg hectorhdzg requested a review from a team January 3, 2020 21:18
@hectorhdzg hectorhdzg added ext needs reviewers PRs with this label are ready for review and needs people to review to move forward. tracing and removed WIP Work in progress labels Jan 6, 2020
@hectorhdzg
Copy link
Member Author

@toumorokoshi and @Oberon00 I updated this to consume dbapi ext, added basic integration test, this would be super easy to test with functional tests similar to #340 would be happy to add them using similar approach, let me know if you have more feedback

@codecov-io
Copy link

codecov-io commented Jan 7, 2020

Codecov Report

Merging #298 into master will increase coverage by 0.3%.
The diff coverage is 92.07%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master     #298     +/-   ##
=========================================
+ Coverage   84.82%   85.13%   +0.3%     
=========================================
  Files          38       38             
  Lines        1839     1911     +72     
  Branches      217      225      +8     
=========================================
+ Hits         1560     1627     +67     
- Misses        214      219      +5     
  Partials       65       65
Impacted Files Coverage Δ
...-ext-flask/src/opentelemetry/ext/flask/__init__.py 88.88% <100%> (ø) ⬆️
opentelemetry-api/src/opentelemetry/util/types.py 100% <100%> (ø) ⬆️
...emetry-sdk/src/opentelemetry/sdk/trace/__init__.py 90.94% <100%> (+1.06%) ⬆️
...ry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py 68.18% <33.33%> (ø) ⬆️
...ntelemetry-api/src/opentelemetry/trace/__init__.py 84.56% <89.36%> (+0.44%) ⬆️
...elemetry-api/src/opentelemetry/metrics/__init__.py 87.93% <90.9%> (+1.93%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ee0682...2dc0671. Read the comment docs.

with mock.patch("psycopg2.connect"):
trace_integration(tracer)
cnx = psycopg2.connect(database="test")
self.assertIsNotNone(cnx.cursor_factory)
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the test for trace_integration should include to see if the functions are successfully decorated.
As well, the query functions themselves and the Cursor should also have tests.
See OpenCensus

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm only decorating the connect method and this will add the cursor factory, not sure if wrapt will add some "decorated" property, psycopg2 internally will instantiate PsycopgTraceCursor that just call dbapi traced_execution that is already tested, unit tests are hard in here because if the mixed Python/c execution, I believe functional tests would be way more useful and easier to implement, did't want to add them yet until #340 is complete and people are ok with that kind of approach

Copy link
Contributor

@lzchen lzchen left a comment

Choose a reason for hiding this comment

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

LGTM save the basic unit tests.

@lzchen
Copy link
Contributor

lzchen commented Jan 13, 2020

@hectorhdzg FYI [#360]

Copy link
Member

@toumorokoshi toumorokoshi left a comment

Choose a reason for hiding this comment

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

LGTM! Sounds good on deeper testing when the functional testing pattern is added in.

@toumorokoshi
Copy link
Member

@hectorhdzg looks good! Can you resolve conflicts (looks like there was some styling stuff on the readmes that conflict with master) and then I can merge?

@toumorokoshi toumorokoshi removed the needs reviewers PRs with this label are ready for review and needs people to review to move forward. label Jan 20, 2020
@hectorhdzg hectorhdzg added the PR:please merge This PR is ready to be merged by a Maintainer (has enough valid approvals, successful build, etc.) label Jan 21, 2020
@toumorokoshi toumorokoshi merged commit a40edf5 into open-telemetry:master Jan 22, 2020
@c24t c24t removed the PR:please merge This PR is ready to be merged by a Maintainer (has enough valid approvals, successful build, etc.) label Jan 29, 2020
toumorokoshi pushed a commit to toumorokoshi/opentelemetry-python that referenced this pull request Feb 17, 2020
@hectorhdzg hectorhdzg deleted the hectorhdzg/postgres branch March 24, 2020 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants