@obsunified/collector 2.4.3 → 2.4.4

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/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  randomHex,
10
10
  sha256Hex,
11
11
  sqlDbFor
12
- } from "./chunk-2FALTDCE.js";
12
+ } from "./chunk-VSOZJO6Y.js";
13
13
  import {
14
14
  LlmCallError,
15
15
  aiEvaluationEvidenceReferences,
@@ -3575,22 +3575,66 @@ var isPrivateIpv4 = (o) => o[0] === 0 || // "this" network / unspecified
3575
3575
  o[0] === 10 || o[0] === 127 || o[0] === 100 && o[1] >= 64 && o[1] <= 127 || // CGNAT
3576
3576
  o[0] === 169 && o[1] === 254 || // link-local incl. cloud metadata
3577
3577
  o[0] === 172 && o[1] >= 16 && o[1] <= 31 || o[0] === 192 && o[1] === 168 || o[0] >= 224;
3578
+ var parseIpv6 = (literal) => {
3579
+ let text = literal.replace(/%.*$/, "");
3580
+ const tail = /:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(text);
3581
+ let tailGroups = [];
3582
+ if (tail) {
3583
+ const v4 = parseIpv4(tail[1]);
3584
+ if (!v4) return null;
3585
+ tailGroups = [v4[0] << 8 | v4[1], v4[2] << 8 | v4[3]];
3586
+ text = text.slice(0, -tail[1].length);
3587
+ if (text.endsWith(":") && !text.endsWith("::")) text = text.slice(0, -1);
3588
+ }
3589
+ const halves = text.split("::");
3590
+ if (halves.length > 2) return null;
3591
+ const toGroups = (part) => {
3592
+ if (part === "") return [];
3593
+ const groups = [];
3594
+ for (const g of part.split(":")) {
3595
+ if (!/^[0-9a-f]{1,4}$/.test(g)) return null;
3596
+ groups.push(Number.parseInt(g, 16));
3597
+ }
3598
+ return groups;
3599
+ };
3600
+ const head = toGroups(halves[0]);
3601
+ const rest = halves.length === 2 ? toGroups(halves[1]) : [];
3602
+ if (!head || !rest) return null;
3603
+ const explicit = head.length + rest.length + tailGroups.length;
3604
+ if (halves.length === 1) {
3605
+ return explicit === 8 ? [...head, ...tailGroups] : null;
3606
+ }
3607
+ if (explicit > 7) return null;
3608
+ return [
3609
+ ...head,
3610
+ ...new Array(8 - explicit).fill(0),
3611
+ ...rest,
3612
+ ...tailGroups
3613
+ ];
3614
+ };
3615
+ var embeddedIpv4 = (hi, lo) => [
3616
+ hi >> 8,
3617
+ hi & 255,
3618
+ lo >> 8,
3619
+ lo & 255
3620
+ ];
3578
3621
  var isPrivateIpv6 = (host) => {
3579
3622
  const literal = host.replace(/^\[|\]$/g, "").toLowerCase();
3580
- if (literal === "::" || literal === "::1") return true;
3581
- const dotted = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(literal);
3582
- if (dotted) {
3583
- const v4 = parseIpv4(dotted[1]);
3584
- return v4 ? isPrivateIpv4(v4) : true;
3585
- }
3586
- const hex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(literal);
3587
- if (hex) {
3588
- const hi = Number.parseInt(hex[1], 16);
3589
- const lo = Number.parseInt(hex[2], 16);
3590
- return isPrivateIpv4([hi >> 8, hi & 255, lo >> 8, lo & 255]);
3591
- }
3592
- const first = Number.parseInt(literal.split(":")[0] || "0", 16);
3593
- if (Number.isNaN(first)) return true;
3623
+ const g = parseIpv6(literal);
3624
+ if (!g) return true;
3625
+ const zeroPrefix = (n) => g.slice(0, n).every((x) => x === 0);
3626
+ if (zeroPrefix(6)) {
3627
+ if (g[6] === 0 && (g[7] === 0 || g[7] === 1)) return true;
3628
+ return isPrivateIpv4(embeddedIpv4(g[6], g[7]));
3629
+ }
3630
+ if (zeroPrefix(5) && g[5] === 65535) {
3631
+ return isPrivateIpv4(embeddedIpv4(g[6], g[7]));
3632
+ }
3633
+ if (g[0] === 100 && g[1] === 65435 && g.slice(2, 6).every((x) => x === 0)) {
3634
+ return isPrivateIpv4(embeddedIpv4(g[6], g[7]));
3635
+ }
3636
+ if (g[0] === 8194) return isPrivateIpv4(embeddedIpv4(g[1], g[2]));
3637
+ const first = g[0];
3594
3638
  if ((first & 65024) === 64512) return true;
3595
3639
  if ((first & 65472) === 65152) return true;
3596
3640
  if ((first & 65280) === 65280) return true;
@@ -8502,6 +8546,17 @@ var createTelemetryCollectorApp = (pluginsOrConfig) => {
8502
8546
  app.use("/v1/*", config.auth.middleware);
8503
8547
  } else if (config.auth?.ingest) {
8504
8548
  app.use("/v1/*", config.auth.ingest);
8549
+ } else if (!config.allowUnauthenticatedIngest) {
8550
+ let warned = false;
8551
+ app.use("/v1/*", async (_c, next) => {
8552
+ if (!warned) {
8553
+ warned = true;
8554
+ runtime.logger.warn(
8555
+ "[collector] WARNING: /v1/* ingest is UNAUTHENTICATED \u2014 this app was built without `auth`, so anyone who can reach it can write telemetry. Pass `auth: { middleware: createIngestAuth() }` (and set INGEST_KEY or create a key in the dashboard), or set `allowUnauthenticatedIngest: true` to acknowledge and silence this warning."
8556
+ );
8557
+ }
8558
+ await next();
8559
+ });
8505
8560
  }
8506
8561
  if (config.dashboardAuth) {
8507
8562
  const { middleware } = config.dashboardAuth;
@@ -13750,9 +13805,12 @@ var AlertsStore = class {
13750
13805
  const cutoff = new Date(
13751
13806
  Date.now() - params.hours * 60 * 60 * 1e3
13752
13807
  ).toISOString();
13753
- const rs = await this.db.prepare(
13808
+ const limit = Math.min(params.limit ?? 500, 1e3);
13809
+ const rs = params.projectId ? await this.db.prepare(
13810
+ `SELECT * FROM alert_evaluations WHERE rule_id = ? AND project_id = ? AND evaluated_at >= ? ORDER BY evaluated_at DESC LIMIT ?`
13811
+ ).bind(params.ruleId, params.projectId, cutoff, limit).all() : await this.db.prepare(
13754
13812
  `SELECT * FROM alert_evaluations WHERE rule_id = ? AND evaluated_at >= ? ORDER BY evaluated_at DESC LIMIT ?`
13755
- ).bind(params.ruleId, cutoff, Math.min(params.limit ?? 500, 1e3)).all();
13813
+ ).bind(params.ruleId, cutoff, limit).all();
13756
13814
  const rows = rs.results ?? [];
13757
13815
  const projectId = params.projectId ?? rows[0]?.project_id;
13758
13816
  const rule = projectId ? await this.getRule(params.ruleId, projectId) : null;
@@ -17706,6 +17764,7 @@ var filterPprofByTraceId = async (profile, traceIdFilter) => {
17706
17764
  var DEFAULT_CHUNK_LIMIT = 100;
17707
17765
  var MAX_CHUNK_LIMIT = 500;
17708
17766
  var REPLAY_CHUNK_FETCH_CONCURRENCY = 8;
17767
+ var REPLAY_RESPONSE_BYTE_BUDGET = 64 * 1024 * 1024;
17709
17768
  async function mapWithConcurrency2(items, concurrency, mapper) {
17710
17769
  const results = new Array(items.length);
17711
17770
  let nextIndex = 0;
@@ -17720,6 +17779,23 @@ async function mapWithConcurrency2(items, concurrency, mapper) {
17720
17779
  );
17721
17780
  return results;
17722
17781
  }
17782
+ function selectReplayChunkPage(objects, offset, limit, byteBudget = REPLAY_RESPONSE_BYTE_BUDGET) {
17783
+ const window = objects.slice(offset, offset + limit);
17784
+ let bytes = 0;
17785
+ let count = 0;
17786
+ for (const obj of window) {
17787
+ const size = typeof obj.size === "number" && obj.size > 0 ? obj.size : 0;
17788
+ if (count > 0 && bytes + size > byteBudget) break;
17789
+ bytes += size;
17790
+ count++;
17791
+ }
17792
+ const selected = window.slice(0, count);
17793
+ const end = offset + count;
17794
+ return {
17795
+ selected,
17796
+ nextChunkOffset: end < objects.length ? end : null
17797
+ };
17798
+ }
17723
17799
  async function fetchReplayChunks(bucket, objects, concurrency = REPLAY_CHUNK_FETCH_CONCURRENCY) {
17724
17800
  const chunks2 = await mapWithConcurrency2(objects, concurrency, async (obj) => {
17725
17801
  const objectData = await bucket.get(obj.key);
@@ -17786,15 +17862,11 @@ var replayQueryRoutesPlugin = {
17786
17862
  ) || DEFAULT_CHUNK_LIMIT
17787
17863
  )
17788
17864
  );
17789
- const selectedObjects = objects.slice(
17790
- chunkOffset,
17791
- chunkOffset + chunkLimit
17792
- );
17865
+ const { selected: selectedObjects, nextChunkOffset } = selectReplayChunkPage(objects, chunkOffset, chunkLimit);
17793
17866
  const events = await fetchReplayChunks(
17794
17867
  c.env.REPLAYS_BUCKET,
17795
17868
  selectedObjects
17796
17869
  );
17797
- const nextChunkOffset = chunkOffset + chunkLimit < objects.length ? chunkOffset + chunkLimit : null;
17798
17870
  return c.json({
17799
17871
  metadata,
17800
17872
  events,
@@ -20805,19 +20877,34 @@ var anyValueToString = (v) => {
20805
20877
  return bytesToBase64(v.value.value);
20806
20878
  case "arrayValue":
20807
20879
  case "kvlistValue":
20808
- return JSON.stringify(adaptAnyValue(v));
20880
+ return JSON.stringify(adaptAnyValueAt(v, 1));
20809
20881
  default:
20810
20882
  return "";
20811
20883
  }
20812
20884
  };
20813
- var keyValuesToRecord = (kvs) => {
20885
+ var MAX_ANY_VALUE_DEPTH = 64;
20886
+ var TRUNCATED_DEPTH_MARKER = `[truncated: nested deeper than ${MAX_ANY_VALUE_DEPTH} levels]`;
20887
+ var setOwn = (out, key, value) => {
20888
+ if (key === "__proto__") {
20889
+ Object.defineProperty(out, key, {
20890
+ value,
20891
+ enumerable: true,
20892
+ writable: true,
20893
+ configurable: true
20894
+ });
20895
+ } else {
20896
+ out[key] = value;
20897
+ }
20898
+ };
20899
+ var keyValuesToRecord = (kvs) => keyValuesToRecordAt(kvs, 0);
20900
+ var keyValuesToRecordAt = (kvs, depth) => {
20814
20901
  const out = {};
20815
20902
  for (const kv of kvs) {
20816
- out[kv.key] = anyValueToJson(kv.value);
20903
+ setOwn(out, kv.key, anyValueToJson(kv.value, depth + 1));
20817
20904
  }
20818
20905
  return out;
20819
20906
  };
20820
- var anyValueToJson = (v) => {
20907
+ var anyValueToJson = (v, depth) => {
20821
20908
  if (!v) return null;
20822
20909
  switch (v.value.case) {
20823
20910
  case "stringValue":
@@ -20831,18 +20918,21 @@ var anyValueToJson = (v) => {
20831
20918
  case "bytesValue":
20832
20919
  return bytesToBase64(v.value.value);
20833
20920
  case "arrayValue":
20834
- return v.value.value.values.map((x) => anyValueToJson(x));
20921
+ if (depth > MAX_ANY_VALUE_DEPTH) return TRUNCATED_DEPTH_MARKER;
20922
+ return v.value.value.values.map((x) => anyValueToJson(x, depth + 1));
20835
20923
  case "kvlistValue":
20836
- return keyValuesToRecord(v.value.value.values);
20924
+ if (depth > MAX_ANY_VALUE_DEPTH) return TRUNCATED_DEPTH_MARKER;
20925
+ return keyValuesToRecordAt(v.value.value.values, depth);
20837
20926
  default:
20838
20927
  return null;
20839
20928
  }
20840
20929
  };
20841
- var adaptKeyValue = (kv) => ({
20930
+ var adaptKeyValue = (kv) => adaptKeyValueAt(kv, 0);
20931
+ var adaptKeyValueAt = (kv, depth) => ({
20842
20932
  key: kv.key,
20843
- value: kv.value ? adaptAnyValue(kv.value) : void 0
20933
+ value: kv.value ? adaptAnyValueAt(kv.value, depth + 1) : void 0
20844
20934
  });
20845
- var adaptAnyValue = (v) => {
20935
+ var adaptAnyValueAt = (v, depth) => {
20846
20936
  switch (v.value.case) {
20847
20937
  case "stringValue":
20848
20938
  return { stringValue: v.value.value };
@@ -20853,15 +20943,21 @@ var adaptAnyValue = (v) => {
20853
20943
  case "doubleValue":
20854
20944
  return { doubleValue: v.value.value };
20855
20945
  case "arrayValue":
20946
+ if (depth > MAX_ANY_VALUE_DEPTH)
20947
+ return { stringValue: TRUNCATED_DEPTH_MARKER };
20856
20948
  return {
20857
20949
  arrayValue: {
20858
- values: v.value.value.values.map((x) => adaptAnyValue(x))
20950
+ values: v.value.value.values.map(
20951
+ (x) => adaptAnyValueAt(x, depth + 1)
20952
+ )
20859
20953
  }
20860
20954
  };
20861
20955
  case "kvlistValue":
20956
+ if (depth > MAX_ANY_VALUE_DEPTH)
20957
+ return { stringValue: TRUNCATED_DEPTH_MARKER };
20862
20958
  return {
20863
20959
  kvlistValue: {
20864
- values: v.value.value.values.map(adaptKeyValue)
20960
+ values: v.value.value.values.map((kv) => adaptKeyValueAt(kv, depth))
20865
20961
  }
20866
20962
  };
20867
20963
  case "bytesValue":
@@ -20889,7 +20985,7 @@ var bytesToBase64 = (bytes) => {
20889
20985
  };
20890
20986
 
20891
20987
  // src/otlp/decode/logs.ts
20892
- var decodeLogsRequest = (body) => {
20988
+ var decodeLogsRequestCapped = (body, maxRecords) => {
20893
20989
  let msg;
20894
20990
  try {
20895
20991
  msg = body.wireFormat === "protobuf" ? fromBinary(ExportLogsServiceRequestSchema, body.bytes) : fromJson(ExportLogsServiceRequestSchema, decodeJsonBody(body.bytes));
@@ -20900,16 +20996,25 @@ var decodeLogsRequest = (body) => {
20900
20996
  );
20901
20997
  }
20902
20998
  const out = [];
20999
+ let rejected = 0;
20903
21000
  for (const rl of msg.resourceLogs) {
21001
+ if (out.length >= maxRecords) {
21002
+ for (const sl of rl.scopeLogs) rejected += sl.logRecords.length;
21003
+ continue;
21004
+ }
20904
21005
  const serviceName = extractServiceName(rl.resource?.attributes);
20905
21006
  for (const sl of rl.scopeLogs) {
20906
21007
  const loggerName = sl.scope?.name || null;
20907
21008
  for (const log of sl.logRecords) {
21009
+ if (out.length >= maxRecords) {
21010
+ rejected++;
21011
+ continue;
21012
+ }
20908
21013
  out.push(adaptLogRecord(log, serviceName, loggerName));
20909
21014
  }
20910
21015
  }
20911
21016
  }
20912
- return out;
21017
+ return { records: out, rejected };
20913
21018
  };
20914
21019
  var adaptLogRecord = (log, serviceName, loggerName) => {
20915
21020
  const ts = log.timeUnixNano || log.observedTimeUnixNano;
@@ -20959,7 +21064,7 @@ var ExportMetricsServiceResponseSchema = /* @__PURE__ */ messageDesc6(file_opent
20959
21064
  var ExportMetricsPartialSuccessSchema = /* @__PURE__ */ messageDesc6(file_opentelemetry_proto_collector_metrics_v1_metrics_service, 2);
20960
21065
 
20961
21066
  // src/otlp/decode/metrics.ts
20962
- var decodeMetricsRequest = (body) => {
21067
+ var decodeMetricsRequestCapped = (body, maxPoints) => {
20963
21068
  let msg;
20964
21069
  try {
20965
21070
  msg = body.wireFormat === "protobuf" ? fromBinary2(ExportMetricsServiceRequestSchema, body.bytes) : fromJson2(
@@ -20973,7 +21078,18 @@ var decodeMetricsRequest = (body) => {
20973
21078
  );
20974
21079
  }
20975
21080
  const out = [];
21081
+ let rejected = 0;
20976
21082
  for (const rm of msg.resourceMetrics) {
21083
+ if (out.length >= maxPoints) {
21084
+ for (const sm of rm.scopeMetrics) rejected += countPoints(sm);
21085
+ continue;
21086
+ }
21087
+ const remaining = maxPoints - out.length;
21088
+ const total = rm.scopeMetrics.reduce((n, sm) => n + countPoints(sm), 0);
21089
+ if (total > remaining) {
21090
+ rejected += total - remaining;
21091
+ trimScopeMetrics(rm.scopeMetrics, remaining);
21092
+ }
20977
21093
  const resourceAttrs = rm.resource?.attributes ?? [];
20978
21094
  const resourceAttrsJson = resourceAttrs.length ? JSON.stringify(keyValuesToRecord(resourceAttrs)) : null;
20979
21095
  const serviceName = extractServiceName(resourceAttrs);
@@ -20981,7 +21097,34 @@ var decodeMetricsRequest = (body) => {
20981
21097
  addMetrics(out, rm, sm, serviceName, resourceAttrsJson);
20982
21098
  }
20983
21099
  }
20984
- return out;
21100
+ return { points: out, rejected };
21101
+ };
21102
+ var metricPointCount = (metric) => {
21103
+ switch (metric.data.case) {
21104
+ case "gauge":
21105
+ case "sum":
21106
+ case "histogram":
21107
+ case "exponentialHistogram":
21108
+ case "summary":
21109
+ return metric.data.value.dataPoints.length;
21110
+ default:
21111
+ return 0;
21112
+ }
21113
+ };
21114
+ var countPoints = (sm) => sm.metrics.reduce((n, m) => n + metricPointCount(m), 0);
21115
+ var trimScopeMetrics = (scopeMetrics, budget) => {
21116
+ let left = budget;
21117
+ for (const sm of scopeMetrics) {
21118
+ for (const metric of sm.metrics) {
21119
+ const n = metricPointCount(metric);
21120
+ if (n === 0) continue;
21121
+ if (n > left) {
21122
+ const data = metric.data.value;
21123
+ data.dataPoints = data.dataPoints.slice(0, left);
21124
+ }
21125
+ left -= Math.min(n, left);
21126
+ }
21127
+ }
20985
21128
  };
20986
21129
  var addMetrics = (out, rm, sm, serviceName, resourceAttrsJson) => {
20987
21130
  const scopeName = sm.scope?.name || null;
@@ -21225,7 +21368,31 @@ var ExportTraceServiceResponseSchema = /* @__PURE__ */ messageDesc8(file_opentel
21225
21368
  var ExportTracePartialSuccessSchema = /* @__PURE__ */ messageDesc8(file_opentelemetry_proto_collector_trace_v1_trace_service, 2);
21226
21369
 
21227
21370
  // src/otlp/decode/traces.ts
21228
- var decodeTraceRequest = (body) => {
21371
+ var decodeTraceRequestCapped = (body, maxSpans) => {
21372
+ const msg = parseTraceMessage(body);
21373
+ let accepted = 0;
21374
+ let rejected = 0;
21375
+ const resourceSpans = [];
21376
+ for (const rs of msg.resourceSpans) {
21377
+ for (const ss of rs.scopeSpans) {
21378
+ const kept = [];
21379
+ for (const s of ss.spans) {
21380
+ if (!hasValidIds(s)) continue;
21381
+ if (accepted >= maxSpans) {
21382
+ rejected++;
21383
+ } else {
21384
+ kept.push(s);
21385
+ accepted++;
21386
+ }
21387
+ }
21388
+ ss.spans = kept;
21389
+ }
21390
+ resourceSpans.push(adaptResourceSpans(rs));
21391
+ }
21392
+ return { request: { resourceSpans }, accepted, rejected };
21393
+ };
21394
+ var hasValidIds = (s) => s.traceId.length === 16 && s.spanId.length === 8;
21395
+ var parseTraceMessage = (body) => {
21229
21396
  let msg;
21230
21397
  try {
21231
21398
  msg = body.wireFormat === "protobuf" ? fromBinary3(ExportTraceServiceRequestSchema, body.bytes) : fromJson3(ExportTraceServiceRequestSchema, decodeJsonBody(body.bytes));
@@ -21235,14 +21402,14 @@ var decodeTraceRequest = (body) => {
21235
21402
  400
21236
21403
  );
21237
21404
  }
21238
- return { resourceSpans: msg.resourceSpans.map(adaptResourceSpans) };
21405
+ return msg;
21239
21406
  };
21240
21407
  var adaptResourceSpans = (rs) => ({
21241
21408
  resource: rs.resource ? { attributes: rs.resource.attributes.map(adaptKeyValue) } : void 0,
21242
21409
  scopeSpans: rs.scopeSpans.map((ss) => ({
21243
21410
  scope: ss.scope ? { name: ss.scope.name, version: ss.scope.version } : void 0,
21244
21411
  spans: ss.spans.flatMap((s) => {
21245
- if (s.traceId.length !== 16 || s.spanId.length !== 8) return [];
21412
+ if (!hasValidIds(s)) return [];
21246
21413
  return [
21247
21414
  {
21248
21415
  traceId: bytesToHex(s.traceId),
@@ -21353,19 +21520,18 @@ var logsReceiverPlugin = {
21353
21520
  throw err;
21354
21521
  }
21355
21522
  let decoded;
21523
+ let rejected = 0;
21356
21524
  try {
21357
- decoded = decodeLogsRequest(body);
21525
+ ({ records: decoded, rejected } = decodeLogsRequestCapped(
21526
+ body,
21527
+ MAX_LOGS_PER_REQUEST
21528
+ ));
21358
21529
  } catch (err) {
21359
21530
  if (err instanceof OtlpDecodeError) {
21360
21531
  return c.json({ error: err.message }, err.status);
21361
21532
  }
21362
21533
  throw err;
21363
21534
  }
21364
- let rejected = 0;
21365
- if (decoded.length > MAX_LOGS_PER_REQUEST) {
21366
- rejected = decoded.length - MAX_LOGS_PER_REQUEST;
21367
- decoded = decoded.slice(0, MAX_LOGS_PER_REQUEST);
21368
- }
21369
21535
  const store = new LogsStore(sqlDbFor(c.env));
21370
21536
  const retentionHours = getConfiguredRetentionHours5(c.env.RETENTION_HOURS);
21371
21537
  const now = /* @__PURE__ */ new Date();
@@ -21474,19 +21640,18 @@ var metricsReceiverPlugin = {
21474
21640
  throw err;
21475
21641
  }
21476
21642
  let points;
21643
+ let rejected = 0;
21477
21644
  try {
21478
- points = decodeMetricsRequest(body);
21645
+ ({ points, rejected } = decodeMetricsRequestCapped(
21646
+ body,
21647
+ MAX_POINTS_PER_REQUEST
21648
+ ));
21479
21649
  } catch (err) {
21480
21650
  if (err instanceof OtlpDecodeError) {
21481
21651
  return c.json({ error: err.message }, err.status);
21482
21652
  }
21483
21653
  throw err;
21484
21654
  }
21485
- let rejected = 0;
21486
- if (points.length > MAX_POINTS_PER_REQUEST) {
21487
- rejected = points.length - MAX_POINTS_PER_REQUEST;
21488
- points = points.slice(0, MAX_POINTS_PER_REQUEST);
21489
- }
21490
21655
  const retentionHours = getConfiguredRetentionHours6(c.env.RETENTION_HOURS);
21491
21656
  const now = /* @__PURE__ */ new Date();
21492
21657
  const receivedAt = now.toISOString();
@@ -21743,34 +21908,18 @@ var otlpReceiverPlugin = {
21743
21908
  }
21744
21909
  throw err;
21745
21910
  }
21746
- let payload;
21911
+ let capped;
21747
21912
  try {
21748
- payload = decodeTraceRequest(body);
21913
+ capped = decodeTraceRequestCapped(body, MAX_SPANS_PER_REQUEST);
21749
21914
  } catch (err) {
21750
21915
  if (err instanceof OtlpDecodeError) {
21751
21916
  return c.json({ error: err.message }, err.status);
21752
21917
  }
21753
21918
  throw err;
21754
21919
  }
21755
- let total = 0;
21756
- let rejected = 0;
21757
- const trimmedResourceSpans = [];
21758
- for (const rs of payload.resourceSpans ?? []) {
21759
- const scopeSpans = [];
21760
- for (const ss of rs.scopeSpans ?? []) {
21761
- const spans2 = [];
21762
- for (const s of ss.spans ?? []) {
21763
- if (total >= MAX_SPANS_PER_REQUEST) {
21764
- rejected++;
21765
- } else {
21766
- spans2.push(s);
21767
- total++;
21768
- }
21769
- }
21770
- scopeSpans.push({ ...ss, spans: spans2 });
21771
- }
21772
- trimmedResourceSpans.push({ ...rs, scopeSpans });
21773
- }
21920
+ const total = capped.accepted;
21921
+ const rejected = capped.rejected;
21922
+ const trimmedResourceSpans = capped.request.resourceSpans;
21774
21923
  const parsedSpans = toStoredSpans(
21775
21924
  { resourceSpans: trimmedResourceSpans },
21776
21925
  projectId,
@@ -21973,6 +22122,7 @@ var profileId = () => {
21973
22122
  for (let i = 0; i < 16; i++) randStr += ENCODING[bytes[i] % 32];
21974
22123
  return timeStr + randStr;
21975
22124
  };
22125
+ var safeFilenamePart = (value) => value.replace(/[^A-Za-z0-9_.-]/g, "_");
21976
22126
  var parseNonNegInt = (value, fallback) => {
21977
22127
  if (value == null) return fallback;
21978
22128
  const parsed = Number.parseInt(value, 10);
@@ -22128,7 +22278,7 @@ var profileRoutesPlugin = {
22128
22278
  headers: {
22129
22279
  "Content-Type": "application/octet-stream",
22130
22280
  "Content-Encoding": "gzip",
22131
- "Content-Disposition": `attachment; filename="${id}-trace-${filterTraceId.slice(0, 8)}.pprof.gz"`,
22281
+ "Content-Disposition": `attachment; filename="${safeFilenamePart(id)}-trace-${safeFilenamePart(filterTraceId.slice(0, 8))}.pprof.gz"`,
22132
22282
  // Surface the size shrink so the UI can show savings.
22133
22283
  "X-Obs-Filter-Original-Bytes": String(raw.byteLength),
22134
22284
  "X-Obs-Filter-Filtered-Bytes": String(filtered.byteLength)
@@ -22148,7 +22298,7 @@ var profileRoutesPlugin = {
22148
22298
  return new Response(obj.body, {
22149
22299
  headers: {
22150
22300
  "Content-Type": "application/octet-stream",
22151
- "Content-Disposition": `attachment; filename="${id}.pprof.gz"`
22301
+ "Content-Disposition": `attachment; filename="${safeFilenamePart(id)}.pprof.gz"`
22152
22302
  }
22153
22303
  });
22154
22304
  }
@@ -24762,7 +24912,8 @@ var createDefaultCollectorApp = (config) => createTelemetryCollectorApp({
24762
24912
  dashboardAuth: config?.dashboardAuth,
24763
24913
  logger: config?.logger,
24764
24914
  withChildSpan: config?.withChildSpan,
24765
- sqlDb: config?.sqlDb
24915
+ sqlDb: config?.sqlDb,
24916
+ allowUnauthenticatedIngest: config?.allowUnauthenticatedIngest
24766
24917
  });
24767
24918
  var src_default = createTelemetryCollectorApp(allPlugins);
24768
24919
  export {