autotel-cloudflare 2.1.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/LICENSE +21 -0
- package/README.md +432 -0
- package/dist/actors.d.ts +248 -0
- package/dist/actors.js +1030 -0
- package/dist/actors.js.map +1 -0
- package/dist/agents.d.ts +219 -0
- package/dist/agents.js +276 -0
- package/dist/agents.js.map +1 -0
- package/dist/bindings.d.ts +40 -0
- package/dist/bindings.js +4 -0
- package/dist/bindings.js.map +1 -0
- package/dist/chunk-JDPN3HND.js +520 -0
- package/dist/chunk-JDPN3HND.js.map +1 -0
- package/dist/chunk-QXFYTHQF.js +298 -0
- package/dist/chunk-QXFYTHQF.js.map +1 -0
- package/dist/chunk-SKKRPS5K.js +50 -0
- package/dist/chunk-SKKRPS5K.js.map +1 -0
- package/dist/events.d.ts +1 -0
- package/dist/events.js +3 -0
- package/dist/events.js.map +1 -0
- package/dist/handlers.d.ts +121 -0
- package/dist/handlers.js +4 -0
- package/dist/handlers.js.map +1 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +576 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +3 -0
- package/dist/logger.js.map +1 -0
- package/dist/sampling.d.ts +4 -0
- package/dist/sampling.js +3 -0
- package/dist/sampling.js.map +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +1 -0
- package/package.json +107 -0
- package/src/actors/alarms.ts +225 -0
- package/src/actors/index.ts +36 -0
- package/src/actors/instrument-actor.test.ts +179 -0
- package/src/actors/instrument-actor.ts +574 -0
- package/src/actors/sockets.ts +217 -0
- package/src/actors/storage.ts +263 -0
- package/src/actors/traced-handler.ts +300 -0
- package/src/actors/types.ts +98 -0
- package/src/actors.ts +50 -0
- package/src/agents/index.ts +42 -0
- package/src/agents/otel-observability.test.ts +329 -0
- package/src/agents/otel-observability.ts +465 -0
- package/src/agents/types.ts +167 -0
- package/src/agents.ts +76 -0
- package/src/bindings/bindings.ts +621 -0
- package/src/bindings/common.ts +75 -0
- package/src/bindings/index.ts +12 -0
- package/src/bindings.ts +6 -0
- package/src/events.ts +6 -0
- package/src/global/cache.test.ts +292 -0
- package/src/global/cache.ts +164 -0
- package/src/global/fetch.test.ts +344 -0
- package/src/global/fetch.ts +134 -0
- package/src/global/index.ts +7 -0
- package/src/handlers/durable-objects.test.ts +524 -0
- package/src/handlers/durable-objects.ts +250 -0
- package/src/handlers/index.ts +6 -0
- package/src/handlers/workflows.ts +318 -0
- package/src/handlers.ts +6 -0
- package/src/index.ts +57 -0
- package/src/logger.ts +6 -0
- package/src/sampling.ts +6 -0
- package/src/testing.ts +6 -0
- package/src/wrappers/index.ts +8 -0
- package/src/wrappers/instrument.integration.test.ts +468 -0
- package/src/wrappers/instrument.ts +643 -0
- package/src/wrappers/wrap-do.ts +34 -0
- package/src/wrappers/wrap-module.ts +37 -0
package/dist/actors.js
ADDED
|
@@ -0,0 +1,1030 @@
|
|
|
1
|
+
import { wrap } from './chunk-SKKRPS5K.js';
|
|
2
|
+
import { propagation, SpanKind, SpanStatusCode, context, trace } from '@opentelemetry/api';
|
|
3
|
+
import { createInitialiser, setConfig } from 'autotel-edge';
|
|
4
|
+
|
|
5
|
+
function getTracer() {
|
|
6
|
+
return trace.getTracer("autotel-cloudflare-actors");
|
|
7
|
+
}
|
|
8
|
+
function instrumentActorStorage(storage, actorInstance, actorClass) {
|
|
9
|
+
if (!storage || typeof storage !== "object") {
|
|
10
|
+
return storage;
|
|
11
|
+
}
|
|
12
|
+
const actorClassName = actorClass.name || "Actor";
|
|
13
|
+
const actorName = actorInstance.name || actorClassName;
|
|
14
|
+
const storageHandler = {
|
|
15
|
+
get(target, prop) {
|
|
16
|
+
const value = Reflect.get(target, prop);
|
|
17
|
+
if (prop === "exec" && typeof value === "function") {
|
|
18
|
+
return function instrumentedExec(query, ...params) {
|
|
19
|
+
const tracer = getTracer();
|
|
20
|
+
const spanName = `Actor ${actorName}: storage.exec`;
|
|
21
|
+
return tracer.startActiveSpan(
|
|
22
|
+
spanName,
|
|
23
|
+
{
|
|
24
|
+
kind: SpanKind.CLIENT,
|
|
25
|
+
attributes: {
|
|
26
|
+
"actor.name": actorName,
|
|
27
|
+
"actor.class": actorClassName,
|
|
28
|
+
"db.system": "sqlite",
|
|
29
|
+
"db.operation": "exec",
|
|
30
|
+
"db.statement": query,
|
|
31
|
+
"db.statement.params_count": params.length
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
(span) => {
|
|
35
|
+
try {
|
|
36
|
+
const result = value.call(target, query, ...params);
|
|
37
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
38
|
+
return result;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
span.recordException(error);
|
|
41
|
+
span.setStatus({
|
|
42
|
+
code: SpanStatusCode.ERROR,
|
|
43
|
+
message: error instanceof Error ? error.message : String(error)
|
|
44
|
+
});
|
|
45
|
+
throw error;
|
|
46
|
+
} finally {
|
|
47
|
+
span.end();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (prop === "query" && typeof value === "function") {
|
|
54
|
+
return function instrumentedQuery(query, ...params) {
|
|
55
|
+
const tracer = getTracer();
|
|
56
|
+
const spanName = `Actor ${actorName}: storage.query`;
|
|
57
|
+
return tracer.startActiveSpan(
|
|
58
|
+
spanName,
|
|
59
|
+
{
|
|
60
|
+
kind: SpanKind.CLIENT,
|
|
61
|
+
attributes: {
|
|
62
|
+
"actor.name": actorName,
|
|
63
|
+
"actor.class": actorClassName,
|
|
64
|
+
"db.system": "sqlite",
|
|
65
|
+
"db.operation": "query",
|
|
66
|
+
"db.statement": query,
|
|
67
|
+
"db.statement.params_count": params.length
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
(span) => {
|
|
71
|
+
try {
|
|
72
|
+
const result = value.call(target, query, ...params);
|
|
73
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
74
|
+
return result;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
span.recordException(error);
|
|
77
|
+
span.setStatus({
|
|
78
|
+
code: SpanStatusCode.ERROR,
|
|
79
|
+
message: error instanceof Error ? error.message : String(error)
|
|
80
|
+
});
|
|
81
|
+
throw error;
|
|
82
|
+
} finally {
|
|
83
|
+
span.end();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (prop === "get" && typeof value === "function") {
|
|
90
|
+
return async function instrumentedGet(key) {
|
|
91
|
+
const tracer = getTracer();
|
|
92
|
+
const spanName = `Actor ${actorName}: storage.get`;
|
|
93
|
+
return tracer.startActiveSpan(
|
|
94
|
+
spanName,
|
|
95
|
+
{
|
|
96
|
+
kind: SpanKind.CLIENT,
|
|
97
|
+
attributes: {
|
|
98
|
+
"actor.name": actorName,
|
|
99
|
+
"actor.class": actorClassName,
|
|
100
|
+
"db.system": "durable_object_storage",
|
|
101
|
+
"db.operation": "get",
|
|
102
|
+
"db.key": key
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
async (span) => {
|
|
106
|
+
try {
|
|
107
|
+
const result = await value.call(target, key);
|
|
108
|
+
span.setAttributes({
|
|
109
|
+
"db.result.found": result !== null && result !== void 0
|
|
110
|
+
});
|
|
111
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
112
|
+
return result;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
span.recordException(error);
|
|
115
|
+
span.setStatus({
|
|
116
|
+
code: SpanStatusCode.ERROR,
|
|
117
|
+
message: error instanceof Error ? error.message : String(error)
|
|
118
|
+
});
|
|
119
|
+
throw error;
|
|
120
|
+
} finally {
|
|
121
|
+
span.end();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (prop === "put" && typeof value === "function") {
|
|
128
|
+
return async function instrumentedPut(key, val) {
|
|
129
|
+
const tracer = getTracer();
|
|
130
|
+
const spanName = `Actor ${actorName}: storage.put`;
|
|
131
|
+
return tracer.startActiveSpan(
|
|
132
|
+
spanName,
|
|
133
|
+
{
|
|
134
|
+
kind: SpanKind.CLIENT,
|
|
135
|
+
attributes: {
|
|
136
|
+
"actor.name": actorName,
|
|
137
|
+
"actor.class": actorClassName,
|
|
138
|
+
"db.system": "durable_object_storage",
|
|
139
|
+
"db.operation": "put",
|
|
140
|
+
"db.key": key,
|
|
141
|
+
"db.value_type": typeof val
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
async (span) => {
|
|
145
|
+
try {
|
|
146
|
+
await value.call(target, key, val);
|
|
147
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
148
|
+
} catch (error) {
|
|
149
|
+
span.recordException(error);
|
|
150
|
+
span.setStatus({
|
|
151
|
+
code: SpanStatusCode.ERROR,
|
|
152
|
+
message: error instanceof Error ? error.message : String(error)
|
|
153
|
+
});
|
|
154
|
+
throw error;
|
|
155
|
+
} finally {
|
|
156
|
+
span.end();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (prop === "delete" && typeof value === "function") {
|
|
163
|
+
return async function instrumentedDelete(key) {
|
|
164
|
+
const tracer = getTracer();
|
|
165
|
+
const spanName = `Actor ${actorName}: storage.delete`;
|
|
166
|
+
return tracer.startActiveSpan(
|
|
167
|
+
spanName,
|
|
168
|
+
{
|
|
169
|
+
kind: SpanKind.CLIENT,
|
|
170
|
+
attributes: {
|
|
171
|
+
"actor.name": actorName,
|
|
172
|
+
"actor.class": actorClassName,
|
|
173
|
+
"db.system": "durable_object_storage",
|
|
174
|
+
"db.operation": "delete",
|
|
175
|
+
"db.key": key
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
async (span) => {
|
|
179
|
+
try {
|
|
180
|
+
const result = await value.call(target, key);
|
|
181
|
+
span.setAttributes({
|
|
182
|
+
"db.result.deleted": result
|
|
183
|
+
});
|
|
184
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
185
|
+
return result;
|
|
186
|
+
} catch (error) {
|
|
187
|
+
span.recordException(error);
|
|
188
|
+
span.setStatus({
|
|
189
|
+
code: SpanStatusCode.ERROR,
|
|
190
|
+
message: error instanceof Error ? error.message : String(error)
|
|
191
|
+
});
|
|
192
|
+
throw error;
|
|
193
|
+
} finally {
|
|
194
|
+
span.end();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (typeof value === "function") {
|
|
201
|
+
return value.bind(target);
|
|
202
|
+
}
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
return wrap(storage, storageHandler);
|
|
207
|
+
}
|
|
208
|
+
function getTracer2() {
|
|
209
|
+
return trace.getTracer("autotel-cloudflare-actors");
|
|
210
|
+
}
|
|
211
|
+
function instrumentActorAlarms(alarms, actorInstance, actorClass) {
|
|
212
|
+
if (!alarms || typeof alarms !== "object") {
|
|
213
|
+
return alarms;
|
|
214
|
+
}
|
|
215
|
+
const actorClassName = actorClass.name || "Actor";
|
|
216
|
+
const actorName = actorInstance.name || actorClassName;
|
|
217
|
+
const alarmsHandler = {
|
|
218
|
+
get(target, prop) {
|
|
219
|
+
const value = Reflect.get(target, prop);
|
|
220
|
+
if (prop === "set" && typeof value === "function") {
|
|
221
|
+
return async function instrumentedSet(...args) {
|
|
222
|
+
const tracer = getTracer2();
|
|
223
|
+
const spanName = `Actor ${actorName}: alarms.set`;
|
|
224
|
+
const alarmAttributes = {
|
|
225
|
+
"actor.name": actorName,
|
|
226
|
+
"actor.class": actorClassName,
|
|
227
|
+
"alarm.operation": "set"
|
|
228
|
+
};
|
|
229
|
+
if (args.length > 0) {
|
|
230
|
+
const firstArg = args[0];
|
|
231
|
+
if (typeof firstArg === "number") {
|
|
232
|
+
alarmAttributes["alarm.delay_ms"] = firstArg;
|
|
233
|
+
} else if (firstArg instanceof Date) {
|
|
234
|
+
alarmAttributes["alarm.scheduled_time"] = firstArg.toISOString();
|
|
235
|
+
} else if (typeof firstArg === "string") {
|
|
236
|
+
alarmAttributes["alarm.cron"] = firstArg;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return tracer.startActiveSpan(
|
|
240
|
+
spanName,
|
|
241
|
+
{
|
|
242
|
+
kind: SpanKind.CLIENT,
|
|
243
|
+
attributes: alarmAttributes
|
|
244
|
+
},
|
|
245
|
+
async (span) => {
|
|
246
|
+
try {
|
|
247
|
+
const result = await value.apply(target, args);
|
|
248
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
249
|
+
return result;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
span.recordException(error);
|
|
252
|
+
span.setStatus({
|
|
253
|
+
code: SpanStatusCode.ERROR,
|
|
254
|
+
message: error instanceof Error ? error.message : String(error)
|
|
255
|
+
});
|
|
256
|
+
throw error;
|
|
257
|
+
} finally {
|
|
258
|
+
span.end();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (prop === "setMultiple" && typeof value === "function") {
|
|
265
|
+
return async function instrumentedSetMultiple(alarmDefs) {
|
|
266
|
+
const tracer = getTracer2();
|
|
267
|
+
const spanName = `Actor ${actorName}: alarms.setMultiple`;
|
|
268
|
+
return tracer.startActiveSpan(
|
|
269
|
+
spanName,
|
|
270
|
+
{
|
|
271
|
+
kind: SpanKind.CLIENT,
|
|
272
|
+
attributes: {
|
|
273
|
+
"actor.name": actorName,
|
|
274
|
+
"actor.class": actorClassName,
|
|
275
|
+
"alarm.operation": "setMultiple",
|
|
276
|
+
"alarm.count": Array.isArray(alarmDefs) ? alarmDefs.length : 0
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
async (span) => {
|
|
280
|
+
try {
|
|
281
|
+
const result = await value.call(target, alarmDefs);
|
|
282
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
283
|
+
return result;
|
|
284
|
+
} catch (error) {
|
|
285
|
+
span.recordException(error);
|
|
286
|
+
span.setStatus({
|
|
287
|
+
code: SpanStatusCode.ERROR,
|
|
288
|
+
message: error instanceof Error ? error.message : String(error)
|
|
289
|
+
});
|
|
290
|
+
throw error;
|
|
291
|
+
} finally {
|
|
292
|
+
span.end();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (prop === "cancel" && typeof value === "function") {
|
|
299
|
+
return async function instrumentedCancel(alarmId) {
|
|
300
|
+
const tracer = getTracer2();
|
|
301
|
+
const spanName = `Actor ${actorName}: alarms.cancel`;
|
|
302
|
+
return tracer.startActiveSpan(
|
|
303
|
+
spanName,
|
|
304
|
+
{
|
|
305
|
+
kind: SpanKind.CLIENT,
|
|
306
|
+
attributes: {
|
|
307
|
+
"actor.name": actorName,
|
|
308
|
+
"actor.class": actorClassName,
|
|
309
|
+
"alarm.operation": "cancel",
|
|
310
|
+
"alarm.id": alarmId
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
async (span) => {
|
|
314
|
+
try {
|
|
315
|
+
const result = await value.call(target, alarmId);
|
|
316
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
317
|
+
return result;
|
|
318
|
+
} catch (error) {
|
|
319
|
+
span.recordException(error);
|
|
320
|
+
span.setStatus({
|
|
321
|
+
code: SpanStatusCode.ERROR,
|
|
322
|
+
message: error instanceof Error ? error.message : String(error)
|
|
323
|
+
});
|
|
324
|
+
throw error;
|
|
325
|
+
} finally {
|
|
326
|
+
span.end();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
if (prop === "cancelAll" && typeof value === "function") {
|
|
333
|
+
return async function instrumentedCancelAll() {
|
|
334
|
+
const tracer = getTracer2();
|
|
335
|
+
const spanName = `Actor ${actorName}: alarms.cancelAll`;
|
|
336
|
+
return tracer.startActiveSpan(
|
|
337
|
+
spanName,
|
|
338
|
+
{
|
|
339
|
+
kind: SpanKind.CLIENT,
|
|
340
|
+
attributes: {
|
|
341
|
+
"actor.name": actorName,
|
|
342
|
+
"actor.class": actorClassName,
|
|
343
|
+
"alarm.operation": "cancelAll"
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
async (span) => {
|
|
347
|
+
try {
|
|
348
|
+
const result = await value.call(target);
|
|
349
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
350
|
+
return result;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
span.recordException(error);
|
|
353
|
+
span.setStatus({
|
|
354
|
+
code: SpanStatusCode.ERROR,
|
|
355
|
+
message: error instanceof Error ? error.message : String(error)
|
|
356
|
+
});
|
|
357
|
+
throw error;
|
|
358
|
+
} finally {
|
|
359
|
+
span.end();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (typeof value === "function") {
|
|
366
|
+
return value.bind(target);
|
|
367
|
+
}
|
|
368
|
+
return value;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
return wrap(alarms, alarmsHandler);
|
|
372
|
+
}
|
|
373
|
+
function getTracer3() {
|
|
374
|
+
return trace.getTracer("autotel-cloudflare-actors");
|
|
375
|
+
}
|
|
376
|
+
function instrumentActorSockets(sockets, actorInstance, actorClass) {
|
|
377
|
+
if (!sockets || typeof sockets !== "object") {
|
|
378
|
+
return sockets;
|
|
379
|
+
}
|
|
380
|
+
const actorClassName = actorClass.name || "Actor";
|
|
381
|
+
const actorName = actorInstance.name || actorClassName;
|
|
382
|
+
const socketsHandler = {
|
|
383
|
+
get(target, prop) {
|
|
384
|
+
const value = Reflect.get(target, prop);
|
|
385
|
+
if (prop === "acceptWebSocket" && typeof value === "function") {
|
|
386
|
+
return function instrumentedAcceptWebSocket(request) {
|
|
387
|
+
const tracer = getTracer3();
|
|
388
|
+
const spanName = `Actor ${actorName}: sockets.acceptWebSocket`;
|
|
389
|
+
return tracer.startActiveSpan(
|
|
390
|
+
spanName,
|
|
391
|
+
{
|
|
392
|
+
kind: SpanKind.SERVER,
|
|
393
|
+
attributes: {
|
|
394
|
+
"actor.name": actorName,
|
|
395
|
+
"actor.class": actorClassName,
|
|
396
|
+
"websocket.operation": "accept",
|
|
397
|
+
"url.full": request.url
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
(span) => {
|
|
401
|
+
try {
|
|
402
|
+
const result = value.call(target, request);
|
|
403
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
404
|
+
return result;
|
|
405
|
+
} catch (error) {
|
|
406
|
+
span.recordException(error);
|
|
407
|
+
span.setStatus({
|
|
408
|
+
code: SpanStatusCode.ERROR,
|
|
409
|
+
message: error instanceof Error ? error.message : String(error)
|
|
410
|
+
});
|
|
411
|
+
throw error;
|
|
412
|
+
} finally {
|
|
413
|
+
span.end();
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
);
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
if (prop === "broadcast" && typeof value === "function") {
|
|
420
|
+
return function instrumentedBroadcast(message) {
|
|
421
|
+
const tracer = getTracer3();
|
|
422
|
+
const spanName = `Actor ${actorName}: sockets.broadcast`;
|
|
423
|
+
tracer.startActiveSpan(
|
|
424
|
+
spanName,
|
|
425
|
+
{
|
|
426
|
+
kind: SpanKind.PRODUCER,
|
|
427
|
+
attributes: {
|
|
428
|
+
"actor.name": actorName,
|
|
429
|
+
"actor.class": actorClassName,
|
|
430
|
+
"websocket.operation": "broadcast",
|
|
431
|
+
"websocket.message.type": typeof message,
|
|
432
|
+
"websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
(span) => {
|
|
436
|
+
try {
|
|
437
|
+
value.call(target, message);
|
|
438
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
439
|
+
} catch (error) {
|
|
440
|
+
span.recordException(error);
|
|
441
|
+
span.setStatus({
|
|
442
|
+
code: SpanStatusCode.ERROR,
|
|
443
|
+
message: error instanceof Error ? error.message : String(error)
|
|
444
|
+
});
|
|
445
|
+
throw error;
|
|
446
|
+
} finally {
|
|
447
|
+
span.end();
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
if (prop === "send" && typeof value === "function") {
|
|
454
|
+
return function instrumentedSend(ws, message) {
|
|
455
|
+
const tracer = getTracer3();
|
|
456
|
+
const spanName = `Actor ${actorName}: sockets.send`;
|
|
457
|
+
tracer.startActiveSpan(
|
|
458
|
+
spanName,
|
|
459
|
+
{
|
|
460
|
+
kind: SpanKind.PRODUCER,
|
|
461
|
+
attributes: {
|
|
462
|
+
"actor.name": actorName,
|
|
463
|
+
"actor.class": actorClassName,
|
|
464
|
+
"websocket.operation": "send",
|
|
465
|
+
"websocket.message.type": typeof message,
|
|
466
|
+
"websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
(span) => {
|
|
470
|
+
try {
|
|
471
|
+
value.call(target, ws, message);
|
|
472
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
473
|
+
} catch (error) {
|
|
474
|
+
span.recordException(error);
|
|
475
|
+
span.setStatus({
|
|
476
|
+
code: SpanStatusCode.ERROR,
|
|
477
|
+
message: error instanceof Error ? error.message : String(error)
|
|
478
|
+
});
|
|
479
|
+
throw error;
|
|
480
|
+
} finally {
|
|
481
|
+
span.end();
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
if (prop === "getConnections" && typeof value === "function") {
|
|
488
|
+
return function instrumentedGetConnections() {
|
|
489
|
+
const tracer = getTracer3();
|
|
490
|
+
const spanName = `Actor ${actorName}: sockets.getConnections`;
|
|
491
|
+
return tracer.startActiveSpan(
|
|
492
|
+
spanName,
|
|
493
|
+
{
|
|
494
|
+
kind: SpanKind.CLIENT,
|
|
495
|
+
attributes: {
|
|
496
|
+
"actor.name": actorName,
|
|
497
|
+
"actor.class": actorClassName,
|
|
498
|
+
"websocket.operation": "getConnections"
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
(span) => {
|
|
502
|
+
try {
|
|
503
|
+
const result = value.call(target);
|
|
504
|
+
if (Array.isArray(result)) {
|
|
505
|
+
span.setAttribute("websocket.connections.count", result.length);
|
|
506
|
+
}
|
|
507
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
508
|
+
return result;
|
|
509
|
+
} catch (error) {
|
|
510
|
+
span.recordException(error);
|
|
511
|
+
span.setStatus({
|
|
512
|
+
code: SpanStatusCode.ERROR,
|
|
513
|
+
message: error instanceof Error ? error.message : String(error)
|
|
514
|
+
});
|
|
515
|
+
throw error;
|
|
516
|
+
} finally {
|
|
517
|
+
span.end();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
);
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (typeof value === "function") {
|
|
524
|
+
return value.bind(target);
|
|
525
|
+
}
|
|
526
|
+
return value;
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
return wrap(sockets, socketsHandler);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/actors/instrument-actor.ts
|
|
533
|
+
var coldStarts = /* @__PURE__ */ new WeakMap();
|
|
534
|
+
function isColdStart(actorClass) {
|
|
535
|
+
if (!coldStarts.has(actorClass)) {
|
|
536
|
+
coldStarts.set(actorClass, true);
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
function getTracer4() {
|
|
542
|
+
return trace.getTracer("autotel-cloudflare-actors");
|
|
543
|
+
}
|
|
544
|
+
function defaultSpanNameFormatter(actorName, actorClass, lifecycle) {
|
|
545
|
+
const displayName = actorName || actorClass;
|
|
546
|
+
return `Actor ${displayName}: ${lifecycle}`;
|
|
547
|
+
}
|
|
548
|
+
function createActorAttributes(actorInstance, actorClass, lifecycle) {
|
|
549
|
+
return {
|
|
550
|
+
"actor.name": actorInstance.name || "unknown",
|
|
551
|
+
"actor.class": actorClass.name || "Actor",
|
|
552
|
+
"actor.lifecycle": lifecycle,
|
|
553
|
+
"actor.coldstart": isColdStart(actorClass),
|
|
554
|
+
...actorInstance.identifier && { "actor.identifier": actorInstance.identifier }
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function instrumentOnInit(originalMethod, actorInstance, actorClass, options) {
|
|
558
|
+
return async function instrumentedOnInit() {
|
|
559
|
+
const tracer = getTracer4();
|
|
560
|
+
const actorClassName = actorClass.name || "Actor";
|
|
561
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "init") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "init");
|
|
562
|
+
return tracer.startActiveSpan(
|
|
563
|
+
spanName,
|
|
564
|
+
{
|
|
565
|
+
kind: SpanKind.INTERNAL,
|
|
566
|
+
attributes: createActorAttributes(actorInstance, actorClass, "init")
|
|
567
|
+
},
|
|
568
|
+
async (span) => {
|
|
569
|
+
try {
|
|
570
|
+
await originalMethod.call(actorInstance);
|
|
571
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
572
|
+
} catch (error) {
|
|
573
|
+
span.recordException(error);
|
|
574
|
+
span.setStatus({
|
|
575
|
+
code: SpanStatusCode.ERROR,
|
|
576
|
+
message: error instanceof Error ? error.message : String(error)
|
|
577
|
+
});
|
|
578
|
+
throw error;
|
|
579
|
+
} finally {
|
|
580
|
+
span.end();
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
);
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function instrumentOnRequest(originalMethod, actorInstance, actorClass, options) {
|
|
587
|
+
return async function instrumentedOnRequest(request) {
|
|
588
|
+
const tracer = getTracer4();
|
|
589
|
+
const parentContext = propagation.extract(context.active(), request.headers);
|
|
590
|
+
const url = new URL(request.url);
|
|
591
|
+
const actorClassName = actorClass.name || "Actor";
|
|
592
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "request") : `Actor ${actorInstance.name || actorClassName}: ${request.method} ${url.pathname}`;
|
|
593
|
+
return tracer.startActiveSpan(
|
|
594
|
+
spanName,
|
|
595
|
+
{
|
|
596
|
+
kind: SpanKind.SERVER,
|
|
597
|
+
attributes: {
|
|
598
|
+
...createActorAttributes(actorInstance, actorClass, "request"),
|
|
599
|
+
"http.request.method": request.method,
|
|
600
|
+
"url.full": request.url,
|
|
601
|
+
"url.path": url.pathname,
|
|
602
|
+
"url.query": url.search
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
parentContext,
|
|
606
|
+
async (span) => {
|
|
607
|
+
try {
|
|
608
|
+
const response = await originalMethod.call(actorInstance, request);
|
|
609
|
+
span.setAttributes({
|
|
610
|
+
"http.response.status_code": response.status
|
|
611
|
+
});
|
|
612
|
+
if (response.ok) {
|
|
613
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
614
|
+
} else {
|
|
615
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
616
|
+
}
|
|
617
|
+
return response;
|
|
618
|
+
} catch (error) {
|
|
619
|
+
span.recordException(error);
|
|
620
|
+
span.setStatus({
|
|
621
|
+
code: SpanStatusCode.ERROR,
|
|
622
|
+
message: error instanceof Error ? error.message : String(error)
|
|
623
|
+
});
|
|
624
|
+
throw error;
|
|
625
|
+
} finally {
|
|
626
|
+
span.end();
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function instrumentOnAlarm(originalMethod, actorInstance, actorClass, options) {
|
|
633
|
+
return async function instrumentedOnAlarm(alarmInfo) {
|
|
634
|
+
const tracer = getTracer4();
|
|
635
|
+
const actorClassName = actorClass.name || "Actor";
|
|
636
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "alarm") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "alarm");
|
|
637
|
+
return tracer.startActiveSpan(
|
|
638
|
+
spanName,
|
|
639
|
+
{
|
|
640
|
+
kind: SpanKind.INTERNAL,
|
|
641
|
+
attributes: {
|
|
642
|
+
...createActorAttributes(actorInstance, actorClass, "alarm"),
|
|
643
|
+
"faas.trigger": "timer"
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
async (span) => {
|
|
647
|
+
try {
|
|
648
|
+
await originalMethod.call(actorInstance, alarmInfo);
|
|
649
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
650
|
+
} catch (error) {
|
|
651
|
+
span.recordException(error);
|
|
652
|
+
span.setStatus({
|
|
653
|
+
code: SpanStatusCode.ERROR,
|
|
654
|
+
message: error instanceof Error ? error.message : String(error)
|
|
655
|
+
});
|
|
656
|
+
throw error;
|
|
657
|
+
} finally {
|
|
658
|
+
span.end();
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
function instrumentOnPersist(originalMethod, actorInstance, actorClass, options) {
|
|
665
|
+
if (!options.capturePersistEvents) {
|
|
666
|
+
return originalMethod;
|
|
667
|
+
}
|
|
668
|
+
return function instrumentedOnPersist(key, value) {
|
|
669
|
+
const tracer = getTracer4();
|
|
670
|
+
const actorClassName = actorClass.name || "Actor";
|
|
671
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "persist") : `Actor ${actorInstance.name || actorClassName}: persist ${key}`;
|
|
672
|
+
tracer.startActiveSpan(
|
|
673
|
+
spanName,
|
|
674
|
+
{
|
|
675
|
+
kind: SpanKind.INTERNAL,
|
|
676
|
+
attributes: {
|
|
677
|
+
...createActorAttributes(actorInstance, actorClass, "persist"),
|
|
678
|
+
"actor.persist.key": key,
|
|
679
|
+
"actor.persist.value_type": typeof value
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
(span) => {
|
|
683
|
+
try {
|
|
684
|
+
originalMethod.call(actorInstance, key, value);
|
|
685
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
686
|
+
} catch (error) {
|
|
687
|
+
span.recordException(error);
|
|
688
|
+
span.setStatus({
|
|
689
|
+
code: SpanStatusCode.ERROR,
|
|
690
|
+
message: error instanceof Error ? error.message : String(error)
|
|
691
|
+
});
|
|
692
|
+
throw error;
|
|
693
|
+
} finally {
|
|
694
|
+
span.end();
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
);
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
function instrumentWebSocketConnect(originalMethod, actorInstance, actorClass, options) {
|
|
701
|
+
return function instrumentedWebSocketConnect(ws, request) {
|
|
702
|
+
const tracer = getTracer4();
|
|
703
|
+
const actorClassName = actorClass.name || "Actor";
|
|
704
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.connect") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.connect");
|
|
705
|
+
tracer.startActiveSpan(
|
|
706
|
+
spanName,
|
|
707
|
+
{
|
|
708
|
+
kind: SpanKind.SERVER,
|
|
709
|
+
attributes: {
|
|
710
|
+
...createActorAttributes(actorInstance, actorClass, "websocket.connect"),
|
|
711
|
+
"url.full": request.url
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
(span) => {
|
|
715
|
+
try {
|
|
716
|
+
originalMethod.call(actorInstance, ws, request);
|
|
717
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
718
|
+
} catch (error) {
|
|
719
|
+
span.recordException(error);
|
|
720
|
+
span.setStatus({
|
|
721
|
+
code: SpanStatusCode.ERROR,
|
|
722
|
+
message: error instanceof Error ? error.message : String(error)
|
|
723
|
+
});
|
|
724
|
+
throw error;
|
|
725
|
+
} finally {
|
|
726
|
+
span.end();
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
);
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
function instrumentWebSocketMessage(originalMethod, actorInstance, actorClass, options) {
|
|
733
|
+
return function instrumentedWebSocketMessage(ws, message) {
|
|
734
|
+
const tracer = getTracer4();
|
|
735
|
+
const actorClassName = actorClass.name || "Actor";
|
|
736
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.message") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.message");
|
|
737
|
+
tracer.startActiveSpan(
|
|
738
|
+
spanName,
|
|
739
|
+
{
|
|
740
|
+
kind: SpanKind.SERVER,
|
|
741
|
+
attributes: {
|
|
742
|
+
...createActorAttributes(actorInstance, actorClass, "websocket.message"),
|
|
743
|
+
"websocket.message.type": typeof message,
|
|
744
|
+
"websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
(span) => {
|
|
748
|
+
try {
|
|
749
|
+
originalMethod.call(actorInstance, ws, message);
|
|
750
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
751
|
+
} catch (error) {
|
|
752
|
+
span.recordException(error);
|
|
753
|
+
span.setStatus({
|
|
754
|
+
code: SpanStatusCode.ERROR,
|
|
755
|
+
message: error instanceof Error ? error.message : String(error)
|
|
756
|
+
});
|
|
757
|
+
throw error;
|
|
758
|
+
} finally {
|
|
759
|
+
span.end();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
);
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
function instrumentWebSocketDisconnect(originalMethod, actorInstance, actorClass, options) {
|
|
766
|
+
return function instrumentedWebSocketDisconnect(ws) {
|
|
767
|
+
const tracer = getTracer4();
|
|
768
|
+
const actorClassName = actorClass.name || "Actor";
|
|
769
|
+
const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.disconnect") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.disconnect");
|
|
770
|
+
tracer.startActiveSpan(
|
|
771
|
+
spanName,
|
|
772
|
+
{
|
|
773
|
+
kind: SpanKind.SERVER,
|
|
774
|
+
attributes: createActorAttributes(actorInstance, actorClass, "websocket.disconnect")
|
|
775
|
+
},
|
|
776
|
+
(span) => {
|
|
777
|
+
try {
|
|
778
|
+
originalMethod.call(actorInstance, ws);
|
|
779
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
780
|
+
} catch (error) {
|
|
781
|
+
span.recordException(error);
|
|
782
|
+
span.setStatus({
|
|
783
|
+
code: SpanStatusCode.ERROR,
|
|
784
|
+
message: error instanceof Error ? error.message : String(error)
|
|
785
|
+
});
|
|
786
|
+
throw error;
|
|
787
|
+
} finally {
|
|
788
|
+
span.end();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
);
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
function instrumentActorInstance(actorInstance, _state, _env, actorClass, options) {
|
|
795
|
+
const instanceHandler = {
|
|
796
|
+
get(target, prop) {
|
|
797
|
+
const value = Reflect.get(target, prop);
|
|
798
|
+
if (prop === "onInit" && typeof value === "function") {
|
|
799
|
+
return instrumentOnInit(value.bind(target), target, actorClass, options);
|
|
800
|
+
}
|
|
801
|
+
if (prop === "onRequest" && typeof value === "function") {
|
|
802
|
+
return instrumentOnRequest(value.bind(target), target, actorClass, options);
|
|
803
|
+
}
|
|
804
|
+
if (prop === "onAlarm" && typeof value === "function") {
|
|
805
|
+
return instrumentOnAlarm(value.bind(target), target, actorClass, options);
|
|
806
|
+
}
|
|
807
|
+
if (prop === "onPersist" && typeof value === "function") {
|
|
808
|
+
return instrumentOnPersist(value.bind(target), target, actorClass, options);
|
|
809
|
+
}
|
|
810
|
+
if (prop === "onWebSocketConnect" && typeof value === "function") {
|
|
811
|
+
return instrumentWebSocketConnect(value.bind(target), target, actorClass, options);
|
|
812
|
+
}
|
|
813
|
+
if (prop === "onWebSocketMessage" && typeof value === "function") {
|
|
814
|
+
return instrumentWebSocketMessage(value.bind(target), target, actorClass, options);
|
|
815
|
+
}
|
|
816
|
+
if (prop === "onWebSocketDisconnect" && typeof value === "function") {
|
|
817
|
+
return instrumentWebSocketDisconnect(value.bind(target), target, actorClass, options);
|
|
818
|
+
}
|
|
819
|
+
if (prop === "storage" && value && options.instrumentStorage !== false) {
|
|
820
|
+
return instrumentActorStorage(value, target, actorClass);
|
|
821
|
+
}
|
|
822
|
+
if (prop === "alarms" && value && options.instrumentAlarms !== false) {
|
|
823
|
+
return instrumentActorAlarms(value, target, actorClass);
|
|
824
|
+
}
|
|
825
|
+
if (prop === "sockets" && value && options.instrumentSockets !== false) {
|
|
826
|
+
return instrumentActorSockets(value, target, actorClass);
|
|
827
|
+
}
|
|
828
|
+
if (typeof value === "function") {
|
|
829
|
+
return value.bind(target);
|
|
830
|
+
}
|
|
831
|
+
return value;
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
return wrap(actorInstance, instanceHandler);
|
|
835
|
+
}
|
|
836
|
+
function instrumentActor(actorClass, config) {
|
|
837
|
+
const initialiser = createInitialiser(config);
|
|
838
|
+
const defaultOptions = {
|
|
839
|
+
instrumentStorage: true,
|
|
840
|
+
instrumentAlarms: true,
|
|
841
|
+
instrumentSockets: true,
|
|
842
|
+
capturePersistEvents: true
|
|
843
|
+
};
|
|
844
|
+
const classHandler = {
|
|
845
|
+
construct(target, [state, env]) {
|
|
846
|
+
const resolvedConfig = typeof config === "function" ? config(env, { id: state.id.toString(), name: state.id.name }) : config;
|
|
847
|
+
const actorOptions = resolvedConfig && typeof resolvedConfig === "object" && "actors" in resolvedConfig ? resolvedConfig.actors : void 0;
|
|
848
|
+
const options = {
|
|
849
|
+
...defaultOptions,
|
|
850
|
+
...actorOptions
|
|
851
|
+
};
|
|
852
|
+
const trigger = {
|
|
853
|
+
id: state.id.toString(),
|
|
854
|
+
name: state.id.name
|
|
855
|
+
};
|
|
856
|
+
const telemetryConfig = initialiser(env, trigger);
|
|
857
|
+
const context$1 = setConfig(telemetryConfig);
|
|
858
|
+
const actorInstance = context.with(context$1, () => {
|
|
859
|
+
return new target(state, env);
|
|
860
|
+
});
|
|
861
|
+
return instrumentActorInstance(actorInstance, state, env, actorClass, options);
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
return wrap(actorClass, classHandler);
|
|
865
|
+
}
|
|
866
|
+
function getTracer5() {
|
|
867
|
+
return trace.getTracer("autotel-cloudflare-actors");
|
|
868
|
+
}
|
|
869
|
+
function tracedHandler(actorClass, config) {
|
|
870
|
+
const initialiser = createInitialiser(config);
|
|
871
|
+
return {
|
|
872
|
+
async fetch(request, env, _ctx) {
|
|
873
|
+
const telemetryConfig = initialiser(env, { type: "http" });
|
|
874
|
+
const configContext = setConfig(telemetryConfig);
|
|
875
|
+
const parentContext = propagation.extract(configContext, request.headers);
|
|
876
|
+
const tracer = getTracer5();
|
|
877
|
+
const url = new URL(request.url);
|
|
878
|
+
const actorClassName = actorClass.name || "Actor";
|
|
879
|
+
let actorName;
|
|
880
|
+
try {
|
|
881
|
+
if (actorClass.nameFromRequest) {
|
|
882
|
+
actorName = await actorClass.nameFromRequest(request);
|
|
883
|
+
}
|
|
884
|
+
} catch {
|
|
885
|
+
actorName = void 0;
|
|
886
|
+
}
|
|
887
|
+
const spanName = `${actorClassName} handler: ${request.method} ${url.pathname}`;
|
|
888
|
+
return tracer.startActiveSpan(
|
|
889
|
+
spanName,
|
|
890
|
+
{
|
|
891
|
+
kind: SpanKind.SERVER,
|
|
892
|
+
attributes: {
|
|
893
|
+
"http.request.method": request.method,
|
|
894
|
+
"url.full": request.url,
|
|
895
|
+
"url.path": url.pathname,
|
|
896
|
+
"url.query": url.search,
|
|
897
|
+
"actor.class": actorClassName,
|
|
898
|
+
...actorName && { "actor.name": actorName },
|
|
899
|
+
"faas.trigger": "http"
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
parentContext,
|
|
903
|
+
async (span) => {
|
|
904
|
+
try {
|
|
905
|
+
const envObj = env;
|
|
906
|
+
const bindingName = Object.keys(envObj).find((key) => {
|
|
907
|
+
const binding = env.__DURABLE_OBJECT_BINDINGS;
|
|
908
|
+
return key === actorClassName || binding?.[key]?.class_name === actorClassName;
|
|
909
|
+
});
|
|
910
|
+
if (!bindingName) {
|
|
911
|
+
span.setStatus({
|
|
912
|
+
code: SpanStatusCode.ERROR,
|
|
913
|
+
message: `No Durable Object binding found for ${actorClassName}`
|
|
914
|
+
});
|
|
915
|
+
return Response.json(
|
|
916
|
+
{
|
|
917
|
+
error: "Configuration Error",
|
|
918
|
+
message: `No Durable Object binding found for actor class ${actorClassName}`
|
|
919
|
+
},
|
|
920
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
921
|
+
);
|
|
922
|
+
}
|
|
923
|
+
const namespace = envObj[bindingName];
|
|
924
|
+
const idString = actorName || "default";
|
|
925
|
+
const locationHint = actorClass.configuration?.(request)?.locationHint;
|
|
926
|
+
const stub = namespace.getByName(idString, { locationHint });
|
|
927
|
+
if ("setName" in stub && typeof stub.setName === "function") {
|
|
928
|
+
stub.setName(idString);
|
|
929
|
+
}
|
|
930
|
+
const headers = new Headers(request.headers);
|
|
931
|
+
propagation.inject(context.active(), headers);
|
|
932
|
+
const tracedRequest = new Request(request.url, {
|
|
933
|
+
method: request.method,
|
|
934
|
+
headers,
|
|
935
|
+
body: request.body,
|
|
936
|
+
redirect: request.redirect
|
|
937
|
+
});
|
|
938
|
+
const response = await stub.fetch(tracedRequest);
|
|
939
|
+
span.setAttributes({
|
|
940
|
+
"http.response.status_code": response.status,
|
|
941
|
+
"actor.name": idString
|
|
942
|
+
});
|
|
943
|
+
if (response.ok) {
|
|
944
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
945
|
+
} else {
|
|
946
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
947
|
+
}
|
|
948
|
+
return response;
|
|
949
|
+
} catch (error) {
|
|
950
|
+
span.recordException(error);
|
|
951
|
+
span.setStatus({
|
|
952
|
+
code: SpanStatusCode.ERROR,
|
|
953
|
+
message: error instanceof Error ? error.message : String(error)
|
|
954
|
+
});
|
|
955
|
+
return Response.json(
|
|
956
|
+
{
|
|
957
|
+
error: "Internal Server Error",
|
|
958
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
959
|
+
},
|
|
960
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
961
|
+
);
|
|
962
|
+
} finally {
|
|
963
|
+
span.end();
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function wrapHandler(originalHandler, config) {
|
|
971
|
+
const initialiser = createInitialiser(config);
|
|
972
|
+
return {
|
|
973
|
+
async fetch(request, env, ctx) {
|
|
974
|
+
const telemetryConfig = initialiser(env, { type: "http" });
|
|
975
|
+
const configContext = setConfig(telemetryConfig);
|
|
976
|
+
const parentContext = propagation.extract(configContext, request.headers);
|
|
977
|
+
const tracer = getTracer5();
|
|
978
|
+
const url = new URL(request.url);
|
|
979
|
+
return tracer.startActiveSpan(
|
|
980
|
+
`Worker: ${request.method} ${url.pathname}`,
|
|
981
|
+
{
|
|
982
|
+
kind: SpanKind.SERVER,
|
|
983
|
+
attributes: {
|
|
984
|
+
"http.request.method": request.method,
|
|
985
|
+
"url.full": request.url,
|
|
986
|
+
"url.path": url.pathname,
|
|
987
|
+
"url.query": url.search,
|
|
988
|
+
"faas.trigger": "http"
|
|
989
|
+
}
|
|
990
|
+
},
|
|
991
|
+
parentContext,
|
|
992
|
+
async (span) => {
|
|
993
|
+
try {
|
|
994
|
+
const headers = new Headers(request.headers);
|
|
995
|
+
propagation.inject(context.active(), headers);
|
|
996
|
+
const tracedRequest = new Request(request.url, {
|
|
997
|
+
method: request.method,
|
|
998
|
+
headers,
|
|
999
|
+
body: request.body,
|
|
1000
|
+
redirect: request.redirect
|
|
1001
|
+
});
|
|
1002
|
+
const response = await originalHandler.fetch(tracedRequest, env, ctx);
|
|
1003
|
+
span.setAttributes({
|
|
1004
|
+
"http.response.status_code": response.status
|
|
1005
|
+
});
|
|
1006
|
+
if (response.ok) {
|
|
1007
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
1008
|
+
} else {
|
|
1009
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1010
|
+
}
|
|
1011
|
+
return response;
|
|
1012
|
+
} catch (error) {
|
|
1013
|
+
span.recordException(error);
|
|
1014
|
+
span.setStatus({
|
|
1015
|
+
code: SpanStatusCode.ERROR,
|
|
1016
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1017
|
+
});
|
|
1018
|
+
throw error;
|
|
1019
|
+
} finally {
|
|
1020
|
+
span.end();
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
export { instrumentActor, instrumentActorAlarms, instrumentActorSockets, instrumentActorStorage, tracedHandler, wrapHandler };
|
|
1029
|
+
//# sourceMappingURL=actors.js.map
|
|
1030
|
+
//# sourceMappingURL=actors.js.map
|