|
16 | 16 |
|
17 | 17 | import {
|
18 | 18 | ROOT_CONTEXT,
|
| 19 | + SpanOptions, |
19 | 20 | SpanStatusCode,
|
20 | 21 | trace,
|
21 | 22 | type Span as ApiSpan,
|
@@ -95,9 +96,15 @@ export async function runInNewSpan<T>(
|
95 | 96 | getAsyncContext().getStore<SpanContext>(spanMetadataAlsKey);
|
96 | 97 | const isInRoot = parentStep?.metadata?.isRoot === true;
|
97 | 98 | if (!parentStep) opts.metadata.isRoot ||= true;
|
| 99 | + |
| 100 | + const spanOptions: SpanOptions = { links: opts.links }; |
| 101 | + if (!isDisableRootSpanDetection()) { |
| 102 | + spanOptions.root = opts.metadata.isRoot; |
| 103 | + } |
| 104 | + |
98 | 105 | return await tracer.startActiveSpan(
|
99 | 106 | opts.metadata.name,
|
100 |
| - { links: opts.links, root: opts.metadata.isRoot }, |
| 107 | + spanOptions, |
101 | 108 | async (otSpan) => {
|
102 | 109 | if (opts.labels) otSpan.setAttributes(opts.labels);
|
103 | 110 | const spanContext = {
|
@@ -317,3 +324,22 @@ function decoratePathWithSubtype(metadata: SpanMetadata): string {
|
317 | 324 | const decoratedStep = `{${pathComponents.at(-1)?.slice(0, -1)}${stepSubtype}}`;
|
318 | 325 | return root + decoratedStep;
|
319 | 326 | }
|
| 327 | + |
| 328 | +const rootSpanDetectionKey = '__genkit_disableRootSpanDetection'; |
| 329 | + |
| 330 | +function isDisableRootSpanDetection(): boolean { |
| 331 | + return global[rootSpanDetectionKey] === true; |
| 332 | +} |
| 333 | + |
| 334 | +/** |
| 335 | + * Disables Genkit's custom root span detection and leaves default Otel root span. |
| 336 | + * |
| 337 | + * This function attempts to control Genkit's internal OTel instrumentation behaviour, |
| 338 | + * since internal implementation details are subject to change at any time consider |
| 339 | + * this function "unstable" and subject to breaking changes as well. |
| 340 | + * |
| 341 | + * @hidden |
| 342 | + */ |
| 343 | +export function disableOTelRootSpanDetection() { |
| 344 | + global[rootSpanDetectionKey] = true; |
| 345 | +} |
0 commit comments