@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/README.md +7 -3
- package/dist/auth.js +1 -1
- package/dist/{chunk-2FALTDCE.js → chunk-VSOZJO6Y.js} +12 -1
- package/dist/chunk-VSOZJO6Y.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +227 -76
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/framework/collector.ts +22 -0
- package/src/framework/ingest-auth-warning.test.ts +71 -0
- package/src/index.ts +1 -0
- package/src/lib/alerts-store.test.ts +31 -0
- package/src/lib/alerts-store.ts +17 -6
- package/src/lib/projects-store.test.ts +44 -1
- package/src/lib/projects-store.ts +21 -0
- package/src/lib/webhook-url.test.ts +49 -0
- package/src/lib/webhook-url.ts +72 -14
- package/src/otlp/decode/logs.ts +30 -2
- package/src/otlp/decode/metrics.ts +67 -2
- package/src/otlp/decode/traces.ts +57 -4
- package/src/otlp/decode/values.ts +64 -10
- package/src/otlp/decode.test.ts +305 -0
- package/src/otlp/decode.ts +9 -3
- package/src/plugins/autosre-routes.ts +9 -0
- package/src/plugins/logs-receiver.ts +8 -8
- package/src/plugins/metrics-receiver.ts +10 -9
- package/src/plugins/otlp-receiver.ts +10 -26
- package/src/plugins/profile-routes.test.ts +22 -0
- package/src/plugins/profile-routes.ts +11 -2
- package/src/plugins/replay-query-routes.test.ts +63 -1
- package/src/plugins/replay-query-routes.ts +40 -9
- package/dist/chunk-2FALTDCE.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
randomHex,
|
|
10
10
|
sha256Hex,
|
|
11
11
|
sqlDbFor
|
|
12
|
-
} from "./chunk-
|
|
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
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
if (
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
if (
|
|
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
|
|
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,
|
|
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
|
|
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(
|
|
20880
|
+
return JSON.stringify(adaptAnyValueAt(v, 1));
|
|
20809
20881
|
default:
|
|
20810
20882
|
return "";
|
|
20811
20883
|
}
|
|
20812
20884
|
};
|
|
20813
|
-
var
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 ?
|
|
20933
|
+
value: kv.value ? adaptAnyValueAt(kv.value, depth + 1) : void 0
|
|
20844
20934
|
});
|
|
20845
|
-
var
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
21911
|
+
let capped;
|
|
21747
21912
|
try {
|
|
21748
|
-
|
|
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
|
-
|
|
21756
|
-
|
|
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 {
|