-
Notifications
You must be signed in to change notification settings - Fork 98
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
Add support for Python. #32
Conversation
So glad to see Python support coming in. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the insane delay – did not know this was here. :-/
python/README.md
Outdated
|
||
```python | ||
tracer = # some OpenTracing Tracer instance | ||
interceptor = open_tracing_client_interceptor(tracer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is there this helper function instead of just initializing an OpenTracingClientInterceptor directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was to be consistent with the rest of gRPC where the __init__.py
file only exposes interface classes and uses functions to construct concrete classes. (See for example the server function that does the same thing.)
Not entirely sure, but I would guess the reasons for this are to keep the documentation in a single location and to have a convention that allows easily supporting additional constructor functions if needed.
python/README.md
Outdated
|
||
```python | ||
tracer = # some OpenTracing Tracer instance | ||
interceptor = open_tracing_server_interceptor(tracer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same)
|
||
### Server-side usage example | ||
|
||
```python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's include import statements in these two examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added import statements.
|
||
## Usage | ||
``` | ||
python integration_server.py --access_token `lightstep-access-token` & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better to support Jaeger's (OSS) library here... it can run in a single local docker image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Will switch the examples to use Jaeger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the examples use Jaeger now.
python/examples/store/README.md
Outdated
|
||
## Usage | ||
``` | ||
python store_server.py --access_token `lightstep-access-token` & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same comment about Jaeger)
import argparse | ||
|
||
import grpc | ||
from jaeger_client import Config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't some sort of dependency need to be added to setup.py or similar for this to work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a requirements.txt file in the example directory that includes jaeger-client as an dependency.
python/grpc_opentracing/_server.py
Outdated
# updates the span accordingly. | ||
def _check_error_code(span, servicer_context): | ||
if servicer_context.code != grpc.StatusCode.OK: | ||
span.set_tag('error', True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this is defined symbolically here: https://github.com/opentracing/opentracing-python/blob/master/opentracing/ext/tags.py#L47
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed to use the constants in opentracing.ext.tags available in opentracing-1.2.2, but tags.ERROR was added for opentracing-1.2.3 which hasn't been released yet.
python/grpc_opentracing/__init__.py
Outdated
"""Creates a service-side interceptor that can be use with gRPC to add | ||
OpenTracing information. | ||
|
||
Args: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing a comment for traced_attributes
python/grpc_opentracing/__init__.py
Outdated
def open_tracing_client_interceptor(tracer, | ||
active_span_source=None, | ||
log_payloads=False, | ||
traced_attributes=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no comment provided for this param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tracer_attributes is documented now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thinking more deeply about this, IMO it might be better to express this functionality as a SpanDecorator function that gives the caller the flexibility to modify the RPC Span in any way (and provides RPC context information like headers, method type/name, deadline, etc in the decorator function arguments somehow).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I'll make that change. It was mostly done this way just to match the Java version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the traced_attributes options and added a span_decorator that can be used instead.
How would you suggest integrating this with https://github.com/uber-common/opentracing-python-instrumentation? Right now I am doing something like this (to get redis and sqlalchemy in the trace): from opentracing_instrumentation.request_context import RequestContextManager
...
class CommandLine(command_line_pb2.CommandLineServicer):
def Echo(self, request, context):
with RequestContextManager(span=context.get_active_span()):
_check_redis_cache()
_make_db_query()
return command_line_pb2.CommandResponse(text=request.text) But I feel like there is a better solution. |
@wkiser There is a PR being worked on to add active span management to the Python OpenTracing API. Once that's in place, I'd expect the code to be updated to make use of it and in-process propagation between different frameworks would hopefully be more seamless. But I'm not sure what could be improved until that's done. |
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
Thanks for this! I totally stole the server interceptor and used it for an unrelated reason. Well, it is actually slightly related: I just want to log start/end of requests for debugging purposes. This is an extremely lightweight version of tracing :) worked like a charm. Looking forward to something like this landing in grpc proper. |
@rnburn out of curiosity, is there a timeline for when that PR would get merged (are there dependencies / blockers)? |
@lapointexavier we were hoping that grpc would add python interceptors so that we wouldn't have to mutate the grpc objects. Given that that is in limbo, we should probably merge this. |
I think @bhs is the only one with write access to merge this -- were there any other concerns? |
I think people might be waiting on the PR for interceptors in gRPC to get merged. That being said, I wouldn't mind this getting merged in the meantime since I am also running off of a hand generated wheel. |
I don't see any reason not to ship what we have and add support for gRPC's own interceptor's in a later version. Even if that PR were to move today (which it won't), it would take a while for those changes to roll out to the various gRPC packages that most people are using, so having a version of this that can work with older version of gRPC makes a lot of sense to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merging seems like a definite improvement over non-merging. :) Looking forward to a core GRPC API that makes interceptors cleaner in python, though. Thanks!
This PR adds interceptors to support OpenTracing with Python. Unfortunately, gRPC doesn't provide any direct support for Python interceptors so the PR includes a submodule (grpcext) that implements interceptors on top of gRPC's Channel and Server APIs.