Skip to content

Commit ba74c4a

Browse files
authored
fix: allow active spans to be passed in as an option (#544)
* fix: allow active spans to be passed in as an option * fix: use original span name, do not override
1 parent 0225010 commit ba74c4a

File tree

3 files changed

+61
-34
lines changed

3 files changed

+61
-34
lines changed

packages/blobs/src/store.ts

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { getTracer, withActiveSpan } from '@netlify/otel'
1+
import type { Span } from '@netlify/otel/opentelemetry'
22
import type { DeleteStoreResponse } from './backend/delete_store.ts'
33
import type { ListResponse, ListResponseBlob } from './backend/list.ts'
44
import { Client, type Conditions } from './client.ts'
55
import type { ConsistencyMode } from './consistency.ts'
66
import { getMetadataFromResponse, Metadata } from './metadata.ts'
77
import { BlobInput, HTTPMethod } from './types.ts'
8-
import { BlobsInternalError, collectIterator } from './util.ts'
8+
import { BlobsInternalError, collectIterator, withSpan } from './util.ts'
99

1010
export const DEPLOY_STORE_PREFIX = 'deploy:'
1111
export const LEGACY_STORE_INTERNAL_PREFIX = 'netlify-internal/legacy-namespace/'
@@ -34,6 +34,10 @@ export interface GetOptions {
3434
consistency?: ConsistencyMode
3535
}
3636

37+
export interface GetMetadataOptions {
38+
consistency?: ConsistencyMode
39+
}
40+
3741
export interface GetWithMetadataOptions {
3842
consistency?: ConsistencyMode
3943
etag?: string
@@ -60,6 +64,10 @@ export interface ListOptions {
6064
prefix?: string
6165
}
6266

67+
export interface TracingOptions {
68+
span?: Span
69+
}
70+
6371
export interface DeleteStoreResult {
6472
deletedBlobs: number
6573
}
@@ -177,17 +185,17 @@ export class Store {
177185
}
178186
}
179187

180-
async get(key: string, options?: GetOptions & { type?: 'arrayBuffer' }): Promise<ArrayBuffer>
181-
async get(key: string, options?: GetOptions & { type?: 'blob' }): Promise<Blob>
182-
async get(key: string, options?: GetOptions & { type?: 'json' }): Promise<any>
183-
async get(key: string, options?: GetOptions & { type?: 'stream' }): Promise<ReadableStream>
184-
async get(key: string, options?: GetOptions & { type?: 'text' }): Promise<string>
185-
async get(key: string, options?: GetOptions): Promise<string | null>
188+
async get(key: string, options?: GetOptions & TracingOptions & { type?: 'arrayBuffer' }): Promise<ArrayBuffer>
189+
async get(key: string, options?: GetOptions & TracingOptions & { type?: 'blob' }): Promise<Blob>
190+
async get(key: string, options?: GetOptions & TracingOptions & { type?: 'json' }): Promise<any>
191+
async get(key: string, options?: GetOptions & TracingOptions & { type?: 'stream' }): Promise<ReadableStream>
192+
async get(key: string, options?: GetOptions & TracingOptions & { type?: 'text' }): Promise<string>
193+
async get(key: string, options?: GetOptions & TracingOptions): Promise<string | null>
186194
async get(
187195
key: string,
188-
options?: GetOptions & { type?: BlobResponseType },
196+
options?: GetOptions & TracingOptions & { type?: BlobResponseType },
189197
): Promise<ArrayBuffer | Blob | ReadableStream | string | null> {
190-
return withActiveSpan(getTracer(), 'blobs.get', async (span) => {
198+
return withSpan(options?.span, 'blobs.get', async (span) => {
191199
const { consistency, type } = options ?? {}
192200

193201
span?.setAttributes({
@@ -243,15 +251,22 @@ export class Store {
243251
})
244252
}
245253

246-
async getMetadata(key: string, { consistency }: { consistency?: ConsistencyMode } = {}) {
247-
return withActiveSpan(getTracer(), 'blobs.getMetadata', async (span) => {
254+
async getMetadata(key: string, options: GetMetadataOptions & TracingOptions = {}) {
255+
return withSpan(options?.span, 'blobs.getMetadata', async (span) => {
248256
span?.setAttributes({
249257
'blobs.store': this.name,
250258
'blobs.key': key,
251259
'blobs.method': 'HEAD',
252-
'blobs.consistency': consistency,
260+
'blobs.consistency': options.consistency,
253261
})
254-
const res = await this.client.makeRequest({ consistency, key, method: HTTPMethod.HEAD, storeName: this.name })
262+
263+
const res = await this.client.makeRequest({
264+
consistency: options.consistency,
265+
key,
266+
method: HTTPMethod.HEAD,
267+
storeName: this.name,
268+
})
269+
255270
span?.setAttributes({
256271
'blobs.response.status': res.status,
257272
})
@@ -277,44 +292,44 @@ export class Store {
277292

278293
async getWithMetadata(
279294
key: string,
280-
options?: GetWithMetadataOptions,
295+
options?: GetWithMetadataOptions & TracingOptions,
281296
): Promise<({ data: string } & GetWithMetadataResult) | null>
282297

283298
async getWithMetadata(
284299
key: string,
285-
options: { type: 'arrayBuffer' } & GetWithMetadataOptions,
300+
options: { type: 'arrayBuffer' } & GetWithMetadataOptions & TracingOptions,
286301
): Promise<{ data: ArrayBuffer } & GetWithMetadataResult>
287302

288303
async getWithMetadata(
289304
key: string,
290-
options: { type: 'blob' } & GetWithMetadataOptions,
305+
options: { type: 'blob' } & GetWithMetadataOptions & TracingOptions,
291306
): Promise<({ data: Blob } & GetWithMetadataResult) | null>
292307

293308
async getWithMetadata(
294309
key: string,
295-
options: { type: 'json' } & GetWithMetadataOptions,
310+
options: { type: 'json' } & GetWithMetadataOptions & TracingOptions,
296311
): Promise<({ data: any } & GetWithMetadataResult) | null>
297312

298313
async getWithMetadata(
299314
key: string,
300-
options: { type: 'stream' } & GetWithMetadataOptions,
315+
options: { type: 'stream' } & GetWithMetadataOptions & TracingOptions,
301316
): Promise<({ data: ReadableStream } & GetWithMetadataResult) | null>
302317

303318
async getWithMetadata(
304319
key: string,
305-
options: { type: 'text' } & GetWithMetadataOptions,
320+
options: { type: 'text' } & GetWithMetadataOptions & TracingOptions,
306321
): Promise<({ data: string } & GetWithMetadataResult) | null>
307322

308323
async getWithMetadata(
309324
key: string,
310-
options?: { type: BlobResponseType } & GetWithMetadataOptions,
325+
options?: { type: BlobResponseType } & GetWithMetadataOptions & TracingOptions,
311326
): Promise<
312327
| ({
313328
data: ArrayBuffer | Blob | ReadableStream | string | null
314329
} & GetWithMetadataResult)
315330
| null
316331
> {
317-
return withActiveSpan(getTracer(), 'blobs.getWithMetadata', async (span) => {
332+
return withSpan(options?.span, 'blobs.getWithMetadata', async (span) => {
318333
const { consistency, etag: requestETag, type } = options ?? {}
319334
const headers = requestETag ? { 'if-none-match': requestETag } : undefined
320335

@@ -384,10 +399,10 @@ export class Store {
384399
})
385400
}
386401

387-
list(options: ListOptions & { paginate: true }): AsyncIterable<ListResult>
388-
list(options?: ListOptions & { paginate?: false }): Promise<ListResult>
389-
list(options: ListOptions = {}): Promise<ListResult> | AsyncIterable<ListResult> {
390-
return withActiveSpan(getTracer(), 'blobs.list', (span) => {
402+
list(options: ListOptions & TracingOptions & { paginate: true }): AsyncIterable<ListResult>
403+
list(options?: ListOptions & TracingOptions & { paginate?: false }): Promise<ListResult>
404+
list(options: ListOptions & TracingOptions = {}): Promise<ListResult> | AsyncIterable<ListResult> {
405+
return withSpan(options.span, 'blobs.list', (span) => {
391406
span?.setAttributes({
392407
'blobs.store': this.name,
393408
'blobs.method': 'GET',
@@ -414,8 +429,8 @@ export class Store {
414429
})
415430
}
416431

417-
async set(key: string, data: BlobInput, options: SetOptions = {}): Promise<WriteResult> {
418-
return withActiveSpan(getTracer(), 'blobs.set', async (span) => {
432+
async set(key: string, data: BlobInput, options: SetOptions & TracingOptions = {}): Promise<WriteResult> {
433+
return withSpan(options.span, 'blobs.set', async (span) => {
419434
span?.setAttributes({
420435
'blobs.store': this.name,
421436
'blobs.key': key,
@@ -459,8 +474,8 @@ export class Store {
459474
})
460475
}
461476

462-
async setJSON(key: string, data: unknown, options: SetOptions = {}): Promise<WriteResult> {
463-
return withActiveSpan(getTracer(), 'blobs.setJSON', async (span) => {
477+
async setJSON(key: string, data: unknown, options: SetOptions & TracingOptions = {}): Promise<WriteResult> {
478+
return withSpan(options.span, 'blobs.setJSON', async (span) => {
464479
span?.setAttributes({
465480
'blobs.store': this.name,
466481
'blobs.key': key,
@@ -585,7 +600,7 @@ export class Store {
585600
}
586601
}
587602

588-
private getListIterator(options?: ListOptions): AsyncIterable<ListResult> {
603+
private getListIterator(options?: ListOptions & TracingOptions): AsyncIterable<ListResult> {
589604
const { client, name: storeName } = this
590605
const parameters: Record<string, string> = {}
591606

@@ -604,7 +619,7 @@ export class Store {
604619

605620
return {
606621
async next() {
607-
return withActiveSpan(getTracer(), 'blobs.list.next', async (span) => {
622+
return withSpan(options?.span, 'blobs.list.next', async (span) => {
608623
span?.setAttributes({
609624
'blobs.store': storeName,
610625
'blobs.method': 'GET',

packages/blobs/src/util.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import process from 'node:process'
2+
import { getTracer, withActiveSpan } from '@netlify/otel'
3+
import type { Span } from '@netlify/otel/opentelemetry'
4+
25
import { NF_ERROR, NF_REQUEST_ID } from './headers.ts'
36

47
export class BlobsInternalError extends Error {
@@ -63,3 +66,12 @@ export function encodeName(string: string): string {
6366
export function decodeName(string: string): string {
6467
return process.platform == 'win32' ? decodeWin32SafeName(string) : string
6568
}
69+
70+
// Allow users to pass in their own active span or defaults to creating a new active span
71+
export function withSpan<F extends (span?: Span) => ReturnType<F>>(span: Span | undefined, name: string, fn: F) {
72+
if (span) return fn(span)
73+
74+
return withActiveSpan(getTracer(), name, (span) => {
75+
return fn(span)
76+
})
77+
}

packages/blobs/tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
"allowImportingTsExtensions": true,
44
"emitDeclarationOnly": true,
55
"target": "ES2020",
6-
"module": "es2020",
6+
"module": "nodenext",
77
"allowJs": true,
88
"declaration": true,
99
"declarationMap": false,
1010
"sourceMap": false,
1111
"outDir": "./dist",
1212
"removeComments": false,
1313
"strict": true,
14-
"moduleResolution": "node",
14+
"moduleResolution": "nodenext",
1515
"esModuleInterop": true,
1616
"skipLibCheck": true,
1717
"forceConsistentCasingInFileNames": true

0 commit comments

Comments
 (0)