-
Notifications
You must be signed in to change notification settings - Fork 27
Add Implementation of the open-tracing interceptor using gRPC interceptor. #14
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
base: master
Are you sure you want to change the base?
Changes from all commits
b4bdc7c
c63dde6
f6e6d85
2e82106
0893c8d
165d306
22cf5e2
30ed3cb
300d7c0
a6a3085
a12b8ad
d56d10c
c517c49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,64 +11,46 @@ pip install grpcio-opentracing | |
|
|
||
| ## Getting started | ||
|
|
||
| See the below code for basic usage or [examples/trivial](examples/trivial) for a | ||
| See the below code for basic usage or [examples/hello_world](examples/hello_world) for a | ||
| complete example. | ||
|
|
||
| ### Client-side usage example | ||
|
|
||
| ```python | ||
| import grpc | ||
| from grpc_opentracing import open_tracing_client_interceptor | ||
| from grpc_opentracing.grpcext import intercept_channel | ||
|
|
||
| tracer = # some OpenTracing Tracer instance | ||
| interceptor = open_tracing_client_interceptor(tracer) | ||
| tracer_interceptor = open_tracing_client_interceptor.OpenTracingClientInterceptor(tracer) | ||
| channel = # the grpc.Channel you created to invoke RPCs | ||
| channel = intercept_channel(channel, interceptor) | ||
| channel = grpc.intercept_channel(channel, tracer_interceptor) | ||
|
|
||
| # All future RPC activity involving `channel` will be automatically traced. | ||
| ``` | ||
|
|
||
| ### Server-side usage example | ||
|
|
||
| ```python | ||
| import grpc | ||
| from concurrent import futures | ||
| from grpc_opentracing import open_tracing_server_interceptor | ||
| from grpc_opentracing.grpcext import intercept_server | ||
|
|
||
| tracer = # some OpenTracing Tracer instance | ||
| interceptor = open_tracing_server_interceptor(tracer) | ||
| server = # the grpc.Server you created to receive RPCs | ||
| server = intercept_server(server, interceptor) | ||
|
|
||
| tracer_interceptor = open_tracing_server_interceptor.OpenTracingServerInterceptor(tracer) | ||
| server = grpc.server( | ||
| futures.ThreadPoolExecutor(max_workers=10), | ||
| interceptors=(tracer_interceptor,)) | ||
| # All future RPC activity involving `server` will be automatically traced. | ||
| ``` | ||
|
|
||
| ### Integrating with other spans. | ||
|
|
||
| `grpcio-opentracing` provides features that let you connect its span with other | ||
| tracing spans. On the client-side, you can write a class that derives from | ||
| `ActiveSpanSource` and provide it when creating the interceptor. | ||
|
|
||
| ```python | ||
| class CustomActiveSpanSource(ActiveSpanSource): | ||
| @classmethod | ||
| def get_active_span(self): | ||
| # your custom method of getting the active span | ||
| tracer = # some OpenTracing Tracer instance | ||
| interceptor = open_tracing_client_interceptor( | ||
| tracer, | ||
| active_span_source=CustomActiveSpanSource) | ||
| ... | ||
| ``` | ||
|
|
||
| On the server-side, the `context` argument passed into your service methods | ||
| packages the gRPC span created on the server-side. | ||
|
|
||
| ```python | ||
| class CustomRpcService(...): | ||
| ... | ||
| def Method1(self, request, context): | ||
| span = context.get_active_span() | ||
| ... | ||
| ``` | ||
| from grpc_opentracing import scope | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have mixed feelings about this, as this will probably get discarded anyway in favor of the OT 2.0 API (
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked into current OT ScopeManager when I wrote this, and thinking it not meet the need. If we can use OT 2.0 API (ScopeManager) would be great. |
||
|
|
||
| See [examples/integration](examples/integration) for a complete example. | ||
| span = scope.get_active_span() | ||
| span = tracer.start_span("do some thing", child_of=span) | ||
| # do some thing | ||
| span.finish() | ||
| ... | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| option java_multiple_files = true; | ||
| option java_package = "io.grpc.examples.helloworld"; | ||
| option java_outer_classname = "HelloWorldProto"; | ||
|
|
||
| package helloworld; | ||
|
|
||
| // The hello world service definition. | ||
| service Greeter { | ||
| // Say hello to the request sender (unary-unary) | ||
| rpc SayHello (HelloRequest) returns (HelloReply) {} | ||
| } | ||
|
|
||
| // The request message containing the sender's name. | ||
| message HelloRequest { | ||
| string name = 1; | ||
| } | ||
|
|
||
| // The response message containing the greetings | ||
| message HelloReply { | ||
| string message = 1; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| from __future__ import print_function | ||
|
|
||
| import argparse | ||
| import time | ||
|
|
||
| import grpc | ||
| from jaeger_client import Config | ||
|
|
||
| import hello_world_pb2 | ||
| import hello_world_pb2_grpc | ||
| from grpc_opentracing import open_tracing_client_interceptor | ||
| from grpc_opentracing import scope | ||
|
|
||
| HOST_PORT = 'localhost:50051' | ||
|
|
||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser() | ||
| parser.add_argument( | ||
| '--log_payloads', | ||
| action='store_true', | ||
| default=True, | ||
| help='log request/response objects to open-tracing spans') | ||
| args = parser.parse_args() | ||
|
|
||
| config = Config( | ||
| config={ | ||
| 'sampler': { | ||
| 'type': 'const', | ||
| 'param': 1, | ||
| }, | ||
| 'logging': True, | ||
| }, | ||
| service_name='hello_world_client') | ||
| tracer = config.initialize_tracer() | ||
| tracer_interceptor = open_tracing_client_interceptor.OpenTracingClientInterceptor( | ||
| tracer, | ||
| log_payloads=args.log_payloads) | ||
| with tracer.start_span("step1") as span: | ||
| scope.set_active_span(span) | ||
| time.sleep(0.01) | ||
| channel = grpc.insecure_channel(HOST_PORT) | ||
| channel = grpc.intercept_channel(channel, tracer_interceptor) | ||
| stub = hello_world_pb2_grpc.GreeterStub(channel) | ||
| response = stub.SayHello(hello_world_pb2.HelloRequest(name='you')) | ||
| print("Message received: " + response.message) | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| main() |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! | ||
| import grpc | ||
|
|
||
| import hello_world_pb2 as hello__world__pb2 | ||
|
|
||
|
|
||
| class GreeterStub(object): | ||
| """The hello world service definition. | ||
| """ | ||
|
|
||
| def __init__(self, channel): | ||
| """Constructor. | ||
|
|
||
| Args: | ||
| channel: A grpc.Channel. | ||
| """ | ||
| self.SayHello = channel.unary_unary( | ||
| '/helloworld.Greeter/SayHello', | ||
| request_serializer=hello__world__pb2.HelloRequest.SerializeToString, | ||
| response_deserializer=hello__world__pb2.HelloReply.FromString, | ||
| ) | ||
|
|
||
|
|
||
| class GreeterServicer(object): | ||
| """The hello world service definition. | ||
| """ | ||
|
|
||
| def SayHello(self, request, context): | ||
| """Say hello to the request sender (unary-unary) | ||
| """ | ||
| context.set_code(grpc.StatusCode.UNIMPLEMENTED) | ||
| context.set_details('Method not implemented!') | ||
| raise NotImplementedError('Method not implemented!') | ||
|
|
||
|
|
||
| def add_GreeterServicer_to_server(servicer, server): | ||
| rpc_method_handlers = { | ||
| 'SayHello': grpc.unary_unary_rpc_method_handler( | ||
| servicer.SayHello, | ||
| request_deserializer=hello__world__pb2.HelloRequest.FromString, | ||
| response_serializer=hello__world__pb2.HelloReply.SerializeToString, | ||
| ), | ||
| } | ||
| generic_handler = grpc.method_handlers_generic_handler( | ||
| 'helloworld.Greeter', rpc_method_handlers) | ||
| server.add_generic_rpc_handlers((generic_handler,)) |
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.
👍