@xylabs/telemetry 5.0.79 → 5.0.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -8
- package/package.json +7 -9
- package/src/index.ts +0 -2
- package/src/span.ts +0 -160
- package/src/timeBudget.ts +0 -30
package/README.md
CHANGED
|
@@ -21,6 +21,10 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
|
|
|
21
21
|
|
|
22
22
|
***
|
|
23
23
|
|
|
24
|
+
## Interfaces
|
|
25
|
+
|
|
26
|
+
- [SpanConfig](#interfaces/SpanConfig)
|
|
27
|
+
|
|
24
28
|
## Functions
|
|
25
29
|
|
|
26
30
|
- [cloneContextWithoutSpan](#functions/cloneContextWithoutSpan)
|
|
@@ -28,6 +32,7 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
|
|
|
28
32
|
- [spanRoot](#functions/spanRoot)
|
|
29
33
|
- [spanAsync](#functions/spanAsync)
|
|
30
34
|
- [spanRootAsync](#functions/spanRootAsync)
|
|
35
|
+
- [timeBudget](#functions/timeBudget)
|
|
31
36
|
|
|
32
37
|
### functions
|
|
33
38
|
|
|
@@ -38,7 +43,7 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
|
|
|
38
43
|
***
|
|
39
44
|
|
|
40
45
|
```ts
|
|
41
|
-
function cloneContextWithoutSpan(activeCtx, configKeys): Context;
|
|
46
|
+
function cloneContextWithoutSpan(activeCtx, configKeys?): Context;
|
|
42
47
|
```
|
|
43
48
|
|
|
44
49
|
## Parameters
|
|
@@ -47,7 +52,7 @@ function cloneContextWithoutSpan(activeCtx, configKeys): Context;
|
|
|
47
52
|
|
|
48
53
|
`Context`
|
|
49
54
|
|
|
50
|
-
### configKeys
|
|
55
|
+
### configKeys?
|
|
51
56
|
|
|
52
57
|
`symbol`[] = `[]`
|
|
53
58
|
|
|
@@ -102,7 +107,7 @@ function span<T>(
|
|
|
102
107
|
function spanAsync<T>(
|
|
103
108
|
name,
|
|
104
109
|
fn,
|
|
105
|
-
|
|
110
|
+
__namedParameters?): Promise<T>;
|
|
106
111
|
```
|
|
107
112
|
|
|
108
113
|
## Type Parameters
|
|
@@ -121,9 +126,9 @@ tracer?): Promise<T>;
|
|
|
121
126
|
|
|
122
127
|
() => `Promise`\<`T`\>
|
|
123
128
|
|
|
124
|
-
###
|
|
129
|
+
### \_\_namedParameters?
|
|
125
130
|
|
|
126
|
-
`
|
|
131
|
+
[`SpanConfig`](#../interfaces/SpanConfig) = `{}`
|
|
127
132
|
|
|
128
133
|
## Returns
|
|
129
134
|
|
|
@@ -176,7 +181,7 @@ function spanRoot<T>(
|
|
|
176
181
|
function spanRootAsync<T>(
|
|
177
182
|
name,
|
|
178
183
|
fn,
|
|
179
|
-
|
|
184
|
+
__namedParameters?): Promise<T>;
|
|
180
185
|
```
|
|
181
186
|
|
|
182
187
|
## Type Parameters
|
|
@@ -195,14 +200,93 @@ tracer?): Promise<T>;
|
|
|
195
200
|
|
|
196
201
|
() => `Promise`\<`T`\>
|
|
197
202
|
|
|
198
|
-
###
|
|
203
|
+
### \_\_namedParameters?
|
|
199
204
|
|
|
200
|
-
`
|
|
205
|
+
[`SpanConfig`](#../interfaces/SpanConfig) = `{}`
|
|
201
206
|
|
|
202
207
|
## Returns
|
|
203
208
|
|
|
204
209
|
`Promise`\<`T`\>
|
|
205
210
|
|
|
211
|
+
### <a id="timeBudget"></a>timeBudget
|
|
212
|
+
|
|
213
|
+
[**@xylabs/telemetry**](#../README)
|
|
214
|
+
|
|
215
|
+
***
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
function timeBudget<TResult>(
|
|
219
|
+
name,
|
|
220
|
+
logger,
|
|
221
|
+
func,
|
|
222
|
+
budget,
|
|
223
|
+
status?): Promise<TResult>;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Type Parameters
|
|
227
|
+
|
|
228
|
+
### TResult
|
|
229
|
+
|
|
230
|
+
`TResult`
|
|
231
|
+
|
|
232
|
+
## Parameters
|
|
233
|
+
|
|
234
|
+
### name
|
|
235
|
+
|
|
236
|
+
`string`
|
|
237
|
+
|
|
238
|
+
### logger
|
|
239
|
+
|
|
240
|
+
`Logger` | `undefined`
|
|
241
|
+
|
|
242
|
+
### func
|
|
243
|
+
|
|
244
|
+
() => `Promise`\<`TResult`\>
|
|
245
|
+
|
|
246
|
+
### budget
|
|
247
|
+
|
|
248
|
+
`number`
|
|
249
|
+
|
|
250
|
+
### status?
|
|
251
|
+
|
|
252
|
+
`boolean` = `false`
|
|
253
|
+
|
|
254
|
+
## Returns
|
|
255
|
+
|
|
256
|
+
`Promise`\<`TResult`\>
|
|
257
|
+
|
|
258
|
+
### interfaces
|
|
259
|
+
|
|
260
|
+
### <a id="SpanConfig"></a>SpanConfig
|
|
261
|
+
|
|
262
|
+
[**@xylabs/telemetry**](#../README)
|
|
263
|
+
|
|
264
|
+
***
|
|
265
|
+
|
|
266
|
+
## Properties
|
|
267
|
+
|
|
268
|
+
### logger?
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
optional logger: Logger | null;
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
***
|
|
275
|
+
|
|
276
|
+
### timeBudgetLimit?
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
optional timeBudgetLimit: number;
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
***
|
|
283
|
+
|
|
284
|
+
### tracer?
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
optional tracer: Tracer;
|
|
288
|
+
```
|
|
289
|
+
|
|
206
290
|
|
|
207
291
|
Part of [sdk-js](https://www.npmjs.com/package/@xyo-network/sdk-js)
|
|
208
292
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xylabs/telemetry",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.81",
|
|
4
4
|
"description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hex",
|
|
@@ -29,30 +29,28 @@
|
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
31
|
"types": "./dist/neutral/index.d.ts",
|
|
32
|
-
"source": "./src/index.ts",
|
|
33
32
|
"default": "./dist/neutral/index.mjs"
|
|
34
33
|
},
|
|
35
34
|
"./package.json": "./package.json"
|
|
36
35
|
},
|
|
37
36
|
"module": "./dist/neutral/index.mjs",
|
|
38
|
-
"source": "./src/index.ts",
|
|
39
37
|
"types": "./dist/neutral/index.d.ts",
|
|
40
38
|
"files": [
|
|
41
39
|
"dist",
|
|
42
|
-
"src",
|
|
43
40
|
"!**/*.bench.*",
|
|
44
41
|
"!**/*.spec.*",
|
|
45
42
|
"!**/*.test.*"
|
|
46
43
|
],
|
|
47
44
|
"dependencies": {
|
|
48
45
|
"@opentelemetry/api": "^1.9.0",
|
|
49
|
-
"@xylabs/logger": "~5.0.
|
|
50
|
-
"@xylabs/typeof": "~5.0.
|
|
46
|
+
"@xylabs/logger": "~5.0.81",
|
|
47
|
+
"@xylabs/typeof": "~5.0.81"
|
|
51
48
|
},
|
|
52
49
|
"devDependencies": {
|
|
53
|
-
"@xylabs/ts-scripts-yarn3": "~7.
|
|
54
|
-
"@xylabs/tsconfig": "~7.
|
|
55
|
-
"typescript": "~5.9.3"
|
|
50
|
+
"@xylabs/ts-scripts-yarn3": "~7.4.11",
|
|
51
|
+
"@xylabs/tsconfig": "~7.4.11",
|
|
52
|
+
"typescript": "~5.9.3",
|
|
53
|
+
"vitest": "~4.0.18"
|
|
56
54
|
},
|
|
57
55
|
"engines": {
|
|
58
56
|
"node": ">=18"
|
package/src/index.ts
DELETED
package/src/span.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Context,
|
|
3
|
-
Tracer,
|
|
4
|
-
} from '@opentelemetry/api'
|
|
5
|
-
import {
|
|
6
|
-
context, propagation, ROOT_CONTEXT, SpanStatusCode, trace as TRACE_API,
|
|
7
|
-
} from '@opentelemetry/api'
|
|
8
|
-
import type { Logger } from '@xylabs/logger'
|
|
9
|
-
import { isDefined } from '@xylabs/typeof'
|
|
10
|
-
|
|
11
|
-
import { timeBudget } from './timeBudget.ts'
|
|
12
|
-
|
|
13
|
-
export interface SpanConfig {
|
|
14
|
-
logger?: Logger | null
|
|
15
|
-
timeBudgetLimit?: number
|
|
16
|
-
tracer?: Tracer
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function cloneContextWithoutSpan(activeCtx: Context, configKeys: symbol[] = []): Context {
|
|
20
|
-
// Start from root to ensure no span is propagated
|
|
21
|
-
let newCtx = ROOT_CONTEXT
|
|
22
|
-
|
|
23
|
-
// Copy baggage
|
|
24
|
-
const baggage = propagation.getBaggage(activeCtx)
|
|
25
|
-
if (baggage) {
|
|
26
|
-
newCtx = propagation.setBaggage(newCtx, baggage)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Copy custom config keys
|
|
30
|
-
for (const key of configKeys) {
|
|
31
|
-
const value = activeCtx.getValue(key)
|
|
32
|
-
if (value !== undefined) {
|
|
33
|
-
newCtx = newCtx.setValue(key, value)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return newCtx
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function span<T>(name: string, fn: () => T, tracer?: Tracer): T {
|
|
41
|
-
const activeTracer = tracer ?? TRACE_API.getTracer(name)
|
|
42
|
-
if (isDefined(activeTracer)) {
|
|
43
|
-
const span = activeTracer.startSpan(name)
|
|
44
|
-
return context.with(TRACE_API.setSpan(context.active(), span), () => {
|
|
45
|
-
try {
|
|
46
|
-
const result = fn()
|
|
47
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
48
|
-
return result
|
|
49
|
-
} catch (ex) {
|
|
50
|
-
const error = ex as Error
|
|
51
|
-
span.recordException(error)
|
|
52
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
|
|
53
|
-
throw ex
|
|
54
|
-
} finally {
|
|
55
|
-
span.end()
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
} else {
|
|
59
|
-
return fn()
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function spanRoot<T>(name: string, fn: () => T, tracer?: Tracer): T {
|
|
64
|
-
const activeTracer = tracer ?? TRACE_API.getTracer(name)
|
|
65
|
-
if (isDefined(activeTracer)) {
|
|
66
|
-
// Get current active context for configuration
|
|
67
|
-
const activeContext = context.active()
|
|
68
|
-
|
|
69
|
-
// Create a new context with no active span
|
|
70
|
-
const noSpanContext = cloneContextWithoutSpan(activeContext)
|
|
71
|
-
|
|
72
|
-
// Create a new span in the context without an active span
|
|
73
|
-
const span = activeTracer.startSpan(name, {}, noSpanContext)
|
|
74
|
-
|
|
75
|
-
// Use the active context but replace its span with our new root span
|
|
76
|
-
return context.with(TRACE_API.setSpan(noSpanContext, span), () => {
|
|
77
|
-
try {
|
|
78
|
-
const result = fn()
|
|
79
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
80
|
-
return result
|
|
81
|
-
} catch (ex) {
|
|
82
|
-
const error = ex as Error
|
|
83
|
-
span.recordException(error)
|
|
84
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
|
|
85
|
-
throw ex
|
|
86
|
-
} finally {
|
|
87
|
-
span.end()
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
} else {
|
|
91
|
-
return fn()
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function spanAsync<T>(
|
|
96
|
-
name: string,
|
|
97
|
-
fn: () => Promise<T>,
|
|
98
|
-
{
|
|
99
|
-
timeBudgetLimit, logger, tracer,
|
|
100
|
-
}: SpanConfig = {},
|
|
101
|
-
): Promise<T> {
|
|
102
|
-
const activeTracer = tracer ?? TRACE_API.getTracer(name)
|
|
103
|
-
const funcToRun = isDefined(timeBudgetLimit) ? () => timeBudget(name, logger ?? console, fn, timeBudgetLimit) : fn
|
|
104
|
-
if (isDefined(activeTracer)) {
|
|
105
|
-
const span = activeTracer.startSpan(name)
|
|
106
|
-
return await context.with(TRACE_API.setSpan(context.active(), span), async () => {
|
|
107
|
-
try {
|
|
108
|
-
const result = await funcToRun()
|
|
109
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
110
|
-
return result
|
|
111
|
-
} catch (ex) {
|
|
112
|
-
const error = ex as Error
|
|
113
|
-
span.recordException(error)
|
|
114
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
|
|
115
|
-
throw ex
|
|
116
|
-
} finally {
|
|
117
|
-
span.end()
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
|
-
} else {
|
|
121
|
-
return await funcToRun()
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export async function spanRootAsync<T>(
|
|
126
|
-
name: string,
|
|
127
|
-
fn: () => Promise<T>,
|
|
128
|
-
{
|
|
129
|
-
timeBudgetLimit, logger, tracer,
|
|
130
|
-
}: SpanConfig = {},
|
|
131
|
-
): Promise<T> {
|
|
132
|
-
const funcToRun = isDefined(timeBudgetLimit) ? () => timeBudget(name, logger ?? console, fn, timeBudgetLimit) : fn
|
|
133
|
-
const activeTracer = tracer ?? TRACE_API.getTracer(name)
|
|
134
|
-
if (isDefined(activeTracer)) {
|
|
135
|
-
const activeContext = context.active()
|
|
136
|
-
|
|
137
|
-
const noSpanContext = cloneContextWithoutSpan(activeContext)
|
|
138
|
-
|
|
139
|
-
// Create a new span in the context without an active span
|
|
140
|
-
const span = activeTracer.startSpan(name, {}, noSpanContext)
|
|
141
|
-
|
|
142
|
-
// Use the active context but replace its span with our new root span
|
|
143
|
-
return await context.with(TRACE_API.setSpan(noSpanContext, span), async () => {
|
|
144
|
-
try {
|
|
145
|
-
const result = await funcToRun()
|
|
146
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
147
|
-
return result
|
|
148
|
-
} catch (ex) {
|
|
149
|
-
const error = ex as Error
|
|
150
|
-
span.recordException(error)
|
|
151
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
|
|
152
|
-
throw ex
|
|
153
|
-
} finally {
|
|
154
|
-
span.end()
|
|
155
|
-
}
|
|
156
|
-
})
|
|
157
|
-
} else {
|
|
158
|
-
return await funcToRun()
|
|
159
|
-
}
|
|
160
|
-
}
|
package/src/timeBudget.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '@xylabs/logger'
|
|
2
|
-
|
|
3
|
-
export async function timeBudget<TResult>(
|
|
4
|
-
name: string,
|
|
5
|
-
logger: Logger | undefined,
|
|
6
|
-
func: () => Promise<TResult>,
|
|
7
|
-
budget: number,
|
|
8
|
-
status = false,
|
|
9
|
-
): Promise<TResult> {
|
|
10
|
-
const start = Date.now()
|
|
11
|
-
const timer = status
|
|
12
|
-
? setInterval(() => {
|
|
13
|
-
const duration = Date.now() - start
|
|
14
|
-
if ((budget > 0) && (duration > budget)) {
|
|
15
|
-
logger?.warn(`Function [${name}] execution is exceeding budget: ${duration}ms > ${budget}ms`)
|
|
16
|
-
}
|
|
17
|
-
}, Math.max(100, budget))
|
|
18
|
-
: undefined
|
|
19
|
-
|
|
20
|
-
const result = await func()
|
|
21
|
-
const duration = Date.now() - start
|
|
22
|
-
|
|
23
|
-
if (!timer && (budget > 0) && (duration > budget)) {
|
|
24
|
-
logger?.warn(`Function [${name}] execution exceeded budget: ${duration}ms > ${budget}ms`)
|
|
25
|
-
}
|
|
26
|
-
if (timer) {
|
|
27
|
-
clearInterval(timer)
|
|
28
|
-
}
|
|
29
|
-
return result
|
|
30
|
-
}
|