@lark-apaas/devtool-kits 1.2.12 → 1.2.14-alpha.0
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/error.html +3 -26
- package/dist/index.cjs +360 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +356 -204
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1394,8 +1394,8 @@ function checkForErrors(logs) {
|
|
|
1394
1394
|
return false;
|
|
1395
1395
|
}
|
|
1396
1396
|
__name(checkForErrors, "checkForErrors");
|
|
1397
|
-
function injectTemplateData(template, clientBasePath) {
|
|
1398
|
-
return template.replace("{{.clientBasePath}}", clientBasePath);
|
|
1397
|
+
function injectTemplateData(template, clientBasePath, parentOrigin) {
|
|
1398
|
+
return template.replace("{{.clientBasePath}}", clientBasePath).replace("{{.parentOrigin}}", parentOrigin);
|
|
1399
1399
|
}
|
|
1400
1400
|
__name(injectTemplateData, "injectTemplateData");
|
|
1401
1401
|
function handleDevProxyError(err, req, res, options) {
|
|
@@ -1433,7 +1433,8 @@ function handleDevProxyError(err, req, res, options) {
|
|
|
1433
1433
|
console.log("[Proxy Error]: Compile error or non-connection error, showing error page");
|
|
1434
1434
|
}
|
|
1435
1435
|
const template = getErrorHtmlTemplate();
|
|
1436
|
-
const
|
|
1436
|
+
const parentOrigin = process.env.FORCE_FRAMEWORK_DOMAIN_MAIN || "";
|
|
1437
|
+
const html = injectTemplateData(template, clientBasePathWithoutSlash, parentOrigin);
|
|
1437
1438
|
res.writeHead(200, {
|
|
1438
1439
|
"Content-Type": "text/html; charset=utf-8",
|
|
1439
1440
|
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
@@ -1908,10 +1909,194 @@ function serializeError(error) {
|
|
|
1908
1909
|
__name(serializeError, "serializeError");
|
|
1909
1910
|
|
|
1910
1911
|
// src/middlewares/dev-logs/controller.ts
|
|
1911
|
-
import { join as
|
|
1912
|
+
import { join as join4 } from "path";
|
|
1913
|
+
|
|
1914
|
+
// src/middlewares/dev-logs/services/file-reader.ts
|
|
1915
|
+
import { promises as fs8 } from "fs";
|
|
1916
|
+
async function readFileReverse(filePath, chunkSize, processLine) {
|
|
1917
|
+
const handle = await fs8.open(filePath, "r");
|
|
1918
|
+
try {
|
|
1919
|
+
const stats = await handle.stat();
|
|
1920
|
+
let position = stats.size;
|
|
1921
|
+
let remainder = "";
|
|
1922
|
+
while (position > 0) {
|
|
1923
|
+
const length = Math.min(chunkSize, position);
|
|
1924
|
+
position -= length;
|
|
1925
|
+
const buffer = Buffer.alloc(length);
|
|
1926
|
+
await handle.read(buffer, 0, length, position);
|
|
1927
|
+
let chunk = buffer.toString("utf8");
|
|
1928
|
+
if (remainder) {
|
|
1929
|
+
chunk += remainder;
|
|
1930
|
+
remainder = "";
|
|
1931
|
+
}
|
|
1932
|
+
const lines = chunk.split("\n");
|
|
1933
|
+
remainder = lines.shift() ?? "";
|
|
1934
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
1935
|
+
if (lines[i]) {
|
|
1936
|
+
processLine(lines[i]);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
if (remainder) {
|
|
1941
|
+
processLine(remainder);
|
|
1942
|
+
}
|
|
1943
|
+
} finally {
|
|
1944
|
+
await handle.close();
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
__name(readFileReverse, "readFileReverse");
|
|
1948
|
+
function buildPaginatedResponse(items, page, pageSize) {
|
|
1949
|
+
const totalItems = items.length;
|
|
1950
|
+
const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
|
|
1951
|
+
const startIndex = (page - 1) * pageSize;
|
|
1952
|
+
const endIndex = Math.min(startIndex + pageSize, totalItems);
|
|
1953
|
+
const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
|
|
1954
|
+
traceId: builder.traceId,
|
|
1955
|
+
method: builder.method,
|
|
1956
|
+
path: builder.path,
|
|
1957
|
+
startTime: builder.startTime,
|
|
1958
|
+
endTime: builder.endTime,
|
|
1959
|
+
statusCode: builder.statusCode,
|
|
1960
|
+
durationMs: builder.durationMs,
|
|
1961
|
+
entries: builder.entries.slice().reverse()
|
|
1962
|
+
}));
|
|
1963
|
+
return {
|
|
1964
|
+
page,
|
|
1965
|
+
pageSize,
|
|
1966
|
+
totalCalls: totalItems,
|
|
1967
|
+
totalPages,
|
|
1968
|
+
calls: pagedItems
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
__name(buildPaginatedResponse, "buildPaginatedResponse");
|
|
1912
1972
|
|
|
1913
|
-
// src/middlewares/dev-logs/services.ts
|
|
1914
|
-
|
|
1973
|
+
// src/middlewares/dev-logs/services/parsers.ts
|
|
1974
|
+
function generateUUID() {
|
|
1975
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
1976
|
+
const r = Math.random() * 16 | 0;
|
|
1977
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
1978
|
+
return v.toString(16);
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
__name(generateUUID, "generateUUID");
|
|
1982
|
+
function mapPinoLevelToServerLogLevel(pinoLevel) {
|
|
1983
|
+
if (typeof pinoLevel === "string") {
|
|
1984
|
+
const lower = pinoLevel.toLowerCase();
|
|
1985
|
+
if (lower === "fatal") return "fatal";
|
|
1986
|
+
if (lower === "error") return "error";
|
|
1987
|
+
if (lower === "warn" || lower === "warning") return "warn";
|
|
1988
|
+
if (lower === "info" || lower === "log") return "log";
|
|
1989
|
+
if (lower === "debug") return "debug";
|
|
1990
|
+
if (lower === "trace" || lower === "verbose") return "verbose";
|
|
1991
|
+
return "log";
|
|
1992
|
+
}
|
|
1993
|
+
if (pinoLevel >= 60) return "fatal";
|
|
1994
|
+
if (pinoLevel >= 50) return "error";
|
|
1995
|
+
if (pinoLevel >= 40) return "warn";
|
|
1996
|
+
if (pinoLevel >= 30) return "log";
|
|
1997
|
+
if (pinoLevel >= 20) return "debug";
|
|
1998
|
+
return "verbose";
|
|
1999
|
+
}
|
|
2000
|
+
__name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
|
|
2001
|
+
function extractLogLevel(text) {
|
|
2002
|
+
const lower = text.toLowerCase();
|
|
2003
|
+
if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
|
|
2004
|
+
if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
|
|
2005
|
+
if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
|
|
2006
|
+
if (lower.includes("debug") || lower.includes("<d>")) return "debug";
|
|
2007
|
+
if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
|
|
2008
|
+
return "log";
|
|
2009
|
+
}
|
|
2010
|
+
__name(extractLogLevel, "extractLogLevel");
|
|
2011
|
+
function parsePinoLog(line, source) {
|
|
2012
|
+
try {
|
|
2013
|
+
const pinoLog = JSON.parse(line);
|
|
2014
|
+
const id = generateUUID();
|
|
2015
|
+
return {
|
|
2016
|
+
id,
|
|
2017
|
+
level: mapPinoLevelToServerLogLevel(pinoLog.level),
|
|
2018
|
+
timestamp: new Date(pinoLog.time).getTime(),
|
|
2019
|
+
message: pinoLog.message || pinoLog.msg || "",
|
|
2020
|
+
context: pinoLog.context || null,
|
|
2021
|
+
traceId: pinoLog.trace_id || null,
|
|
2022
|
+
userId: pinoLog.user_id || null,
|
|
2023
|
+
appId: pinoLog.app_id || null,
|
|
2024
|
+
tenantId: pinoLog.tenant_id || null,
|
|
2025
|
+
stack: pinoLog.stack || null,
|
|
2026
|
+
meta: {
|
|
2027
|
+
pid: pinoLog.pid,
|
|
2028
|
+
hostname: pinoLog.hostname,
|
|
2029
|
+
path: pinoLog.path,
|
|
2030
|
+
method: pinoLog.method,
|
|
2031
|
+
statusCode: pinoLog.status_code,
|
|
2032
|
+
durationMs: pinoLog.duration_ms,
|
|
2033
|
+
ip: pinoLog.ip,
|
|
2034
|
+
requestBody: pinoLog.request_body,
|
|
2035
|
+
responseBody: pinoLog.response_body
|
|
2036
|
+
},
|
|
2037
|
+
tags: [
|
|
2038
|
+
source
|
|
2039
|
+
]
|
|
2040
|
+
};
|
|
2041
|
+
} catch (error) {
|
|
2042
|
+
return null;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
__name(parsePinoLog, "parsePinoLog");
|
|
2046
|
+
function parseStdLog(line, source) {
|
|
2047
|
+
const id = generateUUID();
|
|
2048
|
+
const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
|
|
2049
|
+
if (!match) {
|
|
2050
|
+
return {
|
|
2051
|
+
id,
|
|
2052
|
+
level: "log",
|
|
2053
|
+
timestamp: Date.now(),
|
|
2054
|
+
message: line,
|
|
2055
|
+
context: null,
|
|
2056
|
+
traceId: null,
|
|
2057
|
+
userId: null,
|
|
2058
|
+
appId: null,
|
|
2059
|
+
tenantId: null,
|
|
2060
|
+
stack: null,
|
|
2061
|
+
meta: null,
|
|
2062
|
+
tags: [
|
|
2063
|
+
source
|
|
2064
|
+
]
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
const [, timeStr, , content] = match;
|
|
2068
|
+
let timestamp;
|
|
2069
|
+
try {
|
|
2070
|
+
const isoStr = timeStr.replace(" ", "T");
|
|
2071
|
+
timestamp = new Date(isoStr).getTime();
|
|
2072
|
+
if (isNaN(timestamp)) {
|
|
2073
|
+
timestamp = Date.now();
|
|
2074
|
+
}
|
|
2075
|
+
} catch (error) {
|
|
2076
|
+
timestamp = Date.now();
|
|
2077
|
+
}
|
|
2078
|
+
const level = extractLogLevel(content);
|
|
2079
|
+
return {
|
|
2080
|
+
id,
|
|
2081
|
+
level,
|
|
2082
|
+
timestamp,
|
|
2083
|
+
message: content,
|
|
2084
|
+
context: null,
|
|
2085
|
+
traceId: null,
|
|
2086
|
+
userId: null,
|
|
2087
|
+
appId: null,
|
|
2088
|
+
tenantId: null,
|
|
2089
|
+
stack: null,
|
|
2090
|
+
meta: null,
|
|
2091
|
+
tags: [
|
|
2092
|
+
source
|
|
2093
|
+
]
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
__name(parseStdLog, "parseStdLog");
|
|
2097
|
+
|
|
2098
|
+
// src/middlewares/dev-logs/services/trace.service.ts
|
|
2099
|
+
import { createReadStream } from "fs";
|
|
1915
2100
|
import { createInterface } from "readline";
|
|
1916
2101
|
async function readLogEntriesByTrace(filePath, traceId, limit) {
|
|
1917
2102
|
const exists = await fileExists(filePath);
|
|
@@ -2010,62 +2195,6 @@ async function readRecentTraceCalls(filePath, page, pageSize, pathFilter, method
|
|
|
2010
2195
|
return buildPaginatedResponse(completedCalls, page, pageSize);
|
|
2011
2196
|
}
|
|
2012
2197
|
__name(readRecentTraceCalls, "readRecentTraceCalls");
|
|
2013
|
-
async function readFileReverse(filePath, chunkSize, processLine) {
|
|
2014
|
-
const handle = await fs8.open(filePath, "r");
|
|
2015
|
-
try {
|
|
2016
|
-
const stats = await handle.stat();
|
|
2017
|
-
let position = stats.size;
|
|
2018
|
-
let remainder = "";
|
|
2019
|
-
while (position > 0) {
|
|
2020
|
-
const length = Math.min(chunkSize, position);
|
|
2021
|
-
position -= length;
|
|
2022
|
-
const buffer = Buffer.alloc(length);
|
|
2023
|
-
await handle.read(buffer, 0, length, position);
|
|
2024
|
-
let chunk = buffer.toString("utf8");
|
|
2025
|
-
if (remainder) {
|
|
2026
|
-
chunk += remainder;
|
|
2027
|
-
remainder = "";
|
|
2028
|
-
}
|
|
2029
|
-
const lines = chunk.split("\n");
|
|
2030
|
-
remainder = lines.shift() ?? "";
|
|
2031
|
-
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
2032
|
-
if (lines[i]) {
|
|
2033
|
-
processLine(lines[i]);
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
}
|
|
2037
|
-
if (remainder) {
|
|
2038
|
-
processLine(remainder);
|
|
2039
|
-
}
|
|
2040
|
-
} finally {
|
|
2041
|
-
await handle.close();
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
__name(readFileReverse, "readFileReverse");
|
|
2045
|
-
function buildPaginatedResponse(items, page, pageSize) {
|
|
2046
|
-
const totalItems = items.length;
|
|
2047
|
-
const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
|
|
2048
|
-
const startIndex = (page - 1) * pageSize;
|
|
2049
|
-
const endIndex = Math.min(startIndex + pageSize, totalItems);
|
|
2050
|
-
const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
|
|
2051
|
-
traceId: builder.traceId,
|
|
2052
|
-
method: builder.method,
|
|
2053
|
-
path: builder.path,
|
|
2054
|
-
startTime: builder.startTime,
|
|
2055
|
-
endTime: builder.endTime,
|
|
2056
|
-
statusCode: builder.statusCode,
|
|
2057
|
-
durationMs: builder.durationMs,
|
|
2058
|
-
entries: builder.entries.slice().reverse()
|
|
2059
|
-
}));
|
|
2060
|
-
return {
|
|
2061
|
-
page,
|
|
2062
|
-
pageSize,
|
|
2063
|
-
totalCalls: totalItems,
|
|
2064
|
-
totalPages,
|
|
2065
|
-
calls: pagedItems
|
|
2066
|
-
};
|
|
2067
|
-
}
|
|
2068
|
-
__name(buildPaginatedResponse, "buildPaginatedResponse");
|
|
2069
2198
|
async function readLogFilePage(filePath, page, pageSize) {
|
|
2070
2199
|
if (!await fileExists(filePath)) {
|
|
2071
2200
|
return void 0;
|
|
@@ -2121,6 +2250,11 @@ async function readLogFilePage(filePath, page, pageSize) {
|
|
|
2121
2250
|
};
|
|
2122
2251
|
}
|
|
2123
2252
|
__name(readLogFilePage, "readLogFilePage");
|
|
2253
|
+
|
|
2254
|
+
// src/middlewares/dev-logs/services/server-log.service.ts
|
|
2255
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
2256
|
+
import { createInterface as createInterface2 } from "readline";
|
|
2257
|
+
import { join as join3 } from "path";
|
|
2124
2258
|
async function readServerLogs(logDir, options = {}) {
|
|
2125
2259
|
const limit = options.limit || 100;
|
|
2126
2260
|
const offset = options.offset || 0;
|
|
@@ -2163,20 +2297,19 @@ async function readServerLogs(logDir, options = {}) {
|
|
|
2163
2297
|
}
|
|
2164
2298
|
__name(readServerLogs, "readServerLogs");
|
|
2165
2299
|
async function readLogsBySource(logDir, source) {
|
|
2166
|
-
const { join: join7 } = await import("path");
|
|
2167
2300
|
let filePath;
|
|
2168
2301
|
let parser;
|
|
2169
2302
|
if (source === "server") {
|
|
2170
|
-
filePath =
|
|
2303
|
+
filePath = join3(logDir, "server.log");
|
|
2171
2304
|
parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
|
|
2172
2305
|
} else if (source === "trace") {
|
|
2173
|
-
filePath =
|
|
2306
|
+
filePath = join3(logDir, "trace.log");
|
|
2174
2307
|
parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
|
|
2175
2308
|
} else if (source === "server-std") {
|
|
2176
|
-
filePath =
|
|
2309
|
+
filePath = join3(logDir, "server.std.log");
|
|
2177
2310
|
parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
|
|
2178
2311
|
} else if (source === "client-std") {
|
|
2179
|
-
filePath =
|
|
2312
|
+
filePath = join3(logDir, "client.std.log");
|
|
2180
2313
|
parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
|
|
2181
2314
|
} else {
|
|
2182
2315
|
console.warn(`[readLogsBySource] Unknown source: ${source}`);
|
|
@@ -2190,10 +2323,10 @@ async function readLogsBySource(logDir, source) {
|
|
|
2190
2323
|
let stream = null;
|
|
2191
2324
|
let rl = null;
|
|
2192
2325
|
try {
|
|
2193
|
-
stream =
|
|
2326
|
+
stream = createReadStream2(filePath, {
|
|
2194
2327
|
encoding: "utf8"
|
|
2195
2328
|
});
|
|
2196
|
-
rl =
|
|
2329
|
+
rl = createInterface2({
|
|
2197
2330
|
input: stream,
|
|
2198
2331
|
crlfDelay: Infinity
|
|
2199
2332
|
});
|
|
@@ -2221,129 +2354,10 @@ async function readLogsBySource(logDir, source) {
|
|
|
2221
2354
|
return logs;
|
|
2222
2355
|
}
|
|
2223
2356
|
__name(readLogsBySource, "readLogsBySource");
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
return {
|
|
2229
|
-
id,
|
|
2230
|
-
level: mapPinoLevelToServerLogLevel(pinoLog.level),
|
|
2231
|
-
timestamp: new Date(pinoLog.time).getTime(),
|
|
2232
|
-
message: pinoLog.message || pinoLog.msg || "",
|
|
2233
|
-
context: pinoLog.context || null,
|
|
2234
|
-
traceId: pinoLog.trace_id || null,
|
|
2235
|
-
userId: pinoLog.user_id || null,
|
|
2236
|
-
appId: pinoLog.app_id || null,
|
|
2237
|
-
tenantId: pinoLog.tenant_id || null,
|
|
2238
|
-
stack: pinoLog.stack || null,
|
|
2239
|
-
meta: {
|
|
2240
|
-
pid: pinoLog.pid,
|
|
2241
|
-
hostname: pinoLog.hostname,
|
|
2242
|
-
path: pinoLog.path,
|
|
2243
|
-
method: pinoLog.method,
|
|
2244
|
-
statusCode: pinoLog.status_code,
|
|
2245
|
-
durationMs: pinoLog.duration_ms,
|
|
2246
|
-
ip: pinoLog.ip,
|
|
2247
|
-
requestBody: pinoLog.request_body,
|
|
2248
|
-
responseBody: pinoLog.response_body
|
|
2249
|
-
},
|
|
2250
|
-
tags: [
|
|
2251
|
-
source
|
|
2252
|
-
]
|
|
2253
|
-
};
|
|
2254
|
-
} catch (error) {
|
|
2255
|
-
return null;
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
__name(parsePinoLog, "parsePinoLog");
|
|
2259
|
-
function parseStdLog(line, source) {
|
|
2260
|
-
const id = generateUUID();
|
|
2261
|
-
const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
|
|
2262
|
-
if (!match) {
|
|
2263
|
-
return {
|
|
2264
|
-
id,
|
|
2265
|
-
level: "log",
|
|
2266
|
-
timestamp: Date.now(),
|
|
2267
|
-
message: line,
|
|
2268
|
-
context: null,
|
|
2269
|
-
traceId: null,
|
|
2270
|
-
userId: null,
|
|
2271
|
-
appId: null,
|
|
2272
|
-
tenantId: null,
|
|
2273
|
-
stack: null,
|
|
2274
|
-
meta: null,
|
|
2275
|
-
tags: [
|
|
2276
|
-
source
|
|
2277
|
-
]
|
|
2278
|
-
};
|
|
2279
|
-
}
|
|
2280
|
-
const [, timeStr, , content] = match;
|
|
2281
|
-
let timestamp;
|
|
2282
|
-
try {
|
|
2283
|
-
const isoStr = timeStr.replace(" ", "T");
|
|
2284
|
-
timestamp = new Date(isoStr).getTime();
|
|
2285
|
-
if (isNaN(timestamp)) {
|
|
2286
|
-
timestamp = Date.now();
|
|
2287
|
-
}
|
|
2288
|
-
} catch (error) {
|
|
2289
|
-
timestamp = Date.now();
|
|
2290
|
-
}
|
|
2291
|
-
const level = extractLogLevel(content);
|
|
2292
|
-
return {
|
|
2293
|
-
id,
|
|
2294
|
-
level,
|
|
2295
|
-
timestamp,
|
|
2296
|
-
message: content,
|
|
2297
|
-
context: null,
|
|
2298
|
-
traceId: null,
|
|
2299
|
-
userId: null,
|
|
2300
|
-
appId: null,
|
|
2301
|
-
tenantId: null,
|
|
2302
|
-
stack: null,
|
|
2303
|
-
meta: null,
|
|
2304
|
-
tags: [
|
|
2305
|
-
source
|
|
2306
|
-
]
|
|
2307
|
-
};
|
|
2308
|
-
}
|
|
2309
|
-
__name(parseStdLog, "parseStdLog");
|
|
2310
|
-
function mapPinoLevelToServerLogLevel(pinoLevel) {
|
|
2311
|
-
if (typeof pinoLevel === "string") {
|
|
2312
|
-
const lower = pinoLevel.toLowerCase();
|
|
2313
|
-
if (lower === "fatal") return "fatal";
|
|
2314
|
-
if (lower === "error") return "error";
|
|
2315
|
-
if (lower === "warn" || lower === "warning") return "warn";
|
|
2316
|
-
if (lower === "info" || lower === "log") return "log";
|
|
2317
|
-
if (lower === "debug") return "debug";
|
|
2318
|
-
if (lower === "trace" || lower === "verbose") return "verbose";
|
|
2319
|
-
return "log";
|
|
2320
|
-
}
|
|
2321
|
-
if (pinoLevel >= 60) return "fatal";
|
|
2322
|
-
if (pinoLevel >= 50) return "error";
|
|
2323
|
-
if (pinoLevel >= 40) return "warn";
|
|
2324
|
-
if (pinoLevel >= 30) return "log";
|
|
2325
|
-
if (pinoLevel >= 20) return "debug";
|
|
2326
|
-
return "verbose";
|
|
2327
|
-
}
|
|
2328
|
-
__name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
|
|
2329
|
-
function extractLogLevel(text) {
|
|
2330
|
-
const lower = text.toLowerCase();
|
|
2331
|
-
if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
|
|
2332
|
-
if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
|
|
2333
|
-
if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
|
|
2334
|
-
if (lower.includes("debug") || lower.includes("<d>")) return "debug";
|
|
2335
|
-
if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
|
|
2336
|
-
return "log";
|
|
2337
|
-
}
|
|
2338
|
-
__name(extractLogLevel, "extractLogLevel");
|
|
2339
|
-
function generateUUID() {
|
|
2340
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
2341
|
-
const r = Math.random() * 16 | 0;
|
|
2342
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
2343
|
-
return v.toString(16);
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
__name(generateUUID, "generateUUID");
|
|
2357
|
+
|
|
2358
|
+
// src/middlewares/dev-logs/services/trigger.service.ts
|
|
2359
|
+
import { createReadStream as createReadStream3 } from "fs";
|
|
2360
|
+
import { createInterface as createInterface3 } from "readline";
|
|
2347
2361
|
async function readTriggerList(filePath, trigger, path8, limit, triggerID) {
|
|
2348
2362
|
if (!await fileExists(filePath)) {
|
|
2349
2363
|
return void 0;
|
|
@@ -2459,10 +2473,10 @@ async function readTriggerDetail(filePath, path8, instanceID) {
|
|
|
2459
2473
|
return void 0;
|
|
2460
2474
|
}
|
|
2461
2475
|
const matches = [];
|
|
2462
|
-
const stream =
|
|
2476
|
+
const stream = createReadStream3(filePath, {
|
|
2463
2477
|
encoding: "utf8"
|
|
2464
2478
|
});
|
|
2465
|
-
const rl =
|
|
2479
|
+
const rl = createInterface3({
|
|
2466
2480
|
input: stream,
|
|
2467
2481
|
crlfDelay: Infinity
|
|
2468
2482
|
});
|
|
@@ -2483,6 +2497,118 @@ async function readTriggerDetail(filePath, path8, instanceID) {
|
|
|
2483
2497
|
}
|
|
2484
2498
|
__name(readTriggerDetail, "readTriggerDetail");
|
|
2485
2499
|
|
|
2500
|
+
// src/middlewares/dev-logs/services/capability.service.ts
|
|
2501
|
+
async function readCapabilityTraceList(filePath, capabilityId, limit) {
|
|
2502
|
+
if (!await fileExists(filePath)) {
|
|
2503
|
+
return void 0;
|
|
2504
|
+
}
|
|
2505
|
+
const config = {
|
|
2506
|
+
chunkSize: 64 * 1024
|
|
2507
|
+
};
|
|
2508
|
+
const builders = /* @__PURE__ */ new Map();
|
|
2509
|
+
const completedTraces = [];
|
|
2510
|
+
const createCapabilityTraceBuilder = /* @__PURE__ */ __name((traceId, capId) => ({
|
|
2511
|
+
traceId,
|
|
2512
|
+
capabilityId: capId,
|
|
2513
|
+
hasCompleted: false,
|
|
2514
|
+
hasStartEntry: false
|
|
2515
|
+
}), "createCapabilityTraceBuilder");
|
|
2516
|
+
const shouldIncludeInCompletedTraces = /* @__PURE__ */ __name((builder) => {
|
|
2517
|
+
const alreadyAdded = completedTraces.some((trace) => trace.traceId === builder.traceId);
|
|
2518
|
+
if (alreadyAdded) {
|
|
2519
|
+
return false;
|
|
2520
|
+
}
|
|
2521
|
+
return builder.capabilityId === capabilityId;
|
|
2522
|
+
}, "shouldIncludeInCompletedTraces");
|
|
2523
|
+
const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
|
|
2524
|
+
if (entry.plugin_key && !builder.pluginKey) {
|
|
2525
|
+
builder.pluginKey = String(entry.plugin_key);
|
|
2526
|
+
}
|
|
2527
|
+
if (entry.action && !builder.action) {
|
|
2528
|
+
builder.action = String(entry.action);
|
|
2529
|
+
}
|
|
2530
|
+
const message = entry.message || "";
|
|
2531
|
+
if (message.includes("Executing capability") && !builder.hasStartEntry) {
|
|
2532
|
+
builder.hasStartEntry = true;
|
|
2533
|
+
builder.startTime = entry.time;
|
|
2534
|
+
if (entry.input) {
|
|
2535
|
+
builder.input = String(entry.input);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
if (message.includes("executed successfully")) {
|
|
2539
|
+
builder.hasCompleted = true;
|
|
2540
|
+
builder.endTime = entry.time;
|
|
2541
|
+
builder.status = "success";
|
|
2542
|
+
if (entry.output) {
|
|
2543
|
+
builder.output = String(entry.output);
|
|
2544
|
+
}
|
|
2545
|
+
if (entry.duration_ms) {
|
|
2546
|
+
builder.durationMs = Number(entry.duration_ms);
|
|
2547
|
+
}
|
|
2548
|
+
if (shouldIncludeInCompletedTraces(builder)) {
|
|
2549
|
+
completedTraces.push(builder);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
if (message.includes("execution failed")) {
|
|
2553
|
+
builder.hasCompleted = true;
|
|
2554
|
+
builder.endTime = entry.time;
|
|
2555
|
+
builder.status = "failed";
|
|
2556
|
+
if (entry.error) {
|
|
2557
|
+
builder.error = {
|
|
2558
|
+
message: String(entry.error)
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2561
|
+
if (entry.duration_ms) {
|
|
2562
|
+
builder.durationMs = Number(entry.duration_ms);
|
|
2563
|
+
}
|
|
2564
|
+
if (shouldIncludeInCompletedTraces(builder)) {
|
|
2565
|
+
completedTraces.push(builder);
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
}, "updateBuilderMetadata");
|
|
2569
|
+
const processLogEntry = /* @__PURE__ */ __name((entry) => {
|
|
2570
|
+
const { trace_id: traceId, capability_id: capId } = entry;
|
|
2571
|
+
if (!traceId || !capId || capId !== capabilityId) return;
|
|
2572
|
+
let builder = builders.get(traceId);
|
|
2573
|
+
if (!builder) {
|
|
2574
|
+
builder = createCapabilityTraceBuilder(traceId, capId);
|
|
2575
|
+
builders.set(traceId, builder);
|
|
2576
|
+
}
|
|
2577
|
+
updateBuilderMetadata(builder, entry);
|
|
2578
|
+
}, "processLogEntry");
|
|
2579
|
+
const processLine = /* @__PURE__ */ __name((line) => {
|
|
2580
|
+
const entry = parseLogLine2(line);
|
|
2581
|
+
if (entry?.capability_id) {
|
|
2582
|
+
processLogEntry(entry);
|
|
2583
|
+
}
|
|
2584
|
+
}, "processLine");
|
|
2585
|
+
await readFileReverse(filePath, config.chunkSize, processLine);
|
|
2586
|
+
completedTraces.sort((a, b) => {
|
|
2587
|
+
const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;
|
|
2588
|
+
const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;
|
|
2589
|
+
return timeB - timeA;
|
|
2590
|
+
});
|
|
2591
|
+
const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;
|
|
2592
|
+
return {
|
|
2593
|
+
capabilityId,
|
|
2594
|
+
totalTraces: limitedTraces.length,
|
|
2595
|
+
traces: limitedTraces.map((builder) => ({
|
|
2596
|
+
traceId: builder.traceId,
|
|
2597
|
+
capabilityId: builder.capabilityId,
|
|
2598
|
+
pluginKey: builder.pluginKey,
|
|
2599
|
+
action: builder.action,
|
|
2600
|
+
startTime: builder.startTime,
|
|
2601
|
+
endTime: builder.endTime,
|
|
2602
|
+
durationMs: builder.durationMs,
|
|
2603
|
+
status: builder.status || "failed",
|
|
2604
|
+
input: builder.input,
|
|
2605
|
+
output: builder.output,
|
|
2606
|
+
error: builder.error
|
|
2607
|
+
}))
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
__name(readCapabilityTraceList, "readCapabilityTraceList");
|
|
2611
|
+
|
|
2486
2612
|
// src/middlewares/dev-logs/controller.ts
|
|
2487
2613
|
function handleNotFound(res, filePath, message = "Log file not found") {
|
|
2488
2614
|
res.status(404).json({
|
|
@@ -2498,7 +2624,7 @@ function handleError(res, error, message = "Failed to read log file") {
|
|
|
2498
2624
|
}
|
|
2499
2625
|
__name(handleError, "handleError");
|
|
2500
2626
|
function createGetTraceEntriesHandler(logDir) {
|
|
2501
|
-
const appLogPath =
|
|
2627
|
+
const appLogPath = join4(logDir, "server.log");
|
|
2502
2628
|
return async (req, res) => {
|
|
2503
2629
|
const traceId = (req.params.traceId || "").trim();
|
|
2504
2630
|
if (!traceId) {
|
|
@@ -2525,7 +2651,7 @@ function createGetTraceEntriesHandler(logDir) {
|
|
|
2525
2651
|
}
|
|
2526
2652
|
__name(createGetTraceEntriesHandler, "createGetTraceEntriesHandler");
|
|
2527
2653
|
function createGetRecentTracesHandler(logDir) {
|
|
2528
|
-
const traceLogPath =
|
|
2654
|
+
const traceLogPath = join4(logDir, "trace.log");
|
|
2529
2655
|
return async (req, res) => {
|
|
2530
2656
|
const page = parsePositiveInt(req.query.page, 1);
|
|
2531
2657
|
const pageSize = parseLimit(req.query.pageSize, 10, 100);
|
|
@@ -2602,7 +2728,7 @@ function createGetServerLogsHandler(logDir) {
|
|
|
2602
2728
|
}
|
|
2603
2729
|
__name(createGetServerLogsHandler, "createGetServerLogsHandler");
|
|
2604
2730
|
function createGetTriggerListHandler(logDir) {
|
|
2605
|
-
const traceLogPath =
|
|
2731
|
+
const traceLogPath = join4(logDir, "trace.log");
|
|
2606
2732
|
return async (req, res) => {
|
|
2607
2733
|
const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
|
|
2608
2734
|
if (!trigger) {
|
|
@@ -2630,7 +2756,7 @@ function createGetTriggerListHandler(logDir) {
|
|
|
2630
2756
|
}
|
|
2631
2757
|
__name(createGetTriggerListHandler, "createGetTriggerListHandler");
|
|
2632
2758
|
function createGetTriggerDetailHandler(logDir) {
|
|
2633
|
-
const traceLogPath =
|
|
2759
|
+
const traceLogPath = join4(logDir, "server.log");
|
|
2634
2760
|
return async (req, res) => {
|
|
2635
2761
|
const instanceID = (req.params.instanceID || "").trim();
|
|
2636
2762
|
if (!instanceID) {
|
|
@@ -2654,6 +2780,31 @@ function createGetTriggerDetailHandler(logDir) {
|
|
|
2654
2780
|
};
|
|
2655
2781
|
}
|
|
2656
2782
|
__name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
|
|
2783
|
+
function createGetCapabilityTraceListHandler(logDir) {
|
|
2784
|
+
const serverLogPath = join4(logDir, "server.log");
|
|
2785
|
+
return async (req, res) => {
|
|
2786
|
+
const capabilityId = typeof req.query.capability_id === "string" ? req.query.capability_id.trim() : void 0;
|
|
2787
|
+
if (!capabilityId) {
|
|
2788
|
+
return res.status(400).json({
|
|
2789
|
+
message: "capability_id is required"
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
const limit = parseLimit(req.query.limit, 10, 200);
|
|
2793
|
+
try {
|
|
2794
|
+
const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);
|
|
2795
|
+
if (!result) {
|
|
2796
|
+
return handleNotFound(res, serverLogPath);
|
|
2797
|
+
}
|
|
2798
|
+
res.json({
|
|
2799
|
+
file: getRelativePath(serverLogPath),
|
|
2800
|
+
...result
|
|
2801
|
+
});
|
|
2802
|
+
} catch (error) {
|
|
2803
|
+
handleError(res, error, "Failed to read server log");
|
|
2804
|
+
}
|
|
2805
|
+
};
|
|
2806
|
+
}
|
|
2807
|
+
__name(createGetCapabilityTraceListHandler, "createGetCapabilityTraceListHandler");
|
|
2657
2808
|
|
|
2658
2809
|
// src/middlewares/dev-logs/health.controller.ts
|
|
2659
2810
|
import http2 from "http";
|
|
@@ -3248,6 +3399,7 @@ function createDevLogRouter(options = {}) {
|
|
|
3248
3399
|
router.get("/server-logs/stream", createSSEHandler(logDir));
|
|
3249
3400
|
router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
|
|
3250
3401
|
router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
|
|
3402
|
+
router.get("/trace/capability/list", createGetCapabilityTraceListHandler(logDir));
|
|
3251
3403
|
router.get("/health", createHealthCheckHandler());
|
|
3252
3404
|
return router;
|
|
3253
3405
|
}
|
|
@@ -3306,17 +3458,17 @@ __name(createDevLogsMiddleware, "createDevLogsMiddleware");
|
|
|
3306
3458
|
import express3 from "express";
|
|
3307
3459
|
|
|
3308
3460
|
// src/middlewares/collect-logs/controller.ts
|
|
3309
|
-
import { join as
|
|
3461
|
+
import { join as join7 } from "path";
|
|
3310
3462
|
import fs11 from "fs";
|
|
3311
3463
|
|
|
3312
3464
|
// src/middlewares/collect-logs/utils.ts
|
|
3313
|
-
import { isAbsolute as isAbsolute2, join as
|
|
3465
|
+
import { isAbsolute as isAbsolute2, join as join6 } from "path";
|
|
3314
3466
|
import fs10 from "fs";
|
|
3315
3467
|
function resolveLogDir2(provided) {
|
|
3316
3468
|
if (!provided) {
|
|
3317
|
-
return
|
|
3469
|
+
return join6(process.cwd(), "logs");
|
|
3318
3470
|
}
|
|
3319
|
-
return isAbsolute2(provided) ? provided :
|
|
3471
|
+
return isAbsolute2(provided) ? provided : join6(process.cwd(), provided);
|
|
3320
3472
|
}
|
|
3321
3473
|
__name(resolveLogDir2, "resolveLogDir");
|
|
3322
3474
|
function ensureDir(dir) {
|
|
@@ -3339,7 +3491,7 @@ __name(serializeError2, "serializeError");
|
|
|
3339
3491
|
|
|
3340
3492
|
// src/middlewares/collect-logs/controller.ts
|
|
3341
3493
|
function collectLogsHandler(logDir, fileName) {
|
|
3342
|
-
const filePath =
|
|
3494
|
+
const filePath = join7(logDir, fileName);
|
|
3343
3495
|
ensureDir(logDir);
|
|
3344
3496
|
return async (req, res) => {
|
|
3345
3497
|
try {
|
|
@@ -3364,7 +3516,7 @@ function collectLogsHandler(logDir, fileName) {
|
|
|
3364
3516
|
}
|
|
3365
3517
|
__name(collectLogsHandler, "collectLogsHandler");
|
|
3366
3518
|
function collectLogsBatchHandler(logDir, fileName) {
|
|
3367
|
-
const filePath =
|
|
3519
|
+
const filePath = join7(logDir, fileName);
|
|
3368
3520
|
ensureDir(logDir);
|
|
3369
3521
|
return async (req, res) => {
|
|
3370
3522
|
try {
|