@oneuptime/common 10.5.17 → 10.5.19
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/Server/API/TelemetryAPI.ts +6 -0
- package/Server/EnvironmentConfig.ts +27 -0
- package/Server/Infrastructure/ClickhouseDatabase.ts +21 -1
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +19 -0
- package/Server/Infrastructure/PostgresDatabase.ts +27 -1
- package/Server/Infrastructure/QueueWorker.ts +14 -3
- package/Server/Infrastructure/Redis.ts +11 -0
- package/Server/Services/TelemetryAttributeService.ts +38 -2
- package/Server/Utils/Express.ts +32 -0
- package/Server/Utils/GracefulShutdown.ts +194 -0
- package/Server/Utils/Monitor/MonitorLogUtil.ts +22 -17
- package/Server/Utils/Profiling.ts +14 -6
- package/Server/Utils/Telemetry/LogExceptionExtractor.ts +289 -0
- package/Server/Utils/Telemetry/StackTraceParser.ts +423 -0
- package/Server/Utils/Telemetry.ts +15 -5
- package/Tests/Server/Services/TelemetryAttributeService.test.ts +83 -0
- package/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.ts +0 -0
- package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +7 -1
- package/UI/Components/Dictionary/Dictionary.tsx +19 -0
- package/UI/Components/Filters/FiltersForm.tsx +1 -0
- package/UI/Components/Filters/JSONFilter.tsx +2 -0
- package/UI/Components/Filters/Types/Filter.ts +1 -0
- package/build/dist/Server/API/TelemetryAPI.js +4 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +19 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +16 -2
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +10 -9
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/PostgresDatabase.js +20 -1
- package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +9 -2
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Infrastructure/Redis.js +5 -0
- package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
- package/build/dist/Server/Services/TelemetryAttributeService.js +23 -1
- package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
- package/build/dist/Server/Utils/Express.js +23 -0
- package/build/dist/Server/Utils/Express.js.map +1 -1
- package/build/dist/Server/Utils/GracefulShutdown.js +145 -0
- package/build/dist/Server/Utils/GracefulShutdown.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +12 -10
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
- package/build/dist/Server/Utils/Profiling.js +8 -3
- package/build/dist/Server/Utils/Profiling.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +214 -0
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/StackTraceParser.js +365 -0
- package/build/dist/Server/Utils/Telemetry/StackTraceParser.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +10 -4
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js +50 -0
- package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js.map +1 -0
- package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js +0 -0
- package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js.map +1 -0
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +7 -1
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
- package/build/dist/UI/Components/Dictionary/Dictionary.js +10 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/Filters/FiltersForm.js +1 -1
- package/build/dist/UI/Components/Filters/FiltersForm.js.map +1 -1
- package/build/dist/UI/Components/Filters/JSONFilter.js +1 -1
- package/build/dist/UI/Components/Filters/JSONFilter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import StackTraceParser from "./StackTraceParser";
|
|
2
|
+
/**
|
|
3
|
+
* OTel log severityNumber >= 17 is ERROR (17-20) or FATAL (21-24). Path B only
|
|
4
|
+
* scans those — the overwhelming majority of logs are below this and never
|
|
5
|
+
* reach the parser.
|
|
6
|
+
*/
|
|
7
|
+
const MIN_ERROR_SEVERITY_NUMBER = 17;
|
|
8
|
+
/**
|
|
9
|
+
* Only the first 16 KB of a body is parsed. A clean single-record stack trace
|
|
10
|
+
* fits comfortably (~150 frames); the top frames are the most diagnostic and
|
|
11
|
+
* are at the front. Guards against pathological multi-megabyte error logs on
|
|
12
|
+
* the hot path.
|
|
13
|
+
*/
|
|
14
|
+
const MAX_PARSE_BODY_LENGTH = 16 * 1024;
|
|
15
|
+
/*
|
|
16
|
+
* Raw log bodies are unbounded (unlike SDK-bounded span exception.stacktrace),
|
|
17
|
+
* so clamp what we store into the ZSTD stackTrace column and the Postgres summary.
|
|
18
|
+
*/
|
|
19
|
+
const MAX_STORED_STACK_TRACE_LENGTH = 64 * 1024;
|
|
20
|
+
const MAX_MESSAGE_LENGTH = 1024;
|
|
21
|
+
/**
|
|
22
|
+
* Single pre-compiled signature for "this body plausibly contains a stack
|
|
23
|
+
* trace". Evaluated once before the (more expensive) multi-language parser.
|
|
24
|
+
* Covers: Python traceback header, JS/Java `at file:line`, Go panic/goroutine,
|
|
25
|
+
* Python `File "...", line N`, and a typed `SomethingException`/`SomethingError`.
|
|
26
|
+
*/
|
|
27
|
+
const LOOKS_LIKE_STACK_TRACE = /(?:Traceback \(most recent call last\)|\n\s+at\s+.+:\d+|\bpanic:\s|goroutine\s+\d+\s+\[|\n\s*File\s+"[^"]+",\s+line\s+\d+|\b[A-Za-z_][\w.$]*(?:Exception|Error)\b)/;
|
|
28
|
+
// Header parsers for deriving exceptionType + message from a raw body.
|
|
29
|
+
const PYTHON_TRACEBACK_HEADER = /^Traceback \(most recent call last\):/;
|
|
30
|
+
const JAVA_THREAD_PREFIX = /^Exception in thread\s+"[^"]*"\s+(.*)$/;
|
|
31
|
+
const GO_PANIC = /^panic:\s*(.*)$/;
|
|
32
|
+
/*
|
|
33
|
+
* Leading identifier is optional so a bare "Error: msg" / "Exception: msg"
|
|
34
|
+
* (common in Node.js) matches as well as "TypeError" / "java.lang.IOException".
|
|
35
|
+
*/
|
|
36
|
+
const TYPED_ERROR = /^((?:[A-Za-z_][\w.$]*)?(?:Error|Exception|Warning|Fault))(?::\s*([\s\S]*))?$/;
|
|
37
|
+
const QUALIFIED_TYPE = /^([A-Za-z_][\w.$]*\.[A-Za-z_][\w.$]*):\s*(.*)$/;
|
|
38
|
+
export default class LogExceptionExtractor {
|
|
39
|
+
/**
|
|
40
|
+
* Detect an exception in a single log record. Returns null when none is
|
|
41
|
+
* found. Never throws — extraction must never fail log ingest.
|
|
42
|
+
*/
|
|
43
|
+
static extractFromLogRecord(input) {
|
|
44
|
+
try {
|
|
45
|
+
/*
|
|
46
|
+
* Path A — explicit OTel exception.* attributes. Always on, cheapest,
|
|
47
|
+
* highest-signal (the app explicitly recorded an exception on the log).
|
|
48
|
+
*/
|
|
49
|
+
const fromAttributes = LogExceptionExtractor.extractFromAttributes(input.attributes);
|
|
50
|
+
if (fromAttributes) {
|
|
51
|
+
return fromAttributes;
|
|
52
|
+
}
|
|
53
|
+
// Path B — raw body scan. Gated to keep the hot path cheap.
|
|
54
|
+
if (input.severityNumber < MIN_ERROR_SEVERITY_NUMBER) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (input.hasTraceAndSpan) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return LogExceptionExtractor.extractFromBody(input.body);
|
|
61
|
+
}
|
|
62
|
+
catch (_a) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
static extractFromAttributes(attributes) {
|
|
67
|
+
if (!attributes) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const stackTrace = asString(attributes["exception.stacktrace"]);
|
|
71
|
+
const exceptionType = asString(attributes["exception.type"]);
|
|
72
|
+
const message = asString(attributes["exception.message"]);
|
|
73
|
+
if (!stackTrace && !exceptionType && !message) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const clampedStack = clamp(stackTrace, MAX_STORED_STACK_TRACE_LENGTH);
|
|
77
|
+
let parsedFrames = "[]";
|
|
78
|
+
if (clampedStack) {
|
|
79
|
+
try {
|
|
80
|
+
const parsed = StackTraceParser.parse(clampedStack);
|
|
81
|
+
parsedFrames = JSON.stringify(parsed.frames);
|
|
82
|
+
}
|
|
83
|
+
catch (_a) {
|
|
84
|
+
parsedFrames = "[]";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
message: clamp(message, MAX_MESSAGE_LENGTH),
|
|
89
|
+
exceptionType: exceptionType,
|
|
90
|
+
stackTrace: clampedStack,
|
|
91
|
+
parsedFrames: parsedFrames,
|
|
92
|
+
escaped: toNullableBoolean(attributes["exception.escaped"]),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
static extractFromBody(body) {
|
|
96
|
+
if (!body) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const sliced = body.length > MAX_PARSE_BODY_LENGTH
|
|
100
|
+
? body.slice(0, MAX_PARSE_BODY_LENGTH)
|
|
101
|
+
: body;
|
|
102
|
+
if (!LOOKS_LIKE_STACK_TRACE.test(sliced)) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const parsed = StackTraceParser.parse(sliced);
|
|
106
|
+
/*
|
|
107
|
+
* Require at least one parsed frame. A signature match with zero frames is
|
|
108
|
+
* usually prose that merely mentions "...Error:" / "...Exception" — not an
|
|
109
|
+
* actual stack trace. Path A is the path allowed to emit without frames.
|
|
110
|
+
*/
|
|
111
|
+
if (!parsed.frames || parsed.frames.length === 0) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const header = LogExceptionExtractor.parseHeader(sliced);
|
|
115
|
+
return {
|
|
116
|
+
message: clamp(header.message, MAX_MESSAGE_LENGTH),
|
|
117
|
+
exceptionType: header.exceptionType,
|
|
118
|
+
stackTrace: clamp(sliced, MAX_STORED_STACK_TRACE_LENGTH),
|
|
119
|
+
parsedFrames: JSON.stringify(parsed.frames),
|
|
120
|
+
escaped: null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Best-effort derivation of exceptionType + message from a raw stack-trace
|
|
125
|
+
* body. A stable, clean exceptionType improves grouping and exception-monitor
|
|
126
|
+
* targeting, but a miss is harmless — the fingerprint also uses the message
|
|
127
|
+
* and the normalized stack trace.
|
|
128
|
+
*/
|
|
129
|
+
static parseHeader(body) {
|
|
130
|
+
const lines = body
|
|
131
|
+
.split("\n")
|
|
132
|
+
.map((l) => {
|
|
133
|
+
return l.trim();
|
|
134
|
+
})
|
|
135
|
+
.filter((l) => {
|
|
136
|
+
return l.length > 0;
|
|
137
|
+
});
|
|
138
|
+
if (lines.length === 0) {
|
|
139
|
+
return { exceptionType: "", message: "" };
|
|
140
|
+
}
|
|
141
|
+
/*
|
|
142
|
+
* Python: header is "Traceback (most recent call last):"; the "Type: message"
|
|
143
|
+
* line is at the BOTTOM of the traceback, so scan upward for it.
|
|
144
|
+
*/
|
|
145
|
+
if (PYTHON_TRACEBACK_HEADER.test(lines[0])) {
|
|
146
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
147
|
+
const candidate = lines[i].match(TYPED_ERROR);
|
|
148
|
+
if (candidate) {
|
|
149
|
+
return {
|
|
150
|
+
exceptionType: candidate[1] || "",
|
|
151
|
+
message: (candidate[2] || "").trim(),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Truncated traceback with no type line — keep the last line as message.
|
|
156
|
+
return { exceptionType: "", message: lines[lines.length - 1] };
|
|
157
|
+
}
|
|
158
|
+
// Strip Java's "Exception in thread "name"" prefix if present.
|
|
159
|
+
let firstLine = lines[0];
|
|
160
|
+
const threadMatch = firstLine.match(JAVA_THREAD_PREFIX);
|
|
161
|
+
if (threadMatch) {
|
|
162
|
+
firstLine = threadMatch[1].trim();
|
|
163
|
+
}
|
|
164
|
+
const goMatch = firstLine.match(GO_PANIC);
|
|
165
|
+
if (goMatch) {
|
|
166
|
+
return { exceptionType: "panic", message: (goMatch[1] || "").trim() };
|
|
167
|
+
}
|
|
168
|
+
// "TypeError: msg", "java.lang.NullPointerException: msg", "...Exception"
|
|
169
|
+
const typedMatch = firstLine.match(TYPED_ERROR);
|
|
170
|
+
if (typedMatch) {
|
|
171
|
+
return {
|
|
172
|
+
exceptionType: typedMatch[1] || "",
|
|
173
|
+
message: (typedMatch[2] || "").trim(),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// Generic qualified "pkg.Sub.Type: msg"
|
|
177
|
+
const qualifiedMatch = firstLine.match(QUALIFIED_TYPE);
|
|
178
|
+
if (qualifiedMatch) {
|
|
179
|
+
return {
|
|
180
|
+
exceptionType: qualifiedMatch[1] || "",
|
|
181
|
+
message: (qualifiedMatch[2] || "").trim(),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return { exceptionType: "", message: firstLine };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function asString(value) {
|
|
188
|
+
if (typeof value === "string") {
|
|
189
|
+
return value;
|
|
190
|
+
}
|
|
191
|
+
return "";
|
|
192
|
+
}
|
|
193
|
+
function toNullableBoolean(value) {
|
|
194
|
+
if (typeof value === "boolean") {
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
if (typeof value === "string") {
|
|
198
|
+
const normalized = value.trim().toLowerCase();
|
|
199
|
+
if (normalized === "true") {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
if (normalized === "false") {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function clamp(value, max) {
|
|
209
|
+
if (value && value.length > max) {
|
|
210
|
+
return value.slice(0, max);
|
|
211
|
+
}
|
|
212
|
+
return value;
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=LogExceptionExtractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogExceptionExtractor.js","sourceRoot":"","sources":["../../../../../Server/Utils/Telemetry/LogExceptionExtractor.ts"],"names":[],"mappings":"AACA,OAAO,gBAAsC,MAAM,oBAAoB,CAAC;AA+BxE;;;;GAIG;AACH,MAAM,yBAAyB,GAAW,EAAE,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,qBAAqB,GAAW,EAAE,GAAG,IAAI,CAAC;AAEhD;;;GAGG;AACH,MAAM,6BAA6B,GAAW,EAAE,GAAG,IAAI,CAAC;AACxD,MAAM,kBAAkB,GAAW,IAAI,CAAC;AAExC;;;;;GAKG;AACH,MAAM,sBAAsB,GAC1B,oKAAoK,CAAC;AAEvK,uEAAuE;AACvE,MAAM,uBAAuB,GAAW,uCAAuC,CAAC;AAChF,MAAM,kBAAkB,GAAW,wCAAwC,CAAC;AAC5E,MAAM,QAAQ,GAAW,iBAAiB,CAAC;AAC3C;;;GAGG;AACH,MAAM,WAAW,GACf,8EAA8E,CAAC;AACjF,MAAM,cAAc,GAAW,gDAAgD,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACxC;;;OAGG;IACI,MAAM,CAAC,oBAAoB,CAChC,KAAiC;QAEjC,IAAI,CAAC;YACH;;;eAGG;YACH,MAAM,cAAc,GAClB,qBAAqB,CAAC,qBAAqB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAChE,IAAI,cAAc,EAAE,CAAC;gBACnB,OAAO,cAAc,CAAC;YACxB,CAAC;YAED,4DAA4D;YAC5D,IAAI,KAAK,CAAC,cAAc,GAAG,yBAAyB,EAAE,CAAC;gBACrD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,qBAAqB,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAClC,UAAsB;QAEtB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAW,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACxE,MAAM,aAAa,GAAW,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAW,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAElE,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAW,KAAK,CAChC,UAAU,EACV,6BAA6B,CAC9B,CAAC;QAEF,IAAI,YAAY,GAAW,IAAI,CAAC;QAChC,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAqB,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBACtE,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/C,CAAC;YAAC,WAAM,CAAC;gBACP,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC;YAC3C,aAAa,EAAE,aAAa;YAC5B,UAAU,EAAE,YAAY;YACxB,YAAY,EAAE,YAAY;YAC1B,OAAO,EAAE,iBAAiB,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;SAC5D,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,IAAY;QACzC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,GAAG,qBAAqB;YACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC;YACtC,CAAC,CAAC,IAAI,CAAC;QAEX,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAqB,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEhE;;;;WAIG;QACH,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GACV,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE5C,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC;YAClD,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,6BAA6B,CAAC;YACxD,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;YAC3C,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,WAAW,CAAC,IAAY;QAIrC,MAAM,KAAK,GAAkB,IAAI;aAC9B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;YACjB,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE;YACpB,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;QAEL,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC5C,CAAC;QAED;;;WAGG;QACH,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YAC5C,KAAK,IAAI,CAAC,GAAW,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnD,MAAM,SAAS,GAA4B,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBACxE,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO;wBACL,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE;wBACjC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;qBACrC,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,yEAAyE;YACzE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,EAAE,CAAC;QAClE,CAAC;QAED,+DAA+D;QAC/D,IAAI,SAAS,GAAW,KAAK,CAAC,CAAC,CAAE,CAAC;QAClC,MAAM,WAAW,GACf,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,IAAI,WAAW,EAAE,CAAC;YAChB,SAAS,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QACrC,CAAC;QAED,MAAM,OAAO,GAA4B,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnE,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACxE,CAAC;QAED,0EAA0E;QAC1E,MAAM,UAAU,GAA4B,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzE,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE;gBAClC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aACtC,CAAC;QACJ,CAAC;QAED,wCAAwC;QACxC,MAAM,cAAc,GAClB,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAClC,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO;gBACL,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE;gBACtC,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aAC1C,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IACnD,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,KAA4B;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAA4B;IACrD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAW,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,KAAK,CAAC,KAAa,EAAE,GAAW;IACvC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack trace parser that transforms raw stack trace strings into structured frames.
|
|
3
|
+
* Supports JavaScript/Node.js, Python, Java, Go, Ruby, C#/.NET, and PHP stack traces.
|
|
4
|
+
*/
|
|
5
|
+
// Known library/framework path patterns that indicate non-app code
|
|
6
|
+
const LIBRARY_PATTERNS = [
|
|
7
|
+
// Node.js internals
|
|
8
|
+
/^node:/,
|
|
9
|
+
/^internal\//,
|
|
10
|
+
/node_modules\//,
|
|
11
|
+
/^events\.js$/,
|
|
12
|
+
/^timers\.js$/,
|
|
13
|
+
/^util\.js$/,
|
|
14
|
+
/^net\.js$/,
|
|
15
|
+
/^stream\.js$/,
|
|
16
|
+
/^buffer\.js$/,
|
|
17
|
+
// Python
|
|
18
|
+
/\/site-packages\//,
|
|
19
|
+
/\/dist-packages\//,
|
|
20
|
+
/\/lib\/python\d+\.\d+\//,
|
|
21
|
+
/\/usr\/lib\//,
|
|
22
|
+
/\/usr\/local\/lib\//,
|
|
23
|
+
/\/venv\//,
|
|
24
|
+
/\/\.venv\//,
|
|
25
|
+
/\/virtualenv\//,
|
|
26
|
+
// Java
|
|
27
|
+
/^java\./,
|
|
28
|
+
/^javax\./,
|
|
29
|
+
/^sun\./,
|
|
30
|
+
/^com\.sun\./,
|
|
31
|
+
/^org\.springframework\./,
|
|
32
|
+
/^org\.apache\./,
|
|
33
|
+
/^org\.hibernate\./,
|
|
34
|
+
/^org\.eclipse\./,
|
|
35
|
+
/^io\.netty\./,
|
|
36
|
+
/^com\.google\./,
|
|
37
|
+
/^org\.junit\./,
|
|
38
|
+
// Go
|
|
39
|
+
/^runtime\//,
|
|
40
|
+
/^net\/http\//,
|
|
41
|
+
/^testing\//,
|
|
42
|
+
/\/vendor\//,
|
|
43
|
+
/\/pkg\/mod\//,
|
|
44
|
+
// Ruby
|
|
45
|
+
/\/gems\//,
|
|
46
|
+
/\/rubygems\//,
|
|
47
|
+
/\/ruby\/\d+\.\d+\.\d+\//,
|
|
48
|
+
// C#/.NET
|
|
49
|
+
/^System\./,
|
|
50
|
+
/^Microsoft\./,
|
|
51
|
+
/^Newtonsoft\./,
|
|
52
|
+
// PHP
|
|
53
|
+
/\/vendor\//,
|
|
54
|
+
/^phar:\/\//,
|
|
55
|
+
];
|
|
56
|
+
export default class StackTraceParser {
|
|
57
|
+
/**
|
|
58
|
+
* Parse a raw stack trace string into structured frames.
|
|
59
|
+
* Auto-detects the language and applies the appropriate parser.
|
|
60
|
+
*/
|
|
61
|
+
static parse(rawStackTrace) {
|
|
62
|
+
if (!rawStackTrace || rawStackTrace.trim().length === 0) {
|
|
63
|
+
return { frames: [], raw: rawStackTrace || "" };
|
|
64
|
+
}
|
|
65
|
+
const lines = rawStackTrace.split("\n").map((l) => {
|
|
66
|
+
return l.trim();
|
|
67
|
+
});
|
|
68
|
+
// Try each parser and use the one that produces the most frames
|
|
69
|
+
const parsers = [
|
|
70
|
+
StackTraceParser.parseJavaScript,
|
|
71
|
+
StackTraceParser.parsePython,
|
|
72
|
+
StackTraceParser.parseJava,
|
|
73
|
+
StackTraceParser.parseGo,
|
|
74
|
+
StackTraceParser.parseRuby,
|
|
75
|
+
StackTraceParser.parseCSharp,
|
|
76
|
+
StackTraceParser.parsePHP,
|
|
77
|
+
];
|
|
78
|
+
let bestFrames = [];
|
|
79
|
+
for (const parser of parsers) {
|
|
80
|
+
try {
|
|
81
|
+
const frames = parser(lines);
|
|
82
|
+
if (frames.length > bestFrames.length) {
|
|
83
|
+
bestFrames = frames;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (_a) {
|
|
87
|
+
// Skip failing parsers
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
frames: bestFrames,
|
|
92
|
+
raw: rawStackTrace,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Determine if a file path is application code (not library/framework).
|
|
97
|
+
*/
|
|
98
|
+
static isAppCode(filePath) {
|
|
99
|
+
if (!filePath) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
for (const pattern of LIBRARY_PATTERNS) {
|
|
103
|
+
if (pattern.test(filePath)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Parse JavaScript/Node.js stack traces.
|
|
111
|
+
* Format: `at functionName (filePath:line:col)` or `at filePath:line:col`
|
|
112
|
+
*/
|
|
113
|
+
static parseJavaScript(lines) {
|
|
114
|
+
const frames = [];
|
|
115
|
+
// Pattern 1: at functionName (filePath:line:col)
|
|
116
|
+
const patternWithParens = /^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/;
|
|
117
|
+
// Pattern 2: at filePath:line:col
|
|
118
|
+
const patternWithoutParens = /^at\s+(.+?):(\d+):(\d+)$/;
|
|
119
|
+
// Pattern 3: at functionName (filePath:line)
|
|
120
|
+
const patternWithParensNoCol = /^at\s+(.+?)\s+\((.+?):(\d+)\)$/;
|
|
121
|
+
// Pattern 4: at eval (eval at functionName (filePath:line:col))
|
|
122
|
+
const patternEval = /^at\s+eval\s+\(eval\s+at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/;
|
|
123
|
+
for (const line of lines) {
|
|
124
|
+
let match = null;
|
|
125
|
+
match = line.match(patternEval);
|
|
126
|
+
if (match) {
|
|
127
|
+
frames.push({
|
|
128
|
+
functionName: `eval at ${match[1]}`,
|
|
129
|
+
fileName: match[2],
|
|
130
|
+
lineNumber: parseInt(match[3], 10),
|
|
131
|
+
columnNumber: parseInt(match[4], 10),
|
|
132
|
+
inApp: StackTraceParser.isAppCode(match[2]),
|
|
133
|
+
});
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
match = line.match(patternWithParens);
|
|
137
|
+
if (match) {
|
|
138
|
+
frames.push({
|
|
139
|
+
functionName: match[1],
|
|
140
|
+
fileName: match[2],
|
|
141
|
+
lineNumber: parseInt(match[3], 10),
|
|
142
|
+
columnNumber: parseInt(match[4], 10),
|
|
143
|
+
inApp: StackTraceParser.isAppCode(match[2]),
|
|
144
|
+
});
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
match = line.match(patternWithParensNoCol);
|
|
148
|
+
if (match) {
|
|
149
|
+
frames.push({
|
|
150
|
+
functionName: match[1],
|
|
151
|
+
fileName: match[2],
|
|
152
|
+
lineNumber: parseInt(match[3], 10),
|
|
153
|
+
inApp: StackTraceParser.isAppCode(match[2]),
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
match = line.match(patternWithoutParens);
|
|
158
|
+
if (match) {
|
|
159
|
+
frames.push({
|
|
160
|
+
functionName: "<anonymous>",
|
|
161
|
+
fileName: match[1],
|
|
162
|
+
lineNumber: parseInt(match[2], 10),
|
|
163
|
+
columnNumber: parseInt(match[3], 10),
|
|
164
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
165
|
+
});
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return frames;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Parse Python stack traces.
|
|
173
|
+
* Format: `File "path", line N, in function`
|
|
174
|
+
*/
|
|
175
|
+
static parsePython(lines) {
|
|
176
|
+
const frames = [];
|
|
177
|
+
const pattern = /^File\s+"(.+?)",\s+line\s+(\d+)(?:,\s+in\s+(.+))?$/;
|
|
178
|
+
for (const line of lines) {
|
|
179
|
+
const match = line.match(pattern);
|
|
180
|
+
if (match) {
|
|
181
|
+
frames.push({
|
|
182
|
+
functionName: match[3] || "<module>",
|
|
183
|
+
fileName: match[1],
|
|
184
|
+
lineNumber: parseInt(match[2], 10),
|
|
185
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return frames;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Parse Java stack traces.
|
|
193
|
+
* Format: `at package.Class.method(File.java:line)`
|
|
194
|
+
*/
|
|
195
|
+
static parseJava(lines) {
|
|
196
|
+
const frames = [];
|
|
197
|
+
// Pattern: at com.package.Class.method(File.java:123)
|
|
198
|
+
const pattern = /^at\s+([\w.$]+)\(([\w.]+):(\d+)\)$/;
|
|
199
|
+
// Pattern for native methods: at com.package.Class.method(Native Method)
|
|
200
|
+
const patternNative = /^at\s+([\w.$]+)\(Native Method\)$/;
|
|
201
|
+
// Pattern for unknown source: at com.package.Class.method(Unknown Source)
|
|
202
|
+
const patternUnknown = /^at\s+([\w.$]+)\(Unknown Source\)$/;
|
|
203
|
+
for (const line of lines) {
|
|
204
|
+
let match = null;
|
|
205
|
+
match = line.match(pattern);
|
|
206
|
+
if (match) {
|
|
207
|
+
const fullMethod = match[1];
|
|
208
|
+
frames.push({
|
|
209
|
+
functionName: fullMethod,
|
|
210
|
+
fileName: match[2],
|
|
211
|
+
lineNumber: parseInt(match[3], 10),
|
|
212
|
+
inApp: StackTraceParser.isAppCode(fullMethod),
|
|
213
|
+
});
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
match = line.match(patternNative);
|
|
217
|
+
if (match) {
|
|
218
|
+
frames.push({
|
|
219
|
+
functionName: match[1],
|
|
220
|
+
fileName: "Native Method",
|
|
221
|
+
lineNumber: 0,
|
|
222
|
+
inApp: false,
|
|
223
|
+
});
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
match = line.match(patternUnknown);
|
|
227
|
+
if (match) {
|
|
228
|
+
frames.push({
|
|
229
|
+
functionName: match[1],
|
|
230
|
+
fileName: "Unknown Source",
|
|
231
|
+
lineNumber: 0,
|
|
232
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
233
|
+
});
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return frames;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Parse Go stack traces.
|
|
241
|
+
* Format: `package/file.go:line +0xNN` or `goroutine N [reason]:`
|
|
242
|
+
* Go stack traces have pairs of lines:
|
|
243
|
+
* functionName(args)
|
|
244
|
+
* /path/to/file.go:line +0xNN
|
|
245
|
+
*/
|
|
246
|
+
static parseGo(lines) {
|
|
247
|
+
const frames = [];
|
|
248
|
+
const filePattern = /^(.+\.go):(\d+)\s*(?:\+0x[0-9a-f]+)?$/;
|
|
249
|
+
for (let i = 0; i < lines.length; i++) {
|
|
250
|
+
const line = lines[i];
|
|
251
|
+
// Skip goroutine headers
|
|
252
|
+
if (line.startsWith("goroutine ")) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
// Look for file:line pattern
|
|
256
|
+
const match = line.match(filePattern);
|
|
257
|
+
if (match) {
|
|
258
|
+
// The previous line should be the function name
|
|
259
|
+
let functionName = "<unknown>";
|
|
260
|
+
if (i > 0 && lines[i - 1]) {
|
|
261
|
+
// Remove arguments from function name
|
|
262
|
+
const funcLine = lines[i - 1];
|
|
263
|
+
const parenIndex = funcLine.indexOf("(");
|
|
264
|
+
functionName =
|
|
265
|
+
parenIndex > 0 ? funcLine.substring(0, parenIndex) : funcLine;
|
|
266
|
+
}
|
|
267
|
+
frames.push({
|
|
268
|
+
functionName: functionName,
|
|
269
|
+
fileName: match[1],
|
|
270
|
+
lineNumber: parseInt(match[2], 10),
|
|
271
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return frames;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Parse Ruby stack traces.
|
|
279
|
+
* Format: `file:line:in 'method'` or `file:line:in \`method'`
|
|
280
|
+
*/
|
|
281
|
+
static parseRuby(lines) {
|
|
282
|
+
const frames = [];
|
|
283
|
+
const pattern = /^(.+?):(\d+):in\s+[`'](.+?)'$/;
|
|
284
|
+
for (const line of lines) {
|
|
285
|
+
const match = line.match(pattern);
|
|
286
|
+
if (match) {
|
|
287
|
+
frames.push({
|
|
288
|
+
functionName: match[3],
|
|
289
|
+
fileName: match[1],
|
|
290
|
+
lineNumber: parseInt(match[2], 10),
|
|
291
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return frames;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Parse C#/.NET stack traces.
|
|
299
|
+
* Format: `at Namespace.Class.Method(params) in file:line N`
|
|
300
|
+
*/
|
|
301
|
+
static parseCSharp(lines) {
|
|
302
|
+
const frames = [];
|
|
303
|
+
// Pattern: at Namespace.Class.Method(params) in /path/to/file.cs:line 42
|
|
304
|
+
const patternWithFile = /^at\s+(.+?)\s+in\s+(.+?):line\s+(\d+)$/;
|
|
305
|
+
// Pattern: at Namespace.Class.Method(params)
|
|
306
|
+
const patternWithoutFile = /^at\s+([\w.<>+]+\(.*?\))$/;
|
|
307
|
+
for (const line of lines) {
|
|
308
|
+
let match = null;
|
|
309
|
+
match = line.match(patternWithFile);
|
|
310
|
+
if (match) {
|
|
311
|
+
frames.push({
|
|
312
|
+
functionName: match[1],
|
|
313
|
+
fileName: match[2],
|
|
314
|
+
lineNumber: parseInt(match[3], 10),
|
|
315
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
316
|
+
});
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
match = line.match(patternWithoutFile);
|
|
320
|
+
if (match) {
|
|
321
|
+
frames.push({
|
|
322
|
+
functionName: match[1],
|
|
323
|
+
fileName: "",
|
|
324
|
+
lineNumber: 0,
|
|
325
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
326
|
+
});
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return frames;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Parse PHP stack traces.
|
|
334
|
+
* Format: `#N /path/to/file.php(line): Class->method()`
|
|
335
|
+
*/
|
|
336
|
+
static parsePHP(lines) {
|
|
337
|
+
const frames = [];
|
|
338
|
+
// Pattern: #0 /path/to/file.php(42): ClassName->method()
|
|
339
|
+
const pattern = /^#\d+\s+(.+?)\((\d+)\):\s+(.+)$/;
|
|
340
|
+
// Pattern: #0 {main}
|
|
341
|
+
const patternMain = /^#\d+\s+\{main\}$/;
|
|
342
|
+
for (const line of lines) {
|
|
343
|
+
if (patternMain.test(line)) {
|
|
344
|
+
frames.push({
|
|
345
|
+
functionName: "{main}",
|
|
346
|
+
fileName: "",
|
|
347
|
+
lineNumber: 0,
|
|
348
|
+
inApp: true,
|
|
349
|
+
});
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const match = line.match(pattern);
|
|
353
|
+
if (match) {
|
|
354
|
+
frames.push({
|
|
355
|
+
functionName: match[3].replace(/\(\)$/, ""),
|
|
356
|
+
fileName: match[1],
|
|
357
|
+
lineNumber: parseInt(match[2], 10),
|
|
358
|
+
inApp: StackTraceParser.isAppCode(match[1]),
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return frames;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=StackTraceParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StackTraceParser.js","sourceRoot":"","sources":["../../../../../Server/Utils/Telemetry/StackTraceParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semanti
|
|
|
14
14
|
import URL from "../../Types/API/URL";
|
|
15
15
|
import { AppVersion, Env, DisableTelemetry } from "../EnvironmentConfig";
|
|
16
16
|
import logger from "./Logger";
|
|
17
|
+
import GracefulShutdown, { ShutdownPriority } from "./GracefulShutdown";
|
|
17
18
|
import ContextSpanProcessor from "./Telemetry/ContextSpanProcessor";
|
|
18
19
|
import RuntimeMetrics from "./Telemetry/RuntimeMetrics";
|
|
19
20
|
export var SpanStatusCode;
|
|
@@ -160,10 +161,15 @@ class Telemetry {
|
|
|
160
161
|
const sdk = new opentelemetry.NodeSDK(nodeSdkConfiguration);
|
|
161
162
|
this.getMeterProvider();
|
|
162
163
|
this.getMeter();
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
/*
|
|
165
|
+
* Flush traces / metrics / logs last (Telemetry tier) so spans and logs
|
|
166
|
+
* emitted by the rest of the shutdown still get exported. GracefulShutdown
|
|
167
|
+
* owns process.exit now — this handler must NOT call it itself, or it
|
|
168
|
+
* would race the other tiers and abandon the datastore pools (the exact
|
|
169
|
+
* bug this replaced).
|
|
170
|
+
*/
|
|
171
|
+
GracefulShutdown.registerHandler("Telemetry", ShutdownPriority.Telemetry, () => {
|
|
172
|
+
return sdk.shutdown();
|
|
167
173
|
});
|
|
168
174
|
sdk.start();
|
|
169
175
|
this.sdk = sdk;
|