@hue-run/sdk 0.18.1 → 0.18.2

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/dist/transport.js CHANGED
@@ -6,7 +6,8 @@ import { LogsExporterMetricsHelper, ProtobufLogsSerializer, ProtobufTraceSeriali
6
6
  import { BatchSpanProcessor, } from "@opentelemetry/sdk-trace";
7
7
  import { BatchLogRecordProcessor, } from "@opentelemetry/sdk-logs";
8
8
  import { isInsecureOrigin, REDACTION_CONTEXT_UNITS, validateOptions } from "./config.js";
9
- import { BLOBS_KEY, MAX_BLOB_ENTRIES, blobEntry, countFallback, BlobUploader, FALLBACK_MESSAGES, fallbackAttributes, fallbackRecord, MAX_HELD_BLOB_BYTES, newTally, mediaKey, offloadAttributes, offloadRecord, uploadBudgetMillis, } from "./blobs.js";
9
+ import { BLOBS_KEY, MAX_BLOB_ENTRIES, blobEntry, countFallback, BlobUploader, FALLBACK_MESSAGES, fallbackAttributes, fallbackRecord, heldBytesOf, MAX_HELD_BLOB_BYTES, newTally, mediaKey, offloadAttributes, offloadRecord, sizeOf, uploadBudgetMillis, } from "./blobs.js";
10
+ import { isByteSource } from "./large-media.js";
10
11
  import { advertisedLimits, BATCH_TARGET_BYTES, DEFAULT_RECEIVER_LIMITS, fitsWithoutCompression, } from "./limits.js";
11
12
  import { announcesLiveSpan, LIVE_SPAN_INTERVAL_MILLIS, MAX_LIVE_SPANS, pendingPlaceholder, PLACEHOLDERS_HEADER, withoutPlaceholderMarkers, } from "./live-spans.js";
12
13
  import { estimateRecordBytes, spanSource } from "./safety.js";
@@ -218,6 +219,8 @@ export class HueTransport {
218
219
  admissionDigests = new WeakMap();
219
220
  // The span's own messages each admitted span inspected, or left to export to inspect.
220
221
  admissionInspected = new WeakMap();
222
+ // The span's own values each admitted span held whole past the inspection bounds.
223
+ admissionLarge = new WeakMap();
221
224
  /** Uploads values over the inline limit apart from their spans; absent when disabled. */
222
225
  uploader;
223
226
  /** Bytes of values over the inline limit queued spans hold whole for upload, and each span's. */
@@ -245,9 +248,12 @@ export class HueTransport {
245
248
  this.liveSpans = this.options.enabled !== false && this.options.liveSpans;
246
249
  this.announcesLiveSpans = this.liveSpans;
247
250
  this.traceExporter = new ReportingExporter(this, "traces", ProtobufTraceSerializer, TraceExporterMetricsHelper, (span, cache, offload) => {
248
- // Export inspects only the messages admission inspected within the record's allowance.
249
- if (offload)
251
+ // Export inspects only the messages admission inspected within the record's allowance,
252
+ // and reads in place the values it held whole past the inspection bounds.
253
+ if (offload) {
250
254
  offload.inspected = this.admissionInspected.get(span);
255
+ offload.large = this.admissionLarge.get(span);
256
+ }
251
257
  return redactSpan(span, this.options, cache, {
252
258
  valueBytes: this.limits.valueBytes,
253
259
  cut: this.admissionCuts.get(span),
@@ -308,7 +314,7 @@ export class HueTransport {
308
314
  if (!queued) {
309
315
  const tally = newTally();
310
316
  for (const file of this.mediaAttachments(span))
311
- if (file.bytes.byteLength)
317
+ if (sizeOf(file.bytes))
312
318
  countFallback(tally, "budget", span.spanContext().traceId);
313
319
  this.reportOffload(tally);
314
320
  this.releaseMedia(span);
@@ -407,6 +413,8 @@ export class HueTransport {
407
413
  this.admissionDigests.set(snapshot.record, snapshot.digested);
408
414
  if (signal === "traces")
409
415
  this.admissionInspected.set(snapshot.record, snapshot.inspected);
416
+ if (snapshot.large.size)
417
+ this.admissionLarge.set(snapshot.record, snapshot.large);
410
418
  if (snapshot.held) {
411
419
  this.heldBytes += snapshot.held;
412
420
  this.held.set(snapshot.record, snapshot.held);
@@ -534,7 +542,7 @@ export class HueTransport {
534
542
  }
535
543
  /** @internal Retain a defensive copy within the existing held-value budget. */
536
544
  stageMedia(span, file) {
537
- if (this.closed || !this.offloadsValues() || file?.bytes.byteLength === 0)
545
+ if (this.closed || !this.offloadsValues() || (file && sizeOf(file.bytes) === 0))
538
546
  return true;
539
547
  if (!file) {
540
548
  const tally = newTally();
@@ -552,16 +560,18 @@ export class HueTransport {
552
560
  const files = this.media.get(identity) ?? [];
553
561
  if (files.length >= 64 ||
554
562
  (!this.media.has(identity) && this.media.size >= 2048) ||
555
- this.heldBytes + file.bytes.byteLength > MAX_HELD_BLOB_BYTES) {
563
+ this.heldBytes + heldBytesOf(file.bytes) > MAX_HELD_BLOB_BYTES) {
556
564
  this.uploadFallbacks++;
557
565
  this.issue("traces", "warning", 1, "File bytes did not fit the SDK's upload budget; their hue.file metadata was recorded", undefined, [span.spanContext().traceId]);
558
566
  return false;
559
567
  }
560
- const bytes = Uint8Array.from(file.bytes);
568
+ // A file read from disk as it is uploaded holds no bytes; bytes are copied, so a later change
569
+ // to the caller's buffer cannot alter what was recorded.
570
+ const bytes = isByteSource(file.bytes) ? file.bytes : Uint8Array.from(file.bytes);
561
571
  files.push({ ...file, bytes });
562
572
  this.media.set(identity, files);
563
573
  this.ownMedia(span, identity);
564
- this.heldBytes += bytes.byteLength;
574
+ this.heldBytes += heldBytesOf(bytes);
565
575
  return true;
566
576
  }
567
577
  /**
@@ -579,7 +589,7 @@ export class HueTransport {
579
589
  const kept = previous.filter((file) => {
580
590
  if (file.attribute !== attribute)
581
591
  return true;
582
- this.heldBytes -= file.bytes.byteLength;
592
+ this.heldBytes -= heldBytesOf(file.bytes);
583
593
  return false;
584
594
  });
585
595
  if (kept.length)
@@ -589,7 +599,7 @@ export class HueTransport {
589
599
  }
590
600
  const tally = newTally();
591
601
  for (const file of files) {
592
- if (!file.bytes.byteLength)
602
+ if (!sizeOf(file.bytes))
593
603
  continue;
594
604
  const refused = this.uploader?.refusal();
595
605
  if (!this.holdsValues() || refused) {
@@ -600,14 +610,14 @@ export class HueTransport {
600
610
  const staged = this.media.get(identity) ?? [];
601
611
  if (staged.length >= MAX_BLOB_ENTRIES ||
602
612
  (!this.media.has(identity) && this.media.size >= 2048) ||
603
- this.heldBytes + file.bytes.byteLength > MAX_HELD_BLOB_BYTES) {
613
+ this.heldBytes + heldBytesOf(file.bytes) > MAX_HELD_BLOB_BYTES) {
604
614
  countFallback(tally, "budget", traceId);
605
615
  continue;
606
616
  }
607
617
  // Attachment bytes are the attachment's own copy: held as they are.
608
618
  staged.push({ ...file, attribute });
609
619
  this.media.set(identity, staged);
610
- this.heldBytes += file.bytes.byteLength;
620
+ this.heldBytes += heldBytesOf(file.bytes);
611
621
  this.ownMedia(span, identity);
612
622
  }
613
623
  if (tally.fallbacks.size)
@@ -624,7 +634,7 @@ export class HueTransport {
624
634
  const tally = newTally();
625
635
  const staged = [];
626
636
  for (const file of files) {
627
- if (!file.bytes.byteLength)
637
+ if (!sizeOf(file.bytes))
628
638
  continue;
629
639
  const refused = this.uploader?.refusal();
630
640
  if (!this.holdsValues() || refused)
@@ -651,7 +661,7 @@ export class HueTransport {
651
661
  if (!pending)
652
662
  return;
653
663
  this.logParts.delete(body);
654
- const size = pending.files.reduce((total, file) => total + file.bytes.byteLength, 0);
664
+ const size = pending.files.reduce((total, file) => total + heldBytesOf(file.bytes), 0);
655
665
  if (this.heldBytes + size > MAX_HELD_BLOB_BYTES) {
656
666
  const tally = newTally();
657
667
  for (const _file of pending.files)
@@ -714,7 +724,7 @@ export class HueTransport {
714
724
  if (!files)
715
725
  return;
716
726
  for (const file of files)
717
- this.heldBytes -= file.bytes.byteLength;
727
+ this.heldBytes -= heldBytesOf(file.bytes);
718
728
  this.media.delete(identity);
719
729
  }
720
730
  sweepMedia() {
package/dist/types.d.ts CHANGED
@@ -256,11 +256,19 @@ export interface FileRecord {
256
256
  mediaType: string;
257
257
  /** Hex SHA-256 of the file's bytes; computed from `data` when omitted. */
258
258
  sha256?: string;
259
- /** Upload supplied bytes on this span when content capture is enabled. Defaults to false. */
259
+ /** Upload the file's bytes (`data`, or the file at `path`) on this span when content capture is
260
+ * enabled. Defaults to false. */
260
261
  upload?: boolean;
261
262
  /** The file's bytes, hashed and measured locally by default; a string is hashed as UTF-8.
262
- * Data larger than 25 MiB is omitted and counted as an instrumentation failure. */
263
+ * Data larger than 25 MiB, which would be held in memory until it is uploaded, is omitted and
264
+ * counted as an instrumentation failure. Give `data` or `path`, not both. */
263
265
  data?: Uint8Array | string;
266
+ /** A file to hash and measure locally (Node.js file system) instead of `data`. Up to 25 MiB it is
267
+ * read now, as `data` is. A larger regular file, up to Hue's 1 GB upload limit, is hashed now a
268
+ * slice at a time and, with `upload: true`, read again from disk when it is uploaded: it must
269
+ * stay unchanged until the client flushes, and is uploaded only if it still has the size and
270
+ * SHA-256 it was recorded with (otherwise it counts as an upload fallback). */
271
+ path?: string;
264
272
  /** Size in bytes; computed from `data` when omitted. */
265
273
  byteSize?: number;
266
274
  /** File name, recorded as `hue.file.name` only when `captureContent` is true. */
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Package version shared by the instrumentation scope and the export User-Agent. */
2
- export declare const sdkVersion = "0.18.1";
2
+ export declare const sdkVersion = "0.18.2";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/write-version.mjs from package.json; do not edit by hand.
2
2
  /** Package version shared by the instrumentation scope and the export User-Agent. */
3
- export const sdkVersion = "0.18.1";
3
+ export const sdkVersion = "0.18.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hue-run/sdk",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "publishConfig": {