Skip to content

Commit 4fc00a8

Browse files
committed
Refactor config and sampling logic out of the sdk file
1 parent f15b21c commit 4fc00a8

File tree

3 files changed

+85
-89
lines changed

3 files changed

+85
-89
lines changed

src/config.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import { context } from '@opentelemetry/api'
2-
import { ResolvedTraceConfig, Trigger } from './types.js'
2+
import {
3+
ExporterConfig,
4+
isSpanProcessorConfig,
5+
ParentRatioSamplingConfig,
6+
ResolvedTraceConfig,
7+
TraceConfig,
8+
Trigger,
9+
} from './types.js'
10+
import { W3CTraceContextPropagator } from '@opentelemetry/core'
11+
import { AlwaysOnSampler, ReadableSpan, Sampler, SpanExporter } from '@opentelemetry/sdk-trace-base'
12+
13+
import { OTLPExporter } from './exporter.js'
14+
import { multiTailSampler, isHeadSampled, isRootErrorSpan, createSampler } from './sampling.js'
15+
import { BatchTraceSpanProcessor } from './spanprocessor.js'
316

417
const configSymbol = Symbol('Otel Workers Tracing Configuration')
518

@@ -13,3 +26,55 @@ export function getActiveConfig(): ResolvedTraceConfig | undefined {
1326
const config = context.active().getValue(configSymbol) as ResolvedTraceConfig
1427
return config || undefined
1528
}
29+
30+
function isSpanExporter(exporterConfig: ExporterConfig): exporterConfig is SpanExporter {
31+
return !!(exporterConfig as SpanExporter).export
32+
}
33+
34+
function isSampler(sampler: Sampler | ParentRatioSamplingConfig): sampler is Sampler {
35+
return !!(sampler as Sampler).shouldSample
36+
}
37+
38+
export function parseConfig(supplied: TraceConfig): ResolvedTraceConfig {
39+
if (isSpanProcessorConfig(supplied)) {
40+
const headSampleConf = supplied.sampling?.headSampler
41+
const headSampler = headSampleConf
42+
? isSampler(headSampleConf)
43+
? headSampleConf
44+
: createSampler(headSampleConf)
45+
: new AlwaysOnSampler()
46+
const spanProcessors = Array.isArray(supplied.spanProcessors) ? supplied.spanProcessors : [supplied.spanProcessors]
47+
if (spanProcessors.length === 0) {
48+
console.log(
49+
'Warning! You must either specify an exporter or your own SpanProcessor(s)/Exporter combination in the open-telemetry configuration.',
50+
)
51+
}
52+
return {
53+
fetch: {
54+
includeTraceContext: supplied.fetch?.includeTraceContext ?? true,
55+
},
56+
handlers: {
57+
fetch: {
58+
acceptTraceContext: supplied.handlers?.fetch?.acceptTraceContext ?? true,
59+
},
60+
},
61+
postProcessor: supplied.postProcessor || ((spans: ReadableSpan[]) => spans),
62+
sampling: {
63+
headSampler,
64+
tailSampler: supplied.sampling?.tailSampler || multiTailSampler([isHeadSampled, isRootErrorSpan]),
65+
},
66+
service: supplied.service,
67+
spanProcessors,
68+
propagator: supplied.propagator || new W3CTraceContextPropagator(),
69+
instrumentation: {
70+
instrumentGlobalCache: supplied.instrumentation?.instrumentGlobalCache ?? true,
71+
instrumentGlobalFetch: supplied.instrumentation?.instrumentGlobalFetch ?? true,
72+
},
73+
}
74+
} else {
75+
const exporter = isSpanExporter(supplied.exporter) ? supplied.exporter : new OTLPExporter(supplied.exporter)
76+
const spanProcessors = [new BatchTraceSpanProcessor(exporter)]
77+
const newConfig = Object.assign(supplied, { exporter: undefined, spanProcessors }) as TraceConfig
78+
return parseConfig(newConfig)
79+
}
80+
}

src/sampling.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { TraceFlags, SpanStatusCode } from '@opentelemetry/api'
2-
import { ReadableSpan } from '@opentelemetry/sdk-trace-base'
2+
import { ParentBasedSampler, ReadableSpan, Sampler, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-base'
3+
import { ParentRatioSamplingConfig } from './types'
34

45
export interface LocalTrace {
56
readonly traceId: string
@@ -24,3 +25,16 @@ export const isRootErrorSpan: TailSampleFn = (traceInfo) => {
2425
const localRootSpan = traceInfo.localRootSpan
2526
return localRootSpan.status.code === SpanStatusCode.ERROR
2627
}
28+
29+
export function createSampler(conf: ParentRatioSamplingConfig): Sampler {
30+
const ratioSampler = new TraceIdRatioBasedSampler(conf.ratio)
31+
if (typeof conf.acceptRemote === 'boolean' && !conf.acceptRemote) {
32+
return new ParentBasedSampler({
33+
root: ratioSampler,
34+
remoteParentSampled: ratioSampler,
35+
remoteParentNotSampled: ratioSampler,
36+
})
37+
} else {
38+
return new ParentBasedSampler({ root: ratioSampler })
39+
}
40+
}

src/sdk.ts

Lines changed: 4 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,16 @@
11
import { propagation } from '@opentelemetry/api'
2-
import { W3CTraceContextPropagator } from '@opentelemetry/core'
32
import { Resource } from '@opentelemetry/resources'
4-
import {
5-
AlwaysOnSampler,
6-
ParentBasedSampler,
7-
ReadableSpan,
8-
Sampler,
9-
SpanExporter,
10-
TraceIdRatioBasedSampler,
11-
} from '@opentelemetry/sdk-trace-base'
12-
13-
import { Initialiser } from './config.js'
14-
import { OTLPExporter } from './exporter.js'
3+
4+
import { Initialiser, parseConfig } from './config.js'
155
import { WorkerTracerProvider } from './provider.js'
16-
import { isHeadSampled, isRootErrorSpan, multiTailSampler } from './sampling.js'
17-
import { BatchTraceSpanProcessor } from './spanprocessor.js'
18-
import {
19-
Trigger,
20-
TraceConfig,
21-
ResolvedTraceConfig,
22-
ExporterConfig,
23-
ParentRatioSamplingConfig,
24-
isSpanProcessorConfig,
25-
} from './types.js'
6+
import { Trigger, TraceConfig, ResolvedTraceConfig } from './types.js'
267
import { unwrap } from './wrap.js'
278
import { createFetchHandler, instrumentGlobalFetch } from './instrumentation/fetch.js'
289
import { instrumentGlobalCache } from './instrumentation/cache.js'
2910
import { createQueueHandler } from './instrumentation/queue.js'
3011
import { DOClass, instrumentDOClass } from './instrumentation/do.js'
3112
import { createScheduledHandler } from './instrumentation/scheduled.js'
13+
//@ts-ignore
3214
import * as versions from '../versions.json'
3315

3416
type FetchHandler = ExportedHandlerFetchHandler<unknown, unknown>
@@ -70,10 +52,6 @@ const createResource = (config: ResolvedTraceConfig): Resource => {
7052
return resource.merge(serviceResource)
7153
}
7254

73-
function isSpanExporter(exporterConfig: ExporterConfig): exporterConfig is SpanExporter {
74-
return !!(exporterConfig as SpanExporter).export
75-
}
76-
7755
let initialised = false
7856
function init(config: ResolvedTraceConfig): void {
7957
if (!initialised) {
@@ -92,67 +70,6 @@ function init(config: ResolvedTraceConfig): void {
9270
}
9371
}
9472

95-
function isSampler(sampler: Sampler | ParentRatioSamplingConfig): sampler is Sampler {
96-
return !!(sampler as Sampler).shouldSample
97-
}
98-
99-
function createSampler(conf: ParentRatioSamplingConfig): Sampler {
100-
const ratioSampler = new TraceIdRatioBasedSampler(conf.ratio)
101-
if (typeof conf.acceptRemote === 'boolean' && !conf.acceptRemote) {
102-
return new ParentBasedSampler({
103-
root: ratioSampler,
104-
remoteParentSampled: ratioSampler,
105-
remoteParentNotSampled: ratioSampler,
106-
})
107-
} else {
108-
return new ParentBasedSampler({ root: ratioSampler })
109-
}
110-
}
111-
112-
function parseConfig(supplied: TraceConfig): ResolvedTraceConfig {
113-
if (isSpanProcessorConfig(supplied)) {
114-
const headSampleConf = supplied.sampling?.headSampler
115-
const headSampler = headSampleConf
116-
? isSampler(headSampleConf)
117-
? headSampleConf
118-
: createSampler(headSampleConf)
119-
: new AlwaysOnSampler()
120-
const spanProcessors = Array.isArray(supplied.spanProcessors) ? supplied.spanProcessors : [supplied.spanProcessors]
121-
if (spanProcessors.length === 0) {
122-
console.log(
123-
'Warning! You must either specify an exporter or your own SpanProcessor(s)/Exporter combination in the open-telemetry configuration.',
124-
)
125-
}
126-
return {
127-
fetch: {
128-
includeTraceContext: supplied.fetch?.includeTraceContext ?? true,
129-
},
130-
handlers: {
131-
fetch: {
132-
acceptTraceContext: supplied.handlers?.fetch?.acceptTraceContext ?? true,
133-
},
134-
},
135-
postProcessor: supplied.postProcessor || ((spans: ReadableSpan[]) => spans),
136-
sampling: {
137-
headSampler,
138-
tailSampler: supplied.sampling?.tailSampler || multiTailSampler([isHeadSampled, isRootErrorSpan]),
139-
},
140-
service: supplied.service,
141-
spanProcessors,
142-
propagator: supplied.propagator || new W3CTraceContextPropagator(),
143-
instrumentation: {
144-
instrumentGlobalCache: supplied.instrumentation?.instrumentGlobalCache ?? true,
145-
instrumentGlobalFetch: supplied.instrumentation?.instrumentGlobalFetch ?? true,
146-
},
147-
}
148-
} else {
149-
const exporter = isSpanExporter(supplied.exporter) ? supplied.exporter : new OTLPExporter(supplied.exporter)
150-
const spanProcessors = [new BatchTraceSpanProcessor(exporter)]
151-
const newConfig = Object.assign(supplied, { exporter: undefined, spanProcessors }) as TraceConfig
152-
return parseConfig(newConfig)
153-
}
154-
}
155-
15673
function createInitialiser(config: ConfigurationOption): Initialiser {
15774
if (typeof config === 'function') {
15875
return (env, trigger) => {

0 commit comments

Comments
 (0)