@bentocache/otel 0.1.2 → 0.2.0
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 +2 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +123 -24
- package/package.json +44 -34
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Official OpenTelemetry instrumentation for Bentocache.
|
|
|
8
8
|
pnpm add @bentocache/otel
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Requires OpenTelemetry JS SDK 3 (`@opentelemetry/api` 1.10) and Node.js 22.15.0 or newer. For OpenTelemetry SDK 2, use `@bentocache/otel@0.1.x`.
|
|
12
|
+
|
|
11
13
|
## Usage
|
|
12
14
|
|
|
13
15
|
```ts
|
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Span } from '@opentelemetry/api';
|
|
2
1
|
import { CacheOperationMessage } from 'bentocache';
|
|
2
|
+
import { Span } from '@opentelemetry/api';
|
|
3
3
|
import { TracingChannelSubscribers } from 'node:diagnostics_channel';
|
|
4
4
|
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
5
5
|
import { BentoCacheInstrumentationConfig, BentoCacheModuleExports } from './src/types.js';
|
package/build/index.js
CHANGED
|
@@ -5,6 +5,105 @@ import {
|
|
|
5
5
|
InstrumentationBase,
|
|
6
6
|
InstrumentationNodeModuleDefinition
|
|
7
7
|
} from "@opentelemetry/instrumentation";
|
|
8
|
+
|
|
9
|
+
// package.json
|
|
10
|
+
var package_default = {
|
|
11
|
+
name: "@bentocache/otel",
|
|
12
|
+
version: "0.2.0",
|
|
13
|
+
description: "OpenTelemetry instrumentation for Bentocache",
|
|
14
|
+
keywords: [
|
|
15
|
+
"bentocache",
|
|
16
|
+
"instrumentation",
|
|
17
|
+
"opentelemetry",
|
|
18
|
+
"otel",
|
|
19
|
+
"tracing"
|
|
20
|
+
],
|
|
21
|
+
license: "MIT",
|
|
22
|
+
author: "Julien Ripouteau <julien@ripouteau.com>",
|
|
23
|
+
repository: {
|
|
24
|
+
type: "git",
|
|
25
|
+
url: "git+https://github.com/Julien-R44/bentocache.git",
|
|
26
|
+
directory: "packages/otel"
|
|
27
|
+
},
|
|
28
|
+
files: [
|
|
29
|
+
"build"
|
|
30
|
+
],
|
|
31
|
+
type: "module",
|
|
32
|
+
main: "build/index.js",
|
|
33
|
+
exports: {
|
|
34
|
+
".": "./build/index.js",
|
|
35
|
+
"./types": "./build/src/types.js"
|
|
36
|
+
},
|
|
37
|
+
publishConfig: {
|
|
38
|
+
access: "public",
|
|
39
|
+
tag: "latest"
|
|
40
|
+
},
|
|
41
|
+
scripts: {
|
|
42
|
+
test: "c8 pnpm quick:test",
|
|
43
|
+
"quick:test": "cross-env NODE_NO_WARNINGS=1 node --enable-source-maps --import=tsx bin/test.ts",
|
|
44
|
+
build: "tsup-node",
|
|
45
|
+
typecheck: "tsc --noEmit",
|
|
46
|
+
lint: "oxlint",
|
|
47
|
+
release: "pnpm build && pnpm release-it",
|
|
48
|
+
prepublishOnly: "pnpm build",
|
|
49
|
+
checks: "pnpm lint && pnpm typecheck"
|
|
50
|
+
},
|
|
51
|
+
dependencies: {
|
|
52
|
+
"@opentelemetry/core": "^3.1.1",
|
|
53
|
+
"@opentelemetry/instrumentation": "^0.301.1"
|
|
54
|
+
},
|
|
55
|
+
devDependencies: {
|
|
56
|
+
"@julr/utils": "^1.9.0",
|
|
57
|
+
"@opentelemetry/api": "^1.10.0",
|
|
58
|
+
"@opentelemetry/context-async-hooks": "^3.1.1",
|
|
59
|
+
"@opentelemetry/sdk-trace": "^3.1.1",
|
|
60
|
+
bentocache: "workspace:*"
|
|
61
|
+
},
|
|
62
|
+
peerDependencies: {
|
|
63
|
+
"@opentelemetry/api": "^1.10.0",
|
|
64
|
+
bentocache: "^1.6.0"
|
|
65
|
+
},
|
|
66
|
+
c8: {
|
|
67
|
+
exclude: [
|
|
68
|
+
"bin",
|
|
69
|
+
"tests/**",
|
|
70
|
+
"test_helpers/**",
|
|
71
|
+
"factories/**"
|
|
72
|
+
],
|
|
73
|
+
reporter: [
|
|
74
|
+
"text",
|
|
75
|
+
"html"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
engines: {
|
|
79
|
+
node: ">=22.15.0"
|
|
80
|
+
},
|
|
81
|
+
"release-it": {
|
|
82
|
+
git: {
|
|
83
|
+
commitMessage: "chore(release): @bentocache/otel@${version}",
|
|
84
|
+
tagAnnotation: "release ${version}",
|
|
85
|
+
tagName: "@bentocache/otel@${version}"
|
|
86
|
+
},
|
|
87
|
+
github: {
|
|
88
|
+
release: true,
|
|
89
|
+
releaseName: "@bentocache/otel@${version}",
|
|
90
|
+
web: true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
tsup: {
|
|
94
|
+
entry: [
|
|
95
|
+
"./index.ts",
|
|
96
|
+
"./src/types.ts"
|
|
97
|
+
],
|
|
98
|
+
outDir: "./build",
|
|
99
|
+
clean: true,
|
|
100
|
+
format: "esm",
|
|
101
|
+
dts: true,
|
|
102
|
+
target: "esnext"
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/instrumentation.ts
|
|
8
107
|
var DEFAULT_CONFIG = {
|
|
9
108
|
requireParentSpan: true,
|
|
10
109
|
includeKeys: false,
|
|
@@ -16,10 +115,11 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
16
115
|
spans = /* @__PURE__ */ new WeakMap();
|
|
17
116
|
handlers;
|
|
18
117
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
118
|
+
* Context tokens attached on `start` and disposed on the synchronous `end`
|
|
119
|
+
* event, so the operation span is the active context for everything the
|
|
120
|
+
* operation runs: nested cache operations and the user factory.
|
|
21
121
|
*/
|
|
22
|
-
#
|
|
122
|
+
#contextTokens = /* @__PURE__ */ new WeakMap();
|
|
23
123
|
#cacheOperation;
|
|
24
124
|
#originalBentoCache;
|
|
25
125
|
/**
|
|
@@ -42,20 +142,22 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
42
142
|
}
|
|
43
143
|
if (moduleExports.BentoCache !== this.#originalBentoCache) return;
|
|
44
144
|
const original = this.#originalBentoCache;
|
|
45
|
-
const
|
|
145
|
+
const patchConfig = this.#patchConfig.bind(this);
|
|
46
146
|
const BentoCachePatched = class BentoCachePatched extends original {
|
|
47
147
|
/**
|
|
48
148
|
* Wraps user config before delegating to the original BentoCache constructor.
|
|
49
149
|
*/
|
|
50
150
|
constructor(config) {
|
|
51
|
-
super(
|
|
151
|
+
super(patchConfig(config));
|
|
52
152
|
}
|
|
53
153
|
};
|
|
54
154
|
Object.setPrototypeOf(BentoCachePatched, original);
|
|
55
155
|
try {
|
|
56
156
|
moduleExports.BentoCache = BentoCachePatched;
|
|
57
157
|
} catch {
|
|
58
|
-
|
|
158
|
+
this._diag.warn(
|
|
159
|
+
"Cannot patch the BentoCache constructor because the module exports are read-only (ESM namespace). suppressInternalOperations has no effect on caches created from these exports."
|
|
160
|
+
);
|
|
59
161
|
}
|
|
60
162
|
}
|
|
61
163
|
/**
|
|
@@ -93,8 +195,7 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
93
195
|
this.subscribed = true;
|
|
94
196
|
this.handlers = {
|
|
95
197
|
start: (message) => this.#handleStart(message),
|
|
96
|
-
end: () =>
|
|
97
|
-
},
|
|
198
|
+
end: (message) => this.#handleEnd(message),
|
|
98
199
|
asyncStart: () => {
|
|
99
200
|
},
|
|
100
201
|
asyncEnd: (message) => this.#handleAsyncEnd(message),
|
|
@@ -111,17 +212,15 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
111
212
|
this.subscribed = false;
|
|
112
213
|
this.handlers = void 0;
|
|
113
214
|
this.spans = /* @__PURE__ */ new WeakMap();
|
|
114
|
-
this.#activeContexts.clear();
|
|
115
215
|
}
|
|
116
216
|
/**
|
|
117
|
-
* Starts a span for each cache operation
|
|
217
|
+
* Starts a span for each cache operation and makes it the active context
|
|
218
|
+
* while the operation runs, so nested operations and the factory are parented to it.
|
|
118
219
|
*/
|
|
119
220
|
#handleStart(message) {
|
|
120
221
|
const config = this.getConfig();
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
const parentSpan = trace.getSpan(parentContext);
|
|
124
|
-
if (config.requireParentSpan && !parentSpan) return;
|
|
222
|
+
const parentContext = context.active();
|
|
223
|
+
if (config.requireParentSpan && !trace.getSpan(parentContext)) return;
|
|
125
224
|
const spanName = this.#getSpanName(message);
|
|
126
225
|
const span = this.tracer.startSpan(
|
|
127
226
|
spanName,
|
|
@@ -132,9 +231,15 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
132
231
|
parentContext
|
|
133
232
|
);
|
|
134
233
|
this.spans.set(message, span);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
234
|
+
this.#contextTokens.set(message, context.attach(trace.setSpan(parentContext, span)));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Restores the caller context once the operation has returned its promise.
|
|
238
|
+
* Async continuations created by the operation keep the attached context.
|
|
239
|
+
*/
|
|
240
|
+
#handleEnd(message) {
|
|
241
|
+
this.#contextTokens.get(message)?.dispose();
|
|
242
|
+
this.#contextTokens.delete(message);
|
|
138
243
|
}
|
|
139
244
|
/**
|
|
140
245
|
* Finalizes successful async spans and records result attributes.
|
|
@@ -147,9 +252,6 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
147
252
|
if (message.graced !== void 0) span.setAttribute("cache.graced", message.graced);
|
|
148
253
|
span.end();
|
|
149
254
|
this.spans.delete(message);
|
|
150
|
-
if (message.operation === "getOrSet") {
|
|
151
|
-
this.#activeContexts.delete(`${message.store}:${message.key}`);
|
|
152
|
-
}
|
|
153
255
|
}
|
|
154
256
|
/**
|
|
155
257
|
* Finalizes failed spans and records exception details when available.
|
|
@@ -163,9 +265,6 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
163
265
|
}
|
|
164
266
|
span.end();
|
|
165
267
|
this.spans.delete(message);
|
|
166
|
-
if (message.operation === "getOrSet") {
|
|
167
|
-
this.#activeContexts.delete(`${message.store}:${message.key}`);
|
|
168
|
-
}
|
|
169
268
|
}
|
|
170
269
|
/**
|
|
171
270
|
* Builds the final span name using custom naming or the configured prefix.
|
|
@@ -201,7 +300,7 @@ var BentoCacheInstrumentation = class extends InstrumentationBase {
|
|
|
201
300
|
* Creates a new instrumentation instance with default and user config merged.
|
|
202
301
|
*/
|
|
203
302
|
constructor(config = {}) {
|
|
204
|
-
super(
|
|
303
|
+
super(package_default.name, package_default.version, { ...DEFAULT_CONFIG, ...config });
|
|
205
304
|
}
|
|
206
305
|
/**
|
|
207
306
|
* Applies runtime config updates while preserving default values.
|
package/package.json
CHANGED
|
@@ -1,64 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bentocache/otel",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.1.2",
|
|
3
|
+
"version": "0.2.0",
|
|
5
4
|
"description": "OpenTelemetry instrumentation for Bentocache",
|
|
6
|
-
"author": "Julien Ripouteau <julien@ripouteau.com>",
|
|
7
|
-
"license": "MIT",
|
|
8
5
|
"keywords": [
|
|
9
6
|
"bentocache",
|
|
7
|
+
"instrumentation",
|
|
10
8
|
"opentelemetry",
|
|
11
9
|
"otel",
|
|
12
|
-
"instrumentation",
|
|
13
10
|
"tracing"
|
|
14
11
|
],
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Julien Ripouteau <julien@ripouteau.com>",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/Julien-R44/bentocache.git",
|
|
17
|
+
"directory": "packages/otel"
|
|
18
18
|
},
|
|
19
|
-
"main": "build/index.js",
|
|
20
19
|
"files": [
|
|
21
20
|
"build"
|
|
22
21
|
],
|
|
23
|
-
"
|
|
24
|
-
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "build/index.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./build/index.js",
|
|
26
|
+
"./types": "./build/src/types.js"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public",
|
|
30
|
+
"tag": "latest"
|
|
25
31
|
},
|
|
26
32
|
"dependencies": {
|
|
27
|
-
"@opentelemetry/
|
|
28
|
-
"@opentelemetry/
|
|
29
|
-
"@opentelemetry/instrumentation": "^0.211.0"
|
|
33
|
+
"@opentelemetry/core": "^3.1.1",
|
|
34
|
+
"@opentelemetry/instrumentation": "^0.301.1"
|
|
30
35
|
},
|
|
31
36
|
"devDependencies": {
|
|
32
37
|
"@julr/utils": "^1.9.0",
|
|
33
|
-
"@opentelemetry/
|
|
38
|
+
"@opentelemetry/api": "^1.10.0",
|
|
39
|
+
"@opentelemetry/context-async-hooks": "^3.1.1",
|
|
40
|
+
"@opentelemetry/sdk-trace": "^3.1.1",
|
|
34
41
|
"bentocache": "1.6.1"
|
|
35
42
|
},
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
"./src/types.ts"
|
|
40
|
-
],
|
|
41
|
-
"outDir": "./build",
|
|
42
|
-
"clean": true,
|
|
43
|
-
"format": "esm",
|
|
44
|
-
"dts": true,
|
|
45
|
-
"target": "esnext"
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@opentelemetry/api": "^1.10.0",
|
|
45
|
+
"bentocache": "^1.6.0"
|
|
46
46
|
},
|
|
47
47
|
"c8": {
|
|
48
|
-
"reporter": [
|
|
49
|
-
"text",
|
|
50
|
-
"html"
|
|
51
|
-
],
|
|
52
48
|
"exclude": [
|
|
53
49
|
"bin",
|
|
54
50
|
"tests/**",
|
|
55
51
|
"test_helpers/**",
|
|
56
52
|
"factories/**"
|
|
53
|
+
],
|
|
54
|
+
"reporter": [
|
|
55
|
+
"text",
|
|
56
|
+
"html"
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"tag": "latest"
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=22.15.0"
|
|
62
61
|
},
|
|
63
62
|
"release-it": {
|
|
64
63
|
"git": {
|
|
@@ -72,12 +71,23 @@
|
|
|
72
71
|
"web": true
|
|
73
72
|
}
|
|
74
73
|
},
|
|
74
|
+
"tsup": {
|
|
75
|
+
"entry": [
|
|
76
|
+
"./index.ts",
|
|
77
|
+
"./src/types.ts"
|
|
78
|
+
],
|
|
79
|
+
"outDir": "./build",
|
|
80
|
+
"clean": true,
|
|
81
|
+
"format": "esm",
|
|
82
|
+
"dts": true,
|
|
83
|
+
"target": "esnext"
|
|
84
|
+
},
|
|
75
85
|
"scripts": {
|
|
76
86
|
"test": "c8 pnpm quick:test",
|
|
77
|
-
"quick:test": "cross-env NODE_NO_WARNINGS=1 node --enable-source-maps --
|
|
87
|
+
"quick:test": "cross-env NODE_NO_WARNINGS=1 node --enable-source-maps --import=tsx bin/test.ts",
|
|
78
88
|
"build": "tsup-node",
|
|
79
89
|
"typecheck": "tsc --noEmit",
|
|
80
|
-
"lint": "
|
|
90
|
+
"lint": "oxlint",
|
|
81
91
|
"release": "pnpm build && pnpm release-it",
|
|
82
92
|
"checks": "pnpm lint && pnpm typecheck"
|
|
83
93
|
}
|