-
Notifications
You must be signed in to change notification settings - Fork 96
feat(tracer): separate cls from tracer #484
feat(tracer): separate cls from tracer #484
Conversation
Codecov Report
@@ Coverage Diff @@
## master #484 +/- ##
==========================================
- Coverage 95.01% 94.99% -0.02%
==========================================
Files 143 145 +2
Lines 9299 10222 +923
Branches 515 874 +359
==========================================
+ Hits 8835 9710 +875
- Misses 464 512 +48
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.
Can you please update CHANGELOG.md
with a breaking change line. How do you plan to expose basic tracer (with no CLS) using tracing instance?
@@ -42,7 +42,7 @@ function startServer (port) { | |||
|
|||
/** A function which handles requests and send response. */ | |||
function handleRequest (request, response) { | |||
const span = tracer.startChildSpan('octutorials.handleRequest'); | |||
const span = tracer.startChildSpan({ name: 'octutorials.handleRequest' }); |
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 would suggest to update the examples in separate PR, WDYT?
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.
Any update here?
@@ -0,0 +1,142 @@ | |||
/** | |||
* Copyright 2018, OpenCensus Authors |
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: s/2018/2019
*/ | ||
|
||
import * as cls from '../../internal/cls'; | ||
|
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.
Optional Nit: Remove blank line
parentSpanId = options.spanContext.spanId || ''; | ||
traceState = options.spanContext.traceState; | ||
let traceId; | ||
if (options && options.spanContext && options.spanContext.traceId) { |
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.
Can we just do options = options || {name: 'span'};
at the start and remove falsiness check on options
(multiple places below)?
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.
actually, we could do just:
function (options = { name: 'span' }) { ... }
/** | ||
* Starts a span. | ||
* @param nameOrOptions Span name string or SpanOptions object. | ||
* @param kind Span kind if not using SpanOptions object. | ||
* @param [options] span options |
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 as above
* @param childOf Span | ||
* @param [name] Span name | ||
* @param [kind] Span kind | ||
* @param [options] Span Options |
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 as above and just keep options param.
/** Get and set the currentRootSpan to tracer instance */ | ||
currentRootSpan: Span; | ||
|
||
|
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: Remove extra blank line.
@mayurkale22 earlier I posted some API ideas as a comment here, I just moved them to the PR description now. Could you please share what do you think about them? |
Thanks for the detailed description, the Changes and Action items makes sense to me. In terms of a breaking changes, could you please elaborate more on ambiguity on span creation? My initial impression was to keep default tracer as
SGTM, But would love to see same for CLS Tracer (easier to maintain and switch around). WDYT? |
@mayurkale22 thanks for the feedback! About the API ambiguity: The Only keeping the object options notations looks clear and robust solution to me, due to the TypeScript types it's easy to discover the available option properties. |
Makes sense to me, please update CHANGELOG.md with a breaking change line. Thanks |
const child1 = | ||
tracer.startChildSpan('child1', types.SpanKind.UNSPECIFIED); | ||
const child1 = tracer.startChildSpan( | ||
{name: 'child1', kind: types.SpanKind.UNSPECIFIED}); |
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.
To simplify these tests and the API, can kind
just have a default value? Then we wouldn't need to specify it again and again.
import * as types from './types'; | ||
|
||
/** | ||
* This class represent a tracer with CLS. |
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.
Explain what CLS is and when you would or would not want to use it.
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.
+1
@mayurkale22 @kenashcraft thanks for the review, I addressed the PR comments:
|
import * as types from './types'; | ||
|
||
/** | ||
* This class represent a tracer. | ||
* This class represents a tracer with Cointunues Local Storage (CLS). |
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: s/Cointunues/Continuation/
private readonly IS_SAMPLED = 0x1; | ||
/** A sampler used to make sample decisions */ | ||
sampler!: samplerTypes.Sampler; | ||
/** A configuration for starting the 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.
Please update this comment to something like -> An object to log information to
rootSpan.start(); | ||
return fn(rootSpan); | ||
} | ||
} else { |
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.
Can we remove this else, and update the debug msg: Tracer is inactive, starting new no record root span
?
import * as types from './types'; | ||
|
||
/** | ||
* This class represent a tracer with CLS. |
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.
+1
* This class represent a tracer. | ||
* This class represents a tracer with Cointunues Local Storage (CLS). | ||
* | ||
* CLS helps keep tracking the root span over function calls automatically. |
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.
Can we add -> It is capable of storing, propagating and retrieving arbitrary continuation-local data (also called "context").
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.
Added
@@ -52,7 +52,7 @@ describe('Tracer', () => { | |||
}); | |||
}); | |||
|
|||
/** Should get/set the current RootSpan from tracer instance */ | |||
// /** Should get/set the current RootSpan from tracer instance */ |
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.
Is this typo or intended stuff?
@mayurkale22 I addressed your new round of comments. Thanks! |
@hekike Thanks for the work! What's your plan on above action items. Also, How do you plan to expose basic tracer (with no CLS) using tracing instance? OR as a user, how do I use basic tracer in my app? |
@mayurkale22 I finished the open action items: separates CoreTracer and CoreTracerBase tests and added some context specific tests. |
@hekike Mayur has been on vacation for the past two weeks, but he's back next Monday. Do you need someone to approve prior to that? |
It would be helpful if we could move this work forward. I'm planning to open further PRs which would require this 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 think this is a reasonable refactor and so LGTM with a few nit-picky comments.
I personally like the breaking change to simplify tracer.startChildSpan
, but I'm not sure how impactful that would be to library users, and I wonder if it would be possible to separate the CLS functionality of the tracer without making that change. I would leave it to @mayurkale22 to make a call here.
/** Indicates if the tracer is active */ | ||
private activeLocal: boolean; | ||
/** A configuration for starting the tracer */ | ||
private config!: configTypes.TracerConfig; |
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.
Rather than using a !
would it be possible to assign some reasonable default 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.
The default config lives in the opencensus-node
today. I could move it to opencensus-core
and add as a static property to this class. Then use it here as defaults and consume from here in the opencensus-node
. My only concern is that this is not a change in this PR and I would prefer to keep the scope focused. But I'm happy to do this as a separate PR.
/** Bit to represent whether trace is sampled or not. */ | ||
private readonly IS_SAMPLED = 0x1; | ||
/** A sampler used to make sample decisions */ | ||
sampler!: samplerTypes.Sampler; |
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.
Similar comment here on the sampler - can we assign some reasonable default sampler, e.g. one that samples at the default rate?
// if there is a context propagation, keep the decision | ||
if (options && options.spanContext && options.spanContext.options) { | ||
propagatedSample = | ||
((options.spanContext.options & this.IS_SAMPLED) !== 0); |
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: can the outer parentheses around this expression be removed?
((options.spanContext.options & this.IS_SAMPLED) !== 0); | ||
} | ||
|
||
let sampleDecision = !!propagatedSample; |
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.
Could this logic be simplified to return !!propagatedSample || this.sampler.shouldSample(traceId)
?
BREAKING CHANGE: startChildSpan only accepts option object
f9c0569
to
cebd25e
Compare
implements: #462
Changes
tracer.startChildSpan
because it brings ambiguity into span creationCoreTracer
andCoreTracerCls
Breaking Changes
startChildSpan
only acceptsoptions
objectTracer
becomeTracerCls
Tracer
is the basic non CLS version nowAction Items
separate tests out to(done)test-tracer.ts
andtest-tracer-cls.ts
Improve non-cls tracer test coverage(done)Child of child with CLS Tracer
It's worth calling out that the CLS implementation still supports only one level of relationships as the
rootSpan
in the namespace context remains the same for child span creation. I guess it's expected based on current instrumentations.A couple of further optimization ideas
startRootSpan
sync in the non-CLS TracerstartRootSpan
andstartChildSpan
in the non CLS Tracer (startSpan
)