-
Notifications
You must be signed in to change notification settings - Fork 104
WIP: Opencensus integration #613
Conversation
ClientContext gets a TracerFactory, which (for the time being) is set to a dummy factory. To enable tracing OpenCensusTracerFactory can be used. In the future, OpenCensusTracerFactory will become the default. TracerFactory will be used by outer Callables to create new Tracers ApiCallContext will be used to carry the Tracers through the callable chains to annotate the spans represented by the Tracers
Codecov Report
@@ Coverage Diff @@
## master #613 +/- ##
============================================
- Coverage 75.03% 70.01% -5.03%
- Complexity 935 957 +22
============================================
Files 177 190 +13
Lines 4090 4492 +402
Branches 323 334 +11
============================================
+ Hits 3069 3145 +76
- Misses 869 1192 +323
- Partials 152 155 +3
Continue to review full report at Codecov.
|
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 did not review the actual implementations for TracedCallables (as it is probably too early to do it). Please let me know if you want those to be carefully reviewed as well.
About the 4 specific questions:
Tracerinterface is fine, maybe exceptTypeenum in it (please see the corresponding comment for details).- Please avoid the duplication of
TimedAttemptSettingsstuff at all cost (please check the corresponding comment inOpencensusTracerclass). I'm not strictly opposed to the statefulness of the tracer, but I'm opposed to duplicating in it the state of other objects, because there would be no guarantee that the reported values are the actual values. gax.tracing.package is fine (we are already structured as package-by-feature). As forTraced*Callables, please check the comment inGrpcCallableFactory(I think it is ok to just not have them at all, and merge all the tracing stuff into existing callables).couldRetry- I really don't like it (especially when there isshouldRetrynext to it). It looks like you can avoid declaring this method (and in a way, which will give you more flexibility in terms of reporting). Please check the corresponding comments for details.
| setAttemptResult(throwable, response, true); | ||
| // a new attempt will be (must be) scheduled by an external executor | ||
| } else if (throwable != null) { | ||
| if (retryAlgorithm.couldRetry(throwable, response)) { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| * @param prevResponse response returned by the previous attempt or null if an exception was | ||
| * thrown instead | ||
| */ | ||
| public boolean couldRetry(Throwable prevThrowable, ResponseT prevResponse) { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| import org.threeten.bp.Duration; | ||
|
|
||
| public interface Tracer { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| import org.threeten.bp.Duration; | ||
|
|
||
| public interface Tracer { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| import org.threeten.bp.Duration; | ||
|
|
||
| public interface Tracer { |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
|
||
| void connectionSelected(int id); | ||
|
|
||
| void startAttempt(); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| } | ||
|
|
||
| enum Type { | ||
| Unary(false, false), |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| try { | ||
| context = context.withTracer(tracer); | ||
| ApiFuture<ResponseT> future = innerCallable.futureCall(request, context); | ||
| ApiFutures.addCallback(future, finisher, MoreExecutors.directExecutor()); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| UnaryCallable<RequestT, ResponseT> callable = | ||
| createBaseUnaryCallable(grpcCallSettings, callSettings, clientContext); | ||
|
|
||
| callable = |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
| private int attempts = 0; | ||
| private long attemptRequests = 0; | ||
| private long attemptResponses = 0; | ||
| private long totalAttemptRequests = 0; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
Thanks for reviewing, I will incorporate most of the suggestions over the coarse of the week. However there are couple things that I think I need to keep:
|
This is extracted from googleapis#613 (comment). Currently for streaming RPCs TimedAttemptSettings only tracks how many attempts occurred trying to receive the next message. Once the message is received, the attempt count is reset. This adds a new field to TimedAttemptSettings that will track overall count so that it can be used in a future integration with opencensus (or be used in a new retry algorithm)
This has been extracted from googleapis#613 This doesn't provide any extra functionality. Instead it just sets up the foundation for integrating tracing in to gax. The general idea is to add a tracing abstraction layer that all parts of gax can call into. This is accomplished by introducing - ApiTracer interface that has methods for all annotations that a span should contain - ApiTracerFactory interface: since an ApiTracer is stateful and has a 1:1 mapping with operations, a factory is introduced to cleanly switch implementations of the tracer By default a NoopApiTracerFactory is configured that will return NoopApiTracers. In the future a parallel OpenCensusApiTracerFactory will be added. A client implementation will be able to opt into tracing by setting the factory in StubSettings. The actual ApiTracer will be propagated by CallContext.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedUnaryCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedServerStreamingCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedClientStreamCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
* Add plumbing for tracing This has been extracted from #613 This doesn't provide any extra functionality. Instead it just sets up the foundation for integrating tracing in to gax. The general idea is to add a tracing abstraction layer that all parts of gax can call into. This is accomplished by introducing - ApiTracer interface that has methods for all annotations that a span should contain - ApiTracerFactory interface: since an ApiTracer is stateful and has a 1:1 mapping with operations, a factory is introduced to cleanly switch implementations of the tracer By default a NoopApiTracerFactory is configured that will return NoopApiTracers. In the future a parallel OpenCensusApiTracerFactory will be added. A client implementation will be able to opt into tracing by setting the factory in StubSettings. The actual ApiTracer will be propagated by CallContext. * rename tracer method to subject action * address feedback * address feedback
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedUnaryCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedServerStreamingCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedClientStreamCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
* Start tracing unary callable. This depends on #633 and is extracted from #613. This introduces TracedUnaryCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions. * trace http json calls as well * fix test * oops * a bit more work * improve method name parsing * address feedback * trace operation cancellation and use static mockito imports in tests * address feedback
* Start tracing bidi streaming callables. This depends on #633 and is extracted from #613. This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions. * fixes * cancellation & static imports * address some feedback * address more feedback
* Start tracing client streaming callables. This depends on #633 and is extracted from #613. This introduces TracedClientStreamCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions. * fixes * handle operation cancellation & use static imports * address feedbac * fix merge * address feedback * address feedback
DON'T MERGE
This is a rough sketch of opencensus integration. I wanted to get some early feedback on the direction I'm taking.
The general idea here is to create an opencensus span for each toplevel operation the user invokes. Then to annotate that span with various interesting events like retry attempts.
All of the logic to create spans and annotations is centralized in a
Tracer. ATracerwraps an opencensusSpan. TheTraceris generally created by outer callables likeTracedUnaryCallableand is passed through the callable chains via theApiCallContext.The main things I would like to get some feedback on are:
Tracerinterface: it centralizes all of the annotations as opposed to exposing the raw opencensus apis.OpencensusTracerimpl. It's has some smarts like counting requests and responses that it will use in a future annotation.tracingpackage (including theCallableimpls)couldRetryto the RetryAlgorithm` to disambiguate between running out of retry attempts and the error not being retryableTODO