@squide/firefly 12.0.4 → 13.0.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/CHANGELOG.md +51 -0
- package/dist/honeycomb/activeSpan.d.ts +12 -0
- package/dist/honeycomb/activeSpan.js +105 -0
- package/dist/honeycomb/activeSpan.js.map +1 -0
- package/dist/honeycomb/createTraceContextId.d.ts +1 -0
- package/dist/honeycomb/createTraceContextId.js +16 -0
- package/dist/honeycomb/createTraceContextId.js.map +1 -0
- package/dist/honeycomb/registerHoneycombInstrumentation.d.ts +4 -0
- package/dist/honeycomb/registerHoneycombInstrumentation.js +430 -0
- package/dist/honeycomb/registerHoneycombInstrumentation.js.map +1 -0
- package/dist/honeycomb/tracer.d.ts +1 -0
- package/dist/honeycomb/tracer.js +14 -0
- package/dist/honeycomb/tracer.js.map +1 -0
- package/dist/honeycomb/utils.d.ts +23 -0
- package/dist/honeycomb/utils.js +49 -0
- package/dist/honeycomb/utils.js.map +1 -0
- package/dist/initializeFirefly.js +9 -0
- package/dist/initializeFirefly.js.map +1 -1
- package/package.json +10 -3
- package/src/honeycomb/activeSpan.ts +131 -0
- package/src/honeycomb/createTraceContextId.ts +12 -0
- package/src/honeycomb/registerHoneycombInstrumentation.ts +504 -0
- package/src/honeycomb/tracer.ts +6 -0
- package/src/honeycomb/utils.ts +64 -0
- package/src/initializeFirefly.ts +7 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import type { Span } from "@opentelemetry/api";
|
|
2
|
+
import {
|
|
3
|
+
LocalModuleDeferredRegistrationFailedEvent,
|
|
4
|
+
LocalModuleDeferredRegistrationUpdateFailedEvent,
|
|
5
|
+
LocalModuleRegistrationFailedEvent,
|
|
6
|
+
LocalModulesDeferredRegistrationCompletedEvent,
|
|
7
|
+
type LocalModulesDeferredRegistrationCompletedEventPayload,
|
|
8
|
+
LocalModulesDeferredRegistrationStartedEvent,
|
|
9
|
+
type LocalModulesDeferredRegistrationStartedEventPayload,
|
|
10
|
+
LocalModulesDeferredRegistrationsUpdateCompletedEvent,
|
|
11
|
+
type LocalModulesDeferredRegistrationsUpdateCompletedEventPayload,
|
|
12
|
+
LocalModulesDeferredRegistrationsUpdateStartedEvent,
|
|
13
|
+
type LocalModulesDeferredRegistrationsUpdateStartedEventPayload,
|
|
14
|
+
LocalModulesRegistrationCompletedEvent,
|
|
15
|
+
type LocalModulesRegistrationCompletedEventPayload,
|
|
16
|
+
LocalModulesRegistrationStartedEvent,
|
|
17
|
+
type LocalModulesRegistrationStartedEventPayload,
|
|
18
|
+
type ModuleRegistrationError
|
|
19
|
+
} from "@squide/core";
|
|
20
|
+
import {
|
|
21
|
+
DeferredRegistrationsUpdateCompletedEvent,
|
|
22
|
+
DeferredRegistrationsUpdateStartedEvent,
|
|
23
|
+
RemoteModuleDeferredRegistrationFailedEvent,
|
|
24
|
+
RemoteModuleDeferredRegistrationUpdateFailedEvent,
|
|
25
|
+
type RemoteModuleRegistrationError,
|
|
26
|
+
RemoteModuleRegistrationFailedEvent,
|
|
27
|
+
RemoteModulesDeferredRegistrationCompletedEvent,
|
|
28
|
+
type RemoteModulesDeferredRegistrationCompletedEventPayload,
|
|
29
|
+
RemoteModulesDeferredRegistrationStartedEvent,
|
|
30
|
+
type RemoteModulesDeferredRegistrationStartedEventPayload,
|
|
31
|
+
RemoteModulesDeferredRegistrationsUpdateCompletedEvent,
|
|
32
|
+
type RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload,
|
|
33
|
+
RemoteModulesDeferredRegistrationsUpdateStartedEvent,
|
|
34
|
+
type RemoteModulesDeferredRegistrationsUpdateStartedEventPayload,
|
|
35
|
+
RemoteModulesRegistrationCompletedEvent,
|
|
36
|
+
type RemoteModulesRegistrationCompletedEventPayload,
|
|
37
|
+
RemoteModulesRegistrationStartedEvent,
|
|
38
|
+
type RemoteModulesRegistrationStartedEventPayload
|
|
39
|
+
} from "@squide/module-federation";
|
|
40
|
+
import { ApplicationBoostrappedEvent, ModulesReadyEvent, ModulesRegisteredEvent, MswReadyEvent, ProtectedDataReadyEvent, PublicDataReadyEvent } from "../AppRouterReducer.ts";
|
|
41
|
+
import type { FireflyRuntime } from "../FireflyRuntime.tsx";
|
|
42
|
+
import { ApplicationBootstrappingStartedEvent } from "../initializeFirefly.ts";
|
|
43
|
+
import { ProtectedDataFetchStartedEvent } from "../useProtectedDataQueries.ts";
|
|
44
|
+
import { PublicDataFetchStartedEvent } from "../usePublicDataQueries.ts";
|
|
45
|
+
import { type ActiveSpan, createOverrideFetchRequestSpanWithActiveSpanContext, registerActiveSpanStack } from "./activeSpan.ts";
|
|
46
|
+
import { getTracer } from "./tracer.ts";
|
|
47
|
+
import { endActiveSpan, startActiveChildSpan, startChildSpan, startSpan, traceError } from "./utils.ts";
|
|
48
|
+
|
|
49
|
+
// TIPS:
|
|
50
|
+
// To query those traces in Honeycomb, use the following query filter: "root.name = squide-bootstrapping".
|
|
51
|
+
|
|
52
|
+
type DataFetchState = "none" | "fetching-data" | "public-data-ready" | "protected-data-ready" | "data-ready";
|
|
53
|
+
|
|
54
|
+
export function reduceDataFetchEvents(
|
|
55
|
+
runtime: FireflyRuntime,
|
|
56
|
+
onDataFetchingStarted: () => void,
|
|
57
|
+
onDataReady: () => void,
|
|
58
|
+
onPublicDataFetchStarted: () => void,
|
|
59
|
+
onPublicDataReady: () => void,
|
|
60
|
+
onProtectedDataFetchStarted: () => void,
|
|
61
|
+
onProtectedDataReady: () => void
|
|
62
|
+
) {
|
|
63
|
+
let dataFetchState: DataFetchState = "none";
|
|
64
|
+
|
|
65
|
+
// TODO: Validate if this handler should use { once: true }.
|
|
66
|
+
runtime.eventBus.addListener(PublicDataFetchStartedEvent, () => {
|
|
67
|
+
if (dataFetchState === "none") {
|
|
68
|
+
dataFetchState = "fetching-data";
|
|
69
|
+
onDataFetchingStarted();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
onPublicDataFetchStarted();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// TODO: Validate if this handler should use { once: true }.
|
|
76
|
+
runtime.eventBus.addListener(PublicDataReadyEvent, () => {
|
|
77
|
+
onPublicDataReady();
|
|
78
|
+
|
|
79
|
+
if (dataFetchState === "fetching-data") {
|
|
80
|
+
dataFetchState = "public-data-ready";
|
|
81
|
+
} else if (dataFetchState === "protected-data-ready") {
|
|
82
|
+
dataFetchState = "data-ready";
|
|
83
|
+
onDataReady();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// TODO: Validate if this handler should use { once: true }.
|
|
88
|
+
runtime.eventBus.addListener(ProtectedDataFetchStartedEvent, () => {
|
|
89
|
+
if (dataFetchState === "none") {
|
|
90
|
+
dataFetchState = "fetching-data";
|
|
91
|
+
onDataFetchingStarted();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
onProtectedDataFetchStarted();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// TODO: Validate if this handler should use { once: true }.
|
|
98
|
+
runtime.eventBus.addListener(ProtectedDataReadyEvent, () => {
|
|
99
|
+
onProtectedDataReady();
|
|
100
|
+
|
|
101
|
+
if (dataFetchState === "fetching-data") {
|
|
102
|
+
dataFetchState = "protected-data-ready";
|
|
103
|
+
} else if (dataFetchState === "public-data-ready") {
|
|
104
|
+
dataFetchState = "data-ready";
|
|
105
|
+
onDataReady();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function registerTrackingListeners(runtime: FireflyRuntime) {
|
|
111
|
+
let bootstrappingSpan: Span;
|
|
112
|
+
let localModuleRegistrationSpan: Span;
|
|
113
|
+
let localModuleDeferredRegistrationSpan: Span;
|
|
114
|
+
let remoteModuleRegistrationSpan: Span;
|
|
115
|
+
let remoteModuleDeferredRegistrationSpan: Span;
|
|
116
|
+
let dataFetchSpan: ActiveSpan;
|
|
117
|
+
let deferredRegistrationsUpdateSpan: Span;
|
|
118
|
+
let localModuleDeferredRegistrationsUpdateSpan: ActiveSpan;
|
|
119
|
+
let remoteModuleDeferredRegistrationsUpdateSpan: ActiveSpan;
|
|
120
|
+
|
|
121
|
+
runtime.eventBus.addListener(ApplicationBootstrappingStartedEvent, () => {
|
|
122
|
+
bootstrappingSpan = startSpan((options, context) => getTracer().startSpan("squide-bootstrapping", options, context));
|
|
123
|
+
}, { once: true });
|
|
124
|
+
|
|
125
|
+
runtime.eventBus.addListener(ApplicationBoostrappedEvent, () => {
|
|
126
|
+
if (bootstrappingSpan) {
|
|
127
|
+
bootstrappingSpan.end();
|
|
128
|
+
}
|
|
129
|
+
}, { once: true });
|
|
130
|
+
|
|
131
|
+
runtime.eventBus.addListener(MswReadyEvent, () => {
|
|
132
|
+
if (bootstrappingSpan) {
|
|
133
|
+
bootstrappingSpan.addEvent("msw-ready");
|
|
134
|
+
}
|
|
135
|
+
}, { once: true });
|
|
136
|
+
|
|
137
|
+
runtime.eventBus.addListener(LocalModulesRegistrationStartedEvent, (payload: unknown) => {
|
|
138
|
+
const attributes = {
|
|
139
|
+
"app.squide.module_count": (payload as LocalModulesRegistrationStartedEventPayload).moduleCount
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
if (bootstrappingSpan) {
|
|
143
|
+
bootstrappingSpan.addEvent("local-module-registration-started", attributes);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
localModuleRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
|
|
147
|
+
return getTracer().startSpan("local-module-registration", { ...options, attributes }, context);
|
|
148
|
+
});
|
|
149
|
+
}, { once: true });
|
|
150
|
+
|
|
151
|
+
runtime.eventBus.addListener(LocalModulesRegistrationCompletedEvent, (payload: unknown) => {
|
|
152
|
+
if (bootstrappingSpan) {
|
|
153
|
+
bootstrappingSpan.addEvent("local-module-registration-completed", {
|
|
154
|
+
"app.squide.module_count": (payload as LocalModulesRegistrationCompletedEventPayload).moduleCount
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (localModuleRegistrationSpan) {
|
|
159
|
+
localModuleRegistrationSpan.end();
|
|
160
|
+
}
|
|
161
|
+
}, { once: true });
|
|
162
|
+
|
|
163
|
+
// Can occur multiple times.
|
|
164
|
+
runtime.eventBus.addListener(LocalModuleRegistrationFailedEvent, (payload: unknown) => {
|
|
165
|
+
const registrationError = payload as ModuleRegistrationError;
|
|
166
|
+
|
|
167
|
+
if (localModuleRegistrationSpan) {
|
|
168
|
+
traceError(localModuleRegistrationSpan, registrationError);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
runtime.eventBus.addListener(LocalModulesDeferredRegistrationStartedEvent, (payload: unknown) => {
|
|
173
|
+
const attributes = {
|
|
174
|
+
"app.squide.registration_count": (payload as LocalModulesDeferredRegistrationStartedEventPayload).registrationCount
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
if (bootstrappingSpan) {
|
|
178
|
+
bootstrappingSpan.addEvent("local-module-deferred-registration-started", attributes);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
localModuleDeferredRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
|
|
182
|
+
return getTracer().startSpan("local-module-deferred-registration", { ...options, attributes }, context);
|
|
183
|
+
});
|
|
184
|
+
}, { once: true });
|
|
185
|
+
|
|
186
|
+
runtime.eventBus.addListener(LocalModulesDeferredRegistrationCompletedEvent, (payload: unknown) => {
|
|
187
|
+
if (bootstrappingSpan) {
|
|
188
|
+
bootstrappingSpan.addEvent("local-module-deferred-registration-completed", {
|
|
189
|
+
"app.squide.registration_count": (payload as LocalModulesDeferredRegistrationCompletedEventPayload).registrationCount
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (localModuleDeferredRegistrationSpan) {
|
|
194
|
+
localModuleDeferredRegistrationSpan.end();
|
|
195
|
+
}
|
|
196
|
+
}, { once: true });
|
|
197
|
+
|
|
198
|
+
// Can occur multiple times.
|
|
199
|
+
runtime.eventBus.addListener(LocalModuleDeferredRegistrationFailedEvent, (payload: unknown) => {
|
|
200
|
+
const registrationError = payload as ModuleRegistrationError;
|
|
201
|
+
|
|
202
|
+
if (localModuleDeferredRegistrationSpan) {
|
|
203
|
+
traceError(localModuleRegistrationSpan, registrationError);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
runtime.eventBus.addListener(RemoteModulesRegistrationStartedEvent, (payload: unknown) => {
|
|
208
|
+
const attributes = {
|
|
209
|
+
"app.squide.remote_count": (payload as RemoteModulesRegistrationStartedEventPayload).remoteCount
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
if (bootstrappingSpan) {
|
|
213
|
+
bootstrappingSpan.addEvent("remote-module-registration-started", attributes);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
remoteModuleRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
|
|
217
|
+
return getTracer().startSpan("remote-module-registration", { ...options, attributes }, context);
|
|
218
|
+
});
|
|
219
|
+
}, { once: true });
|
|
220
|
+
|
|
221
|
+
runtime.eventBus.addListener(RemoteModulesRegistrationCompletedEvent, (payload: unknown) => {
|
|
222
|
+
if (bootstrappingSpan) {
|
|
223
|
+
bootstrappingSpan.addEvent("remote-module-registration-completed", {
|
|
224
|
+
"app.squide.remote_count": (payload as RemoteModulesRegistrationCompletedEventPayload).remoteCount
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (remoteModuleRegistrationSpan) {
|
|
229
|
+
remoteModuleRegistrationSpan.end();
|
|
230
|
+
}
|
|
231
|
+
}, { once: true });
|
|
232
|
+
|
|
233
|
+
// Can occur multiple times.
|
|
234
|
+
runtime.eventBus.addListener(RemoteModuleRegistrationFailedEvent, (payload: unknown) => {
|
|
235
|
+
const registrationError = payload as RemoteModuleRegistrationError;
|
|
236
|
+
|
|
237
|
+
if (remoteModuleRegistrationSpan) {
|
|
238
|
+
traceError(remoteModuleRegistrationSpan, registrationError);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
runtime.eventBus.addListener(RemoteModulesDeferredRegistrationStartedEvent, (payload: unknown) => {
|
|
243
|
+
const attributes = {
|
|
244
|
+
"app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationStartedEventPayload).registrationCount
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
if (bootstrappingSpan) {
|
|
248
|
+
bootstrappingSpan.addEvent("remote-module-deferred-registration-started", attributes);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
remoteModuleDeferredRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
|
|
252
|
+
return getTracer().startSpan("remote-module-deferred-registration", { ...options, attributes }, context);
|
|
253
|
+
});
|
|
254
|
+
}, { once: true });
|
|
255
|
+
|
|
256
|
+
runtime.eventBus.addListener(RemoteModulesDeferredRegistrationCompletedEvent, (payload: unknown) => {
|
|
257
|
+
if (bootstrappingSpan) {
|
|
258
|
+
bootstrappingSpan.addEvent("remote-module-deferred-registration-completed", {
|
|
259
|
+
"app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationCompletedEventPayload).registrationCount
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (remoteModuleDeferredRegistrationSpan) {
|
|
264
|
+
remoteModuleDeferredRegistrationSpan.end();
|
|
265
|
+
}
|
|
266
|
+
}, { once: true });
|
|
267
|
+
|
|
268
|
+
// Can occur multiple times.
|
|
269
|
+
runtime.eventBus.addListener(RemoteModuleDeferredRegistrationFailedEvent, (payload: unknown) => {
|
|
270
|
+
const registrationError = payload as RemoteModuleRegistrationError;
|
|
271
|
+
|
|
272
|
+
if (remoteModuleDeferredRegistrationSpan) {
|
|
273
|
+
traceError(remoteModuleDeferredRegistrationSpan, registrationError);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const handleFetchDataStarted = () => {
|
|
278
|
+
dataFetchSpan = startActiveChildSpan(bootstrappingSpan, (options, context) => {
|
|
279
|
+
const name = "data-fetch";
|
|
280
|
+
const span = getTracer().startSpan(name, options, context);
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
name,
|
|
284
|
+
span
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const handleDataReady = () => {
|
|
290
|
+
if (dataFetchSpan) {
|
|
291
|
+
endActiveSpan(dataFetchSpan);
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const handlePublicDataFetchStarted = () => {
|
|
296
|
+
if (dataFetchSpan) {
|
|
297
|
+
dataFetchSpan.instance.addEvent("public-data-fetch-started");
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const handlePublicDataReady = () => {
|
|
302
|
+
if (dataFetchSpan) {
|
|
303
|
+
dataFetchSpan.instance.addEvent("public-data-ready");
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const handleProtectedDataFetchStarted = () => {
|
|
308
|
+
if (dataFetchSpan) {
|
|
309
|
+
dataFetchSpan.instance.addEvent("protected-data-fetch-started");
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const handleProtectedDataReady = () => {
|
|
314
|
+
if (dataFetchSpan) {
|
|
315
|
+
dataFetchSpan.instance.addEvent("protected-data-ready");
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
reduceDataFetchEvents(
|
|
320
|
+
runtime,
|
|
321
|
+
handleFetchDataStarted,
|
|
322
|
+
handleDataReady,
|
|
323
|
+
handlePublicDataFetchStarted,
|
|
324
|
+
handlePublicDataReady,
|
|
325
|
+
handleProtectedDataFetchStarted,
|
|
326
|
+
handleProtectedDataReady
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
runtime.eventBus.addListener(ModulesRegisteredEvent, () => {
|
|
330
|
+
if (bootstrappingSpan) {
|
|
331
|
+
bootstrappingSpan.addEvent("modules-registered");
|
|
332
|
+
}
|
|
333
|
+
}, { once: true });
|
|
334
|
+
|
|
335
|
+
runtime.eventBus.addListener(ModulesReadyEvent, () => {
|
|
336
|
+
if (bootstrappingSpan) {
|
|
337
|
+
bootstrappingSpan.addEvent("modules-ready");
|
|
338
|
+
}
|
|
339
|
+
}, { once: true });
|
|
340
|
+
|
|
341
|
+
// Can occur multiple times.
|
|
342
|
+
runtime.eventBus.addListener(DeferredRegistrationsUpdateStartedEvent, () => {
|
|
343
|
+
deferredRegistrationsUpdateSpan = startSpan((options, context) => getTracer().startSpan("squide-deferred-registrations-update", options, context));
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Can occur multiple times.
|
|
347
|
+
runtime.eventBus.addListener(DeferredRegistrationsUpdateCompletedEvent, () => {
|
|
348
|
+
if (deferredRegistrationsUpdateSpan) {
|
|
349
|
+
deferredRegistrationsUpdateSpan.end();
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// Can occur multiple times.
|
|
354
|
+
runtime.eventBus.addListener(LocalModulesDeferredRegistrationsUpdateStartedEvent, (payload: unknown) => {
|
|
355
|
+
const attributes = {
|
|
356
|
+
"app.squide.registration_count": (payload as LocalModulesDeferredRegistrationsUpdateStartedEventPayload).registrationCount
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
if (deferredRegistrationsUpdateSpan) {
|
|
360
|
+
deferredRegistrationsUpdateSpan.addEvent("local-module-deferred-registrations-update-started", attributes);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
localModuleDeferredRegistrationsUpdateSpan = startActiveChildSpan(deferredRegistrationsUpdateSpan, (options, context) => {
|
|
364
|
+
const name = "local-module-deferred-registrations-update";
|
|
365
|
+
|
|
366
|
+
const span = getTracer().startSpan(name, {
|
|
367
|
+
attributes,
|
|
368
|
+
...options
|
|
369
|
+
}, context);
|
|
370
|
+
|
|
371
|
+
return {
|
|
372
|
+
name,
|
|
373
|
+
span
|
|
374
|
+
};
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Can occur multiple times.
|
|
379
|
+
runtime.eventBus.addListener(LocalModulesDeferredRegistrationsUpdateCompletedEvent, (payload: unknown) => {
|
|
380
|
+
if (deferredRegistrationsUpdateSpan) {
|
|
381
|
+
deferredRegistrationsUpdateSpan.addEvent("local-module-deferred-registrations-update-completed", {
|
|
382
|
+
"app.squide.registration_count": (payload as LocalModulesDeferredRegistrationsUpdateCompletedEventPayload).registrationCount
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (localModuleDeferredRegistrationsUpdateSpan) {
|
|
387
|
+
endActiveSpan(localModuleDeferredRegistrationsUpdateSpan);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Can occur multiple times.
|
|
392
|
+
runtime.eventBus.addListener(LocalModuleDeferredRegistrationUpdateFailedEvent, (payload: unknown) => {
|
|
393
|
+
const registrationError = payload as ModuleRegistrationError;
|
|
394
|
+
|
|
395
|
+
if (localModuleDeferredRegistrationsUpdateSpan) {
|
|
396
|
+
traceError(localModuleDeferredRegistrationsUpdateSpan.instance, registrationError);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// Can occur multiple times.
|
|
401
|
+
runtime.eventBus.addListener(RemoteModulesDeferredRegistrationsUpdateStartedEvent, (payload: unknown) => {
|
|
402
|
+
const attributes = {
|
|
403
|
+
"app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateStartedEventPayload).registrationCount
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
if (deferredRegistrationsUpdateSpan) {
|
|
407
|
+
deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-started", attributes);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
remoteModuleDeferredRegistrationsUpdateSpan = startActiveChildSpan(deferredRegistrationsUpdateSpan, (options, context) => {
|
|
411
|
+
const name = "remote-module-deferred-registrations-update";
|
|
412
|
+
|
|
413
|
+
const span = getTracer().startSpan(name, {
|
|
414
|
+
attributes,
|
|
415
|
+
...options
|
|
416
|
+
}, context);
|
|
417
|
+
|
|
418
|
+
return {
|
|
419
|
+
name,
|
|
420
|
+
span
|
|
421
|
+
};
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Can occur multiple times.
|
|
426
|
+
runtime.eventBus.addListener(RemoteModulesDeferredRegistrationsUpdateCompletedEvent, (payload: unknown) => {
|
|
427
|
+
if (deferredRegistrationsUpdateSpan) {
|
|
428
|
+
deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-completed", {
|
|
429
|
+
"app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload).registrationCount
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (remoteModuleDeferredRegistrationsUpdateSpan) {
|
|
434
|
+
endActiveSpan(remoteModuleDeferredRegistrationsUpdateSpan);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// Can occur multiple times.
|
|
439
|
+
runtime.eventBus.addListener(RemoteModuleDeferredRegistrationUpdateFailedEvent, (payload: unknown) => {
|
|
440
|
+
const registrationError = payload as RemoteModuleRegistrationError;
|
|
441
|
+
|
|
442
|
+
if (remoteModuleDeferredRegistrationsUpdateSpan) {
|
|
443
|
+
traceError(remoteModuleDeferredRegistrationsUpdateSpan.instance, registrationError);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function getRegisterFetchRequestHookFunction() {
|
|
449
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
450
|
+
// @ts-ignore
|
|
451
|
+
return globalThis.__WLP_HONEYCOMB_REGISTER_DYNAMIC_FETCH_REQUEST_HOOK;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export function registerHoneycombInstrumentation(runtime: FireflyRuntime) {
|
|
455
|
+
const registerFetchRequestHookFunction = getRegisterFetchRequestHookFunction();
|
|
456
|
+
|
|
457
|
+
if (registerFetchRequestHookFunction) {
|
|
458
|
+
registerActiveSpanStack();
|
|
459
|
+
|
|
460
|
+
const activeSpanOverrideFunction = createOverrideFetchRequestSpanWithActiveSpanContext(runtime.logger);
|
|
461
|
+
|
|
462
|
+
// Dynamically registering this request hook function to nest the HTTP requests
|
|
463
|
+
// of squide bootstrapping under the appropriate Honeycomb span.
|
|
464
|
+
registerFetchRequestHookFunction(activeSpanOverrideFunction);
|
|
465
|
+
} else {
|
|
466
|
+
runtime.logger.warning("[squide] Cannot register Honeycomb fetch request hook because \"globalThis.__WLP_HONEYCOMB_REGISTER_DYNAMIC_FETCH_REQUEST_HOOK\" is not available. Honeycomb instrumentation is still functional but in degraded mode.");
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
registerTrackingListeners(runtime);
|
|
470
|
+
|
|
471
|
+
// try {
|
|
472
|
+
// const registerFetchRequestHookFunction = getRegisterFetchRequestHookFunction();
|
|
473
|
+
|
|
474
|
+
// if (registerFetchRequestHookFunction) {
|
|
475
|
+
// const overrideFetchRequestHook = createOverrideFetchRequestWithManifestSectionSpanContext(runtime.logger);
|
|
476
|
+
|
|
477
|
+
// // Dynamically registering this request hook function to nest the HTTP requests
|
|
478
|
+
// // of the widgets initialization under the appropriate Honeycomb span.
|
|
479
|
+
// registerFetchRequestHookFunction(overrideFetchRequestHook);
|
|
480
|
+
// } else {
|
|
481
|
+
// runtime.logger.warning("[wlp-widgets] Cannot register Honeycomb fetch request hook because \"globalThis.__WLP_HONEYCOMB_REGISTER_DYNAMIC_FETCH_REQUEST_HOOK\" is not available. Honeycomb instrumentation is still functional but in degraded mode.");
|
|
482
|
+
// }
|
|
483
|
+
|
|
484
|
+
// registerTrackingListeners(runtime);
|
|
485
|
+
// } catch (error: unknown) {
|
|
486
|
+
// runtime.logger.error("[wlp-widgets] An error occured while registering Honeycomb instrumentation.", error);
|
|
487
|
+
// runtime.errorPropagator.propagate(error as Error);
|
|
488
|
+
// }
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export function canRegisterHoneycombInstrumentation() {
|
|
492
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
493
|
+
// @ts-ignore
|
|
494
|
+
return globalThis.__WLP_HONEYCOMB_INSTRUMENTATION_IS_REGISTERED__ === true;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// export function registerHoneycombInstrumentation(runtime: FireflyRuntime, namespace: string, serviceName: NonNullable<HoneycombSdkOptions["serviceName"]>, apiServiceUrls: PropagateTraceHeaderCorsUrls, options?: RegisterHoneycombInstrumentationOptions) {
|
|
498
|
+
// const augmentedOptions = getInstrumentationOptions(runtime, options);
|
|
499
|
+
|
|
500
|
+
// registerWorkleapHoneycombInstrumentation(namespace, serviceName, apiServiceUrls, augmentedOptions);
|
|
501
|
+
|
|
502
|
+
// registerTrackingListeners(runtime);
|
|
503
|
+
// registerActiveSpanStack();
|
|
504
|
+
// }
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type Context, type Exception, context as otelContext, trace as otelTrace, type Span, SpanKind, type SpanOptions, SpanStatusCode, type TimeInput } from "@opentelemetry/api";
|
|
2
|
+
import { type ActiveSpan, popActiveSpan, setActiveSpan } from "./activeSpan.ts";
|
|
3
|
+
|
|
4
|
+
export type StartSpanFactory = (options?: SpanOptions, context?: Context) => Span;
|
|
5
|
+
|
|
6
|
+
export function startSpan(factory: StartSpanFactory) {
|
|
7
|
+
return factory({ kind: SpanKind.CLIENT });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type StartChildSpanFactory = (options?: SpanOptions, context?: Context) => Span;
|
|
11
|
+
|
|
12
|
+
export function startChildSpan(parent: Span, factory: StartChildSpanFactory) {
|
|
13
|
+
const context = otelTrace.setSpan(otelContext.active(), parent);
|
|
14
|
+
|
|
15
|
+
return factory({ kind: SpanKind.CLIENT }, context);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface StartActiveSpanFactoryReturn {
|
|
19
|
+
name: string;
|
|
20
|
+
span: Span;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type StartActiveSpanFactory = (options?: SpanOptions, context?: Context) => StartActiveSpanFactoryReturn;
|
|
24
|
+
|
|
25
|
+
export function startActiveSpan(factory: StartActiveSpanFactory) {
|
|
26
|
+
const { name, span } = factory({ kind: SpanKind.CLIENT });
|
|
27
|
+
|
|
28
|
+
return setActiveSpan(name, span);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface StartActiveChildSpanFactoryReturn {
|
|
32
|
+
name: string;
|
|
33
|
+
span: Span;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type StartActiveChildSpanFactory = (options?: SpanOptions, context?: Context) => StartActiveChildSpanFactoryReturn;
|
|
37
|
+
|
|
38
|
+
export function startActiveChildSpan(parent: Span, factory: StartActiveChildSpanFactory) {
|
|
39
|
+
const context = otelTrace.setSpan(otelContext.active(), parent);
|
|
40
|
+
|
|
41
|
+
const { name, span } = factory({ kind: SpanKind.CLIENT }, context);
|
|
42
|
+
|
|
43
|
+
return setActiveSpan(name, span);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function endActiveSpan(span: ActiveSpan) {
|
|
47
|
+
span.instance.end();
|
|
48
|
+
|
|
49
|
+
popActiveSpan(span);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface TraceErrorOptions {
|
|
53
|
+
time?: TimeInput;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function traceError(span: Span, error: Exception, options: TraceErrorOptions = {}) {
|
|
57
|
+
const { time } = options;
|
|
58
|
+
|
|
59
|
+
span.recordException(error, time);
|
|
60
|
+
|
|
61
|
+
span.setStatus({
|
|
62
|
+
code: SpanStatusCode.ERROR
|
|
63
|
+
});
|
|
64
|
+
}
|
package/src/initializeFirefly.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { isFunction, registerLocalModules, type ModuleRegisterFunction, type Reg
|
|
|
2
2
|
import { registerRemoteModules, type RemoteDefinition } from "@squide/module-federation";
|
|
3
3
|
import { setMswAsReady } from "@squide/msw";
|
|
4
4
|
import { FireflyRuntime, type FireflyRuntimeOptions } from "./FireflyRuntime.tsx";
|
|
5
|
+
import { canRegisterHoneycombInstrumentation, registerHoneycombInstrumentation } from "./honeycomb/registerHoneycombInstrumentation.ts";
|
|
5
6
|
|
|
6
7
|
export const ApplicationBootstrappingStartedEvent = "squide-app-bootstrapping-started";
|
|
7
8
|
|
|
@@ -85,6 +86,12 @@ export function initializeFirefly<TContext = unknown, TData = unknown>(options:
|
|
|
85
86
|
plugins
|
|
86
87
|
});
|
|
87
88
|
|
|
89
|
+
if (canRegisterHoneycombInstrumentation()) {
|
|
90
|
+
registerHoneycombInstrumentation(runtime);
|
|
91
|
+
} else {
|
|
92
|
+
runtime.logger.debug("[squide] Cannot register Honeycomb instrumentation because the host application is not using the \"@workleap/honeycomb\" package.");
|
|
93
|
+
}
|
|
94
|
+
|
|
88
95
|
bootstrap(runtime, options);
|
|
89
96
|
|
|
90
97
|
return runtime;
|