Skip to content

Add Implementation of the open-tracing interceptor using gRPC interceptor.#14

Open
zhyon404 wants to merge 13 commits into
opentracing-contrib:masterfrom
zhyon404:master
Open

Add Implementation of the open-tracing interceptor using gRPC interceptor.#14
zhyon404 wants to merge 13 commits into
opentracing-contrib:masterfrom
zhyon404:master

Conversation

@zhyon404
Copy link
Copy Markdown

No description provided.

@rnburn
Copy link
Copy Markdown
Collaborator

rnburn commented Oct 1, 2018

Could we remove the existing interceptor code? I don't think we'd want two implementations.

@zhyon404
Copy link
Copy Markdown
Author

zhyon404 commented Oct 2, 2018

We could, of course this will loss backward compatible, but I agree that only one implementation is better. Do you want me to do this?

@zhyon404 zhyon404 force-pushed the master branch 2 times, most recently from f6d6696 to b4bdc7c Compare October 2, 2018 07:09
@rnburn
Copy link
Copy Markdown
Collaborator

rnburn commented Oct 4, 2018

Yes, we can bump the major version to indicate it's not backward compatible.

@wenbochang
Copy link
Copy Markdown

Thank you so much for this!

@carlosalberto carlosalberto self-requested a review October 31, 2018 00:04
@zhyon404
Copy link
Copy Markdown
Author

basically done. not writing much test though

Comment thread .circleci/config.yml Outdated
command: |
. venv/bin/activate
python setup.py test
python3 setup.py test
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we really need to run Python 3 here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I tried, using python works now.

Comment thread README.md Outdated

See the below code for basic usage or [examples/trivial](examples/trivial) for a
complete example.
using official grpc interceptor
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we could leave the original line ("See the below code...") and also mention this new note at the end of the paragraph ;)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed.

Comment thread README.md
tracer_interceptor = 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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

Comment thread README.md

On the server-side, the `context` argument passed into your service methods
packages the gRPC span created on the server-side.
from grpc_opentracing import scope
Copy link
Copy Markdown
Contributor

@carlosalberto carlosalberto Jan 11, 2019

Choose a reason for hiding this comment

The 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 (ScopeManager)...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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.

Comment thread setup.py Outdated
author='LightStep',
license='',
install_requires=['opentracing>=1.2.2', 'grpcio>=1.1.3', 'six>=1.10'],
install_requires=['opentracing>=1.2.2', 'grpcio>=1.8.1', 'six>=1.10'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Interceptors exists within grpc exactly since 1.8.1?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I checked it's 1.8.0. And changed the requirement.

def test_constructor_default(self):
interceptor = client_interceptor.OpenTracingClientInterceptor(Tracer(), True)
self.assertIsNotNone(interceptor._tracer)
self.assertTrue(interceptor._log_payloads)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Think there are other ways to test more into detail the new code?

If you don't have more time slots to spend on this, adding a TODO list for the tests or adding a note somewhere related to this would help ;)

Comment thread README.md Outdated
from grpc_opentracing import open_tracing_client_interceptor
from grpc_opentracing.grpcext import intercept_channel
import grpc
from grpc_opentracing.grpc_interceptor import client_interceptor
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Trying to stay as compatible as before, I'd suggest exposing this new client_interceptor with the same name we had for the old one, i.e.

# __init__.py
from grpc_interceptor import client_interceptor as open_tracing_ client_interceptor # old name, kept even if as deprecated
from grpc_interceptor import client_interceptor # the actual name of the new object

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh, and the same would go for server_interceptor ;)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

@carlosalberto
Copy link
Copy Markdown
Contributor

Hey @zhyon404 thanks for crafting all these changes! Definitely nice to finally use the official interceptor layer ;)

I left a few comments for you - let me know your thoughts. If you are busy with other stuff let me know, so I can help with this.

(And sorry for the delayed feedback!)

@zhyon404
Copy link
Copy Markdown
Author

Hey @carlosalberto, I added some changes according to your advice, I'm kind busy in next week, so it would be great if can help.

@corleyma
Copy link
Copy Markdown

corleyma commented Aug 1, 2019

@zhyon404 @carlosalberto Any plans to push this PR over the line? Is there anything I can do to help?

@inquire
Copy link
Copy Markdown

inquire commented Dec 3, 2019

Is there anything in here that is not ok? This will make the code and unit tests for interceptor servers so much easier :D

Comment on lines +100 to +101
scope.set_active_span(current_span)
scope.end_span()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this doesn't quite work they way it might be expected. I believe you need to pass the original span from before when you create a new one at https://github.com/opentracing-contrib/python-grpc/pull/14/files#diff-4ecafa65ccad14bb230575320502f261R57

The reason for this is that otherwise if there are further gRPC calls issued by the calling code after this point before it explicitly creates a new span each of these calls will appear as though the previous gRPC was it's parent.

e.g.

 - start tracer span
         |
         \--- client grpc call 1
                     |--- server grpc function 1
                     |            \--- ... other tracing calls in server
                     \--- client grpc call 2
                                 |--- server grpc function 2
                                 |            \--- ... other tracing calls in server
                                 \--- client grpc call 3
                                              \--- server grpc function 3
                                                           \--- ... other tracing calls in server

instead of

 - start tracer span
         |
         |--- client grpc call 1
         |            \--- server grpc function 1
         |                          \--- ... other tracing calls in server
         |--- client grpc call 2
         |            \--- server grpc function 2
         |                          \--- ... other tracing calls in server
         \--- client grpc call 3
                       \--- server grpc function 3
                                     \--- ... other tracing calls in server

So the function should take two arguments def _callback(self, current_span, original_span): and then do current_span.finish() followed by scope.set_active_span(original_span). Since you want to finish the current span, but when exiting the grpc interceptor back to the program code the active span should be set back to what it was before the interceptor was called.

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.

7 participants