@logbrew/sdk 0.1.30 → 0.1.31
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/core.cjs +45 -10
- package/package.json +1 -1
package/core.cjs
CHANGED
|
@@ -97,6 +97,8 @@ const MAX_CLIENT_REPORT_COUNT = 1_000_000_000;
|
|
|
97
97
|
const DELIVERY_HEALTH_SCHEMA_VERSION = 1;
|
|
98
98
|
const EVENT_QUEUE_FACTORY = Symbol.for("@logbrew/sdk.eventQueueFactory");
|
|
99
99
|
const CONTEXT_PROVIDER = Symbol.for("@logbrew/sdk.contextProvider");
|
|
100
|
+
// Runtime packages supply request-scoped breadcrumbs through this seam; core merges them into issues.
|
|
101
|
+
const BREADCRUMB_PROVIDER = Symbol.for("@logbrew/sdk.breadcrumbProvider");
|
|
100
102
|
const MAX_ERROR_CAUSES = 5;
|
|
101
103
|
const BUILTIN_ERROR_NAMES = new Set([
|
|
102
104
|
"AggregateError",
|
|
@@ -216,6 +218,7 @@ class LogBrewClient {
|
|
|
216
218
|
sdkVersion,
|
|
217
219
|
context,
|
|
218
220
|
[CONTEXT_PROVIDER]: contextProvider,
|
|
221
|
+
[BREADCRUMB_PROVIDER]: breadcrumbProvider,
|
|
219
222
|
maxRetries = 2,
|
|
220
223
|
eventFilter,
|
|
221
224
|
maxQueueSize = DEFAULT_MAX_QUEUE_SIZE,
|
|
@@ -237,6 +240,9 @@ class LogBrewClient {
|
|
|
237
240
|
if (contextProvider !== undefined && typeof contextProvider !== "function") {
|
|
238
241
|
throw new SdkError("validation_error", "context provider must be a function");
|
|
239
242
|
}
|
|
243
|
+
if (breadcrumbProvider !== undefined && typeof breadcrumbProvider !== "function") {
|
|
244
|
+
throw new SdkError("validation_error", "breadcrumb provider must be a function");
|
|
245
|
+
}
|
|
240
246
|
requireNonNegativeInteger("maxRetries", maxRetries);
|
|
241
247
|
if (eventFilter !== undefined && typeof eventFilter !== "function") {
|
|
242
248
|
throw new SdkError("validation_error", "eventFilter must be a function");
|
|
@@ -286,6 +292,7 @@ class LogBrewClient {
|
|
|
286
292
|
onEventDropped,
|
|
287
293
|
context: clientContext,
|
|
288
294
|
contextProvider,
|
|
295
|
+
breadcrumbProvider,
|
|
289
296
|
sdk: {
|
|
290
297
|
name: sdkName,
|
|
291
298
|
language: "javascript",
|
|
@@ -308,6 +315,7 @@ class LogBrewClient {
|
|
|
308
315
|
onEventDropped,
|
|
309
316
|
context,
|
|
310
317
|
contextProvider,
|
|
318
|
+
breadcrumbProvider,
|
|
311
319
|
eventStore,
|
|
312
320
|
eventQueueFactory,
|
|
313
321
|
transport,
|
|
@@ -327,6 +335,7 @@ class LogBrewClient {
|
|
|
327
335
|
this.onEventDropped = onEventDropped;
|
|
328
336
|
this.context = cloneTelemetryContext(context);
|
|
329
337
|
this.contextProvider = contextProvider;
|
|
338
|
+
this.breadcrumbProvider = breadcrumbProvider;
|
|
330
339
|
this.transport = transport;
|
|
331
340
|
this.sdk = sdk;
|
|
332
341
|
this.maxRetries = maxRetries;
|
|
@@ -632,20 +641,46 @@ class LogBrewClient {
|
|
|
632
641
|
}
|
|
633
642
|
|
|
634
643
|
#pushIssue(id, timestamp, attributes) {
|
|
635
|
-
|
|
644
|
+
if (attributes.breadcrumbs !== undefined) {
|
|
645
|
+
return this.#pushEvent("issue", id, timestamp, validateIssue(attributes));
|
|
646
|
+
}
|
|
647
|
+
const provided = this.#providedBreadcrumbs();
|
|
648
|
+
const merged = provided.breadcrumbs.length === 0
|
|
649
|
+
? this.issueBreadcrumbs
|
|
650
|
+
: [...this.issueBreadcrumbs, ...provided.breadcrumbs]
|
|
651
|
+
.sort((left, right) => Date.parse(left.timestamp) - Date.parse(right.timestamp));
|
|
652
|
+
const breadcrumbs = merged.slice(-MAX_ISSUE_BREADCRUMBS);
|
|
653
|
+
const truncated = attributes.breadcrumbsTruncated === true || this.issueBreadcrumbsTruncated
|
|
654
|
+
|| provided.truncated || merged.length > breadcrumbs.length;
|
|
655
|
+
const withBreadcrumbs = breadcrumbs.length === 0
|
|
636
656
|
? attributes
|
|
637
|
-
: {
|
|
638
|
-
...attributes,
|
|
639
|
-
breadcrumbs: this.issueBreadcrumbs,
|
|
640
|
-
...(
|
|
641
|
-
attributes.breadcrumbsTruncated === true || this.issueBreadcrumbsTruncated
|
|
642
|
-
? { breadcrumbsTruncated: true }
|
|
643
|
-
: {}
|
|
644
|
-
)
|
|
645
|
-
};
|
|
657
|
+
: { ...attributes, breadcrumbs, ...(truncated ? { breadcrumbsTruncated: true } : {}) };
|
|
646
658
|
return this.#pushEvent("issue", id, timestamp, validateIssue(withBreadcrumbs));
|
|
647
659
|
}
|
|
648
660
|
|
|
661
|
+
// Provider failures and invalid entries never cost the issue itself.
|
|
662
|
+
#providedBreadcrumbs() {
|
|
663
|
+
let provided;
|
|
664
|
+
try {
|
|
665
|
+
provided = this.breadcrumbProvider?.();
|
|
666
|
+
} catch {
|
|
667
|
+
return { breadcrumbs: [], truncated: false };
|
|
668
|
+
}
|
|
669
|
+
if (!provided || !Array.isArray(provided.breadcrumbs)) {
|
|
670
|
+
return { breadcrumbs: [], truncated: false };
|
|
671
|
+
}
|
|
672
|
+
const breadcrumbs = [];
|
|
673
|
+
let truncated = provided.truncated === true || provided.breadcrumbs.length > MAX_ISSUE_BREADCRUMBS;
|
|
674
|
+
for (const breadcrumb of provided.breadcrumbs.slice(-MAX_ISSUE_BREADCRUMBS)) {
|
|
675
|
+
try {
|
|
676
|
+
breadcrumbs.push(validateIssueBreadcrumb(breadcrumb));
|
|
677
|
+
} catch {
|
|
678
|
+
truncated = true;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return { breadcrumbs, truncated };
|
|
682
|
+
}
|
|
683
|
+
|
|
649
684
|
#pushEvent(eventType, id, timestamp, attributes) {
|
|
650
685
|
if (this.closed) {
|
|
651
686
|
throw new SdkError("shutdown_error", "client is already shut down");
|