e27b7e996d
A number of changes here. I recommend viewing the diff with the <a href="?w=1">whitespace flag enabled</a>.
- OpenTelemetry is replaced with a custom and lightweight tracing solution.
- Three trace targets are currently supported: console, Zipkin, and NextJS.
- Tracing is now governed by environment variables rather than `--require instrument.js`.
+ `TRACE_TARGET`: one of `CONSOLE`, `ZIPKIN`, or `TELEMETRY`; defaults to `TELEMETRY` if unset or invalid.
+ `TRACE_ID`: an 8-byte hex-encoded value used as the Zipkin trace ID; if not provided, this value will be randomly generated and passed down to subprocesses.
Other sundry:
- I'm missing something, probably a setup step, with the Zipkin target. Traces are captured successfully, but you have to manually enter the Trace ID in order to view the trace - it doesn't show up in queries.
- I'm generally unhappy with [this commit](235cedcb3e
). It is... untidy to provide a telemetry object via `setGlobal`, but I don't have a ready alternative. Is `distDir` strictly required when creating a new Telemetry object? I didn't dig too deep here.
As noted, there are a lot of changes, so it'd be great if a reviewer could:
- [ ] pull down the branch and try to break it
- [ ] check the Zipkin traces and identify possible regressions in the functionality
Closes #22570
Fixes #22574
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { trace, Span } from './trace'
|
|
|
|
const stacks = new WeakMap<any, Array<Span>>()
|
|
const stoppedSpansSets = new WeakMap<any, Set<Span>>()
|
|
|
|
export function stackPush(keyObj: any, spanName: string, attrs?: any): Span {
|
|
let stack = stacks.get(keyObj)
|
|
let span
|
|
|
|
if (!stack) {
|
|
stack = []
|
|
stacks.set(keyObj, stack)
|
|
span = trace(spanName, undefined, attrs ? attrs() : undefined)
|
|
} else {
|
|
const parent = stack[stack.length - 1]
|
|
if (parent) {
|
|
span = trace(spanName, parent.id, attrs ? attrs() : undefined)
|
|
} else {
|
|
span = trace(spanName, undefined, attrs ? attrs() : undefined)
|
|
}
|
|
}
|
|
|
|
stack.push(span)
|
|
return span
|
|
}
|
|
|
|
export function stackPop(keyObj: any, span: any): void {
|
|
let stack = stacks.get(keyObj)
|
|
if (!stack) {
|
|
console.info(
|
|
'Attempted to pop from non-existent stack. Key reference must be bad.'
|
|
)
|
|
return
|
|
}
|
|
|
|
let stoppedSpans = stoppedSpansSets.get(keyObj)
|
|
if (!stoppedSpans) {
|
|
stoppedSpans = new Set()
|
|
stoppedSpansSets.set(keyObj, stoppedSpans)
|
|
}
|
|
if (stoppedSpans.has(span)) {
|
|
console.info(
|
|
`Attempted to terminate tracing span that was already stopped for ${span.name}`
|
|
)
|
|
return
|
|
}
|
|
|
|
while (true) {
|
|
let poppedSpan = stack.pop()
|
|
|
|
if (poppedSpan && poppedSpan === span) {
|
|
stoppedSpans.add(poppedSpan)
|
|
span.stop()
|
|
stoppedSpans.add(span)
|
|
break
|
|
} else if (poppedSpan === undefined || stack.indexOf(span) === -1) {
|
|
// We've either reached the top of the stack or the stack doesn't contain
|
|
// the span for another reason.
|
|
console.info(`Tracing span was not found in stack for: ${span.name}`)
|
|
stoppedSpans.add(span)
|
|
span.stop()
|
|
break
|
|
} else if (stack.indexOf(span) !== -1) {
|
|
console.info(
|
|
`Attempted to pop span that was not at top of stack for: ${span.name}`
|
|
)
|
|
stoppedSpans.add(poppedSpan)
|
|
poppedSpan.stop()
|
|
}
|
|
}
|
|
}
|