@autter/otlp-ingester 1.3.3 → 1.3.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/memory.d.ts
CHANGED
|
@@ -24,15 +24,15 @@ export declare const platformEventSchema: z.ZodObject<{
|
|
|
24
24
|
service: string;
|
|
25
25
|
environment: string;
|
|
26
26
|
release: string;
|
|
27
|
+
kind: "oom_kill" | "restart";
|
|
27
28
|
instanceId: string;
|
|
28
29
|
platform: "ecs" | "kubernetes" | "other";
|
|
29
|
-
kind: "oom_kill" | "restart";
|
|
30
30
|
occurredAt: string;
|
|
31
31
|
}, {
|
|
32
32
|
service: string;
|
|
33
|
+
kind: "oom_kill" | "restart";
|
|
33
34
|
instanceId: string;
|
|
34
35
|
platform: "ecs" | "kubernetes" | "other";
|
|
35
|
-
kind: "oom_kill" | "restart";
|
|
36
36
|
occurredAt: string;
|
|
37
37
|
environment?: string | undefined;
|
|
38
38
|
release?: string | undefined;
|
|
@@ -8,7 +8,7 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
8
8
|
release: z.ZodOptional<z.ZodString>;
|
|
9
9
|
events: z.ZodArray<z.ZodObject<{
|
|
10
10
|
id: z.ZodOptional<z.ZodString>;
|
|
11
|
-
type: z.ZodEnum<["exception", "unhandled_rejection", "message", "session_start", "track_event", "outcome", "request_failure", "timing"]>;
|
|
11
|
+
type: z.ZodEnum<["exception", "unhandled_rejection", "message", "session_start", "track_event", "outcome", "request_failure", "csp_violation", "timing"]>;
|
|
12
12
|
timestamp: z.ZodString;
|
|
13
13
|
/** exception/message events: signal level. Defaults per type. */
|
|
14
14
|
severity: z.ZodOptional<z.ZodEnum<["fatal", "error", "warning", "info"]>>;
|
|
@@ -25,10 +25,11 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
25
25
|
route: z.ZodOptional<z.ZodString>;
|
|
26
26
|
context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
27
27
|
}, "strip", z.ZodTypeAny, {
|
|
28
|
-
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "timing";
|
|
28
|
+
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "csp_violation" | "timing";
|
|
29
29
|
message: string;
|
|
30
30
|
timestamp: string;
|
|
31
31
|
durationMs?: number | undefined;
|
|
32
|
+
route?: string | undefined;
|
|
32
33
|
filename?: string | undefined;
|
|
33
34
|
id?: string | undefined;
|
|
34
35
|
severity?: "fatal" | "error" | "warning" | "info" | undefined;
|
|
@@ -37,12 +38,12 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
37
38
|
errorType?: string | undefined;
|
|
38
39
|
line?: number | undefined;
|
|
39
40
|
column?: number | undefined;
|
|
40
|
-
route?: string | undefined;
|
|
41
41
|
context?: Record<string, unknown> | undefined;
|
|
42
42
|
}, {
|
|
43
|
-
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "timing";
|
|
43
|
+
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "csp_violation" | "timing";
|
|
44
44
|
timestamp: string;
|
|
45
45
|
durationMs?: number | undefined;
|
|
46
|
+
route?: string | undefined;
|
|
46
47
|
message?: string | undefined;
|
|
47
48
|
filename?: string | undefined;
|
|
48
49
|
id?: string | undefined;
|
|
@@ -52,7 +53,6 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
52
53
|
errorType?: string | undefined;
|
|
53
54
|
line?: number | undefined;
|
|
54
55
|
column?: number | undefined;
|
|
55
|
-
route?: string | undefined;
|
|
56
56
|
context?: Record<string, unknown> | undefined;
|
|
57
57
|
}>, "many">;
|
|
58
58
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -60,10 +60,11 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
60
60
|
environment: string;
|
|
61
61
|
version: 1;
|
|
62
62
|
events: {
|
|
63
|
-
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "timing";
|
|
63
|
+
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "csp_violation" | "timing";
|
|
64
64
|
message: string;
|
|
65
65
|
timestamp: string;
|
|
66
66
|
durationMs?: number | undefined;
|
|
67
|
+
route?: string | undefined;
|
|
67
68
|
filename?: string | undefined;
|
|
68
69
|
id?: string | undefined;
|
|
69
70
|
severity?: "fatal" | "error" | "warning" | "info" | undefined;
|
|
@@ -72,7 +73,6 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
72
73
|
errorType?: string | undefined;
|
|
73
74
|
line?: number | undefined;
|
|
74
75
|
column?: number | undefined;
|
|
75
|
-
route?: string | undefined;
|
|
76
76
|
context?: Record<string, unknown> | undefined;
|
|
77
77
|
}[];
|
|
78
78
|
release?: string | undefined;
|
|
@@ -82,9 +82,10 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
82
82
|
environment: string;
|
|
83
83
|
version: 1;
|
|
84
84
|
events: {
|
|
85
|
-
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "timing";
|
|
85
|
+
type: "exception" | "message" | "unhandled_rejection" | "session_start" | "track_event" | "outcome" | "request_failure" | "csp_violation" | "timing";
|
|
86
86
|
timestamp: string;
|
|
87
87
|
durationMs?: number | undefined;
|
|
88
|
+
route?: string | undefined;
|
|
88
89
|
message?: string | undefined;
|
|
89
90
|
filename?: string | undefined;
|
|
90
91
|
id?: string | undefined;
|
|
@@ -94,7 +95,6 @@ export declare const browserPayloadSchema: z.ZodObject<{
|
|
|
94
95
|
errorType?: string | undefined;
|
|
95
96
|
line?: number | undefined;
|
|
96
97
|
column?: number | undefined;
|
|
97
|
-
route?: string | undefined;
|
|
98
98
|
context?: Record<string, unknown> | undefined;
|
|
99
99
|
}[];
|
|
100
100
|
release?: string | undefined;
|
|
@@ -17,6 +17,7 @@ const browserEventSchema = z.object({
|
|
|
17
17
|
"track_event",
|
|
18
18
|
"outcome",
|
|
19
19
|
"request_failure",
|
|
20
|
+
"csp_violation",
|
|
20
21
|
"timing",
|
|
21
22
|
]),
|
|
22
23
|
timestamp: z.string().datetime(),
|
|
@@ -49,6 +50,7 @@ const TYPE_TO_ERROR_TYPE = {
|
|
|
49
50
|
message: "Message",
|
|
50
51
|
outcome: "OutcomeFailure",
|
|
51
52
|
request_failure: "HttpRequestError",
|
|
53
|
+
csp_violation: "CspViolation",
|
|
52
54
|
};
|
|
53
55
|
// Content-level gate for the free-form `context` bag. The schema whitelist
|
|
54
56
|
// above is structural; this masks obvious PII/secrets inside whatever a
|
|
@@ -78,6 +80,7 @@ const TYPE_TO_SEVERITY = {
|
|
|
78
80
|
message: "warning",
|
|
79
81
|
outcome: "error",
|
|
80
82
|
request_failure: "error",
|
|
83
|
+
csp_violation: "error",
|
|
81
84
|
};
|
|
82
85
|
export function normalizeBrowserPayload(payload) {
|
|
83
86
|
const occurrences = [];
|
package/dist/normalize-otlp.js
CHANGED
|
@@ -96,6 +96,7 @@ function severityOf(eventAttrs, spanAttrs) {
|
|
|
96
96
|
const MAX_SPANS_PER_REQUEST = 5000;
|
|
97
97
|
export function normalizeTraces(request) {
|
|
98
98
|
const occurrences = [];
|
|
99
|
+
const occurrenceSpanIds = [];
|
|
99
100
|
const spans = [];
|
|
100
101
|
const llmCalls = [];
|
|
101
102
|
const rollups = new Map();
|
|
@@ -143,6 +144,7 @@ export function normalizeTraces(request) {
|
|
|
143
144
|
for (const event of exceptionEvents) {
|
|
144
145
|
const eventAttrs = attrMap(event.attributes);
|
|
145
146
|
const handled = eventAttrs.get("autter.handled") === "true";
|
|
147
|
+
occurrenceSpanIds.push(span.spanId ?? "");
|
|
146
148
|
occurrences.push({
|
|
147
149
|
source: "server",
|
|
148
150
|
severity: severityOf(eventAttrs, attrs),
|
|
@@ -175,6 +177,7 @@ export function normalizeTraces(request) {
|
|
|
175
177
|
for (const event of failedOutcomes) {
|
|
176
178
|
const outcome = attrMap(event.attributes);
|
|
177
179
|
const name = (outcome.get("autter.outcome.name") ?? "operation").replace(EMAIL_VALUE_RE, "[redacted]").slice(0, 200);
|
|
180
|
+
occurrenceSpanIds.push(span.spanId ?? "");
|
|
178
181
|
occurrences.push({
|
|
179
182
|
source: "server", severity: "error", service: resource.service,
|
|
180
183
|
environment: resource.environment, release: resource.release,
|
|
@@ -186,6 +189,7 @@ export function normalizeTraces(request) {
|
|
|
186
189
|
});
|
|
187
190
|
}
|
|
188
191
|
if (exceptionEvents.length === 0 && failedOutcomes.length === 0 && isError) {
|
|
192
|
+
occurrenceSpanIds.push(span.spanId ?? "");
|
|
189
193
|
occurrences.push({
|
|
190
194
|
source: "server",
|
|
191
195
|
severity: severityOf(new Map(), attrs),
|
|
@@ -270,6 +274,7 @@ export function normalizeTraces(request) {
|
|
|
270
274
|
}
|
|
271
275
|
}
|
|
272
276
|
}
|
|
277
|
+
inheritHttpFromParent(occurrences, occurrenceSpanIds, spans);
|
|
273
278
|
return {
|
|
274
279
|
occurrences,
|
|
275
280
|
spans,
|
|
@@ -278,6 +283,62 @@ export function normalizeTraces(request) {
|
|
|
278
283
|
spanCount,
|
|
279
284
|
};
|
|
280
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Exception spans are often children named "Error" with no HTTP attributes.
|
|
288
|
+
* Copy method, route, status, and duration from the server span in the same
|
|
289
|
+
* trace so the issue can name the API that failed.
|
|
290
|
+
*/
|
|
291
|
+
function inheritHttpFromParent(occurrences, occurrenceSpanIds, spans) {
|
|
292
|
+
const byId = new Map();
|
|
293
|
+
for (const span of spans) {
|
|
294
|
+
if (span.spanId)
|
|
295
|
+
byId.set(span.spanId, span);
|
|
296
|
+
}
|
|
297
|
+
for (let i = 0; i < occurrences.length; i++) {
|
|
298
|
+
const occurrence = occurrences[i];
|
|
299
|
+
const spanId = occurrenceSpanIds[i];
|
|
300
|
+
if (!occurrence || !spanId)
|
|
301
|
+
continue;
|
|
302
|
+
const http = httpServerAncestor(byId, spanId);
|
|
303
|
+
if (!http)
|
|
304
|
+
continue;
|
|
305
|
+
if (!occurrence.route && http.route)
|
|
306
|
+
occurrence.route = http.route;
|
|
307
|
+
const method = methodFromSpan(http);
|
|
308
|
+
if (!occurrence.method && method)
|
|
309
|
+
occurrence.method = method;
|
|
310
|
+
if ((occurrence.statusCode == null || occurrence.statusCode === 0) &&
|
|
311
|
+
http.statusCode != null &&
|
|
312
|
+
http.statusCode > 0) {
|
|
313
|
+
occurrence.statusCode = http.statusCode;
|
|
314
|
+
}
|
|
315
|
+
if (http.durationMs > 0) {
|
|
316
|
+
const attributes = { ...(occurrence.attributes ?? {}) };
|
|
317
|
+
if (attributes["http.server.duration_ms"] == null) {
|
|
318
|
+
attributes["http.server.duration_ms"] = Math.round(http.durationMs);
|
|
319
|
+
occurrence.attributes = attributes;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function httpServerAncestor(byId, spanId) {
|
|
325
|
+
let current = byId.get(spanId) ?? null;
|
|
326
|
+
const seen = new Set();
|
|
327
|
+
while (current && current.spanId && !seen.has(current.spanId)) {
|
|
328
|
+
seen.add(current.spanId);
|
|
329
|
+
if (current.kind === "server")
|
|
330
|
+
return current;
|
|
331
|
+
const parentId = current.parentSpanId;
|
|
332
|
+
if (!parentId)
|
|
333
|
+
return null;
|
|
334
|
+
current = byId.get(parentId) ?? null;
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
function methodFromSpan(span) {
|
|
339
|
+
const raw = span.attributes?.["http.request.method"];
|
|
340
|
+
return typeof raw === "string" && raw.trim() ? raw.trim().toUpperCase().slice(0, 16) : null;
|
|
341
|
+
}
|
|
281
342
|
function minuteBucket(date) {
|
|
282
343
|
return new Date(Math.floor(date.getTime() / 60_000) * 60_000);
|
|
283
344
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autter/otlp-ingester",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Self-hostable OTLP + browser-error ingest service for Autter Runtime: normalises telemetry into a per-repo ClickHouse data model",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|