@lark-apaas/devtool-kits 1.2.11-alpha.1 → 1.2.12-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/index.cjs +772 -407
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +769 -404
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1465,7 +1465,7 @@ function sendSimpleRedirect(req, res) {
|
|
|
1465
1465
|
__name(sendSimpleRedirect, "sendSimpleRedirect");
|
|
1466
1466
|
|
|
1467
1467
|
// src/middlewares/index.ts
|
|
1468
|
-
import
|
|
1468
|
+
import path7 from "path";
|
|
1469
1469
|
|
|
1470
1470
|
// src/middlewares/openapi/router.ts
|
|
1471
1471
|
import express from "express";
|
|
@@ -1809,8 +1809,8 @@ function hasSpecialPatterns(pattern) {
|
|
|
1809
1809
|
return /[{*]/.test(pattern);
|
|
1810
1810
|
}
|
|
1811
1811
|
__name(hasSpecialPatterns, "hasSpecialPatterns");
|
|
1812
|
-
function normalizePathForMatching(
|
|
1813
|
-
return
|
|
1812
|
+
function normalizePathForMatching(path8) {
|
|
1813
|
+
return path8.replace(/\/+/g, "/").replace(/\/+$/, "");
|
|
1814
1814
|
}
|
|
1815
1815
|
__name(normalizePathForMatching, "normalizePathForMatching");
|
|
1816
1816
|
|
|
@@ -1908,194 +1908,10 @@ function serializeError(error) {
|
|
|
1908
1908
|
__name(serializeError, "serializeError");
|
|
1909
1909
|
|
|
1910
1910
|
// src/middlewares/dev-logs/controller.ts
|
|
1911
|
-
import { join as
|
|
1912
|
-
|
|
1913
|
-
// src/middlewares/dev-logs/services/file-reader.ts
|
|
1914
|
-
import { promises as fs8 } from "fs";
|
|
1915
|
-
async function readFileReverse(filePath, chunkSize, processLine) {
|
|
1916
|
-
const handle = await fs8.open(filePath, "r");
|
|
1917
|
-
try {
|
|
1918
|
-
const stats = await handle.stat();
|
|
1919
|
-
let position = stats.size;
|
|
1920
|
-
let remainder = "";
|
|
1921
|
-
while (position > 0) {
|
|
1922
|
-
const length = Math.min(chunkSize, position);
|
|
1923
|
-
position -= length;
|
|
1924
|
-
const buffer = Buffer.alloc(length);
|
|
1925
|
-
await handle.read(buffer, 0, length, position);
|
|
1926
|
-
let chunk = buffer.toString("utf8");
|
|
1927
|
-
if (remainder) {
|
|
1928
|
-
chunk += remainder;
|
|
1929
|
-
remainder = "";
|
|
1930
|
-
}
|
|
1931
|
-
const lines = chunk.split("\n");
|
|
1932
|
-
remainder = lines.shift() ?? "";
|
|
1933
|
-
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
1934
|
-
if (lines[i]) {
|
|
1935
|
-
processLine(lines[i]);
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
}
|
|
1939
|
-
if (remainder) {
|
|
1940
|
-
processLine(remainder);
|
|
1941
|
-
}
|
|
1942
|
-
} finally {
|
|
1943
|
-
await handle.close();
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
__name(readFileReverse, "readFileReverse");
|
|
1947
|
-
function buildPaginatedResponse(items, page, pageSize) {
|
|
1948
|
-
const totalItems = items.length;
|
|
1949
|
-
const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
|
|
1950
|
-
const startIndex = (page - 1) * pageSize;
|
|
1951
|
-
const endIndex = Math.min(startIndex + pageSize, totalItems);
|
|
1952
|
-
const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
|
|
1953
|
-
traceId: builder.traceId,
|
|
1954
|
-
method: builder.method,
|
|
1955
|
-
path: builder.path,
|
|
1956
|
-
startTime: builder.startTime,
|
|
1957
|
-
endTime: builder.endTime,
|
|
1958
|
-
statusCode: builder.statusCode,
|
|
1959
|
-
durationMs: builder.durationMs,
|
|
1960
|
-
entries: builder.entries.slice().reverse()
|
|
1961
|
-
}));
|
|
1962
|
-
return {
|
|
1963
|
-
page,
|
|
1964
|
-
pageSize,
|
|
1965
|
-
totalCalls: totalItems,
|
|
1966
|
-
totalPages,
|
|
1967
|
-
calls: pagedItems
|
|
1968
|
-
};
|
|
1969
|
-
}
|
|
1970
|
-
__name(buildPaginatedResponse, "buildPaginatedResponse");
|
|
1971
|
-
|
|
1972
|
-
// src/middlewares/dev-logs/services/parsers.ts
|
|
1973
|
-
function generateUUID() {
|
|
1974
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
1975
|
-
const r = Math.random() * 16 | 0;
|
|
1976
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
1977
|
-
return v.toString(16);
|
|
1978
|
-
});
|
|
1979
|
-
}
|
|
1980
|
-
__name(generateUUID, "generateUUID");
|
|
1981
|
-
function mapPinoLevelToServerLogLevel(pinoLevel) {
|
|
1982
|
-
if (typeof pinoLevel === "string") {
|
|
1983
|
-
const lower = pinoLevel.toLowerCase();
|
|
1984
|
-
if (lower === "fatal") return "fatal";
|
|
1985
|
-
if (lower === "error") return "error";
|
|
1986
|
-
if (lower === "warn" || lower === "warning") return "warn";
|
|
1987
|
-
if (lower === "info" || lower === "log") return "log";
|
|
1988
|
-
if (lower === "debug") return "debug";
|
|
1989
|
-
if (lower === "trace" || lower === "verbose") return "verbose";
|
|
1990
|
-
return "log";
|
|
1991
|
-
}
|
|
1992
|
-
if (pinoLevel >= 60) return "fatal";
|
|
1993
|
-
if (pinoLevel >= 50) return "error";
|
|
1994
|
-
if (pinoLevel >= 40) return "warn";
|
|
1995
|
-
if (pinoLevel >= 30) return "log";
|
|
1996
|
-
if (pinoLevel >= 20) return "debug";
|
|
1997
|
-
return "verbose";
|
|
1998
|
-
}
|
|
1999
|
-
__name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
|
|
2000
|
-
function extractLogLevel(text) {
|
|
2001
|
-
const lower = text.toLowerCase();
|
|
2002
|
-
if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
|
|
2003
|
-
if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
|
|
2004
|
-
if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
|
|
2005
|
-
if (lower.includes("debug") || lower.includes("<d>")) return "debug";
|
|
2006
|
-
if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
|
|
2007
|
-
return "log";
|
|
2008
|
-
}
|
|
2009
|
-
__name(extractLogLevel, "extractLogLevel");
|
|
2010
|
-
function parsePinoLog(line, source) {
|
|
2011
|
-
try {
|
|
2012
|
-
const pinoLog = JSON.parse(line);
|
|
2013
|
-
const id = generateUUID();
|
|
2014
|
-
return {
|
|
2015
|
-
id,
|
|
2016
|
-
level: mapPinoLevelToServerLogLevel(pinoLog.level),
|
|
2017
|
-
timestamp: new Date(pinoLog.time).getTime(),
|
|
2018
|
-
message: pinoLog.message || pinoLog.msg || "",
|
|
2019
|
-
context: pinoLog.context || null,
|
|
2020
|
-
traceId: pinoLog.trace_id || null,
|
|
2021
|
-
userId: pinoLog.user_id || null,
|
|
2022
|
-
appId: pinoLog.app_id || null,
|
|
2023
|
-
tenantId: pinoLog.tenant_id || null,
|
|
2024
|
-
stack: pinoLog.stack || null,
|
|
2025
|
-
meta: {
|
|
2026
|
-
pid: pinoLog.pid,
|
|
2027
|
-
hostname: pinoLog.hostname,
|
|
2028
|
-
path: pinoLog.path,
|
|
2029
|
-
method: pinoLog.method,
|
|
2030
|
-
statusCode: pinoLog.status_code,
|
|
2031
|
-
durationMs: pinoLog.duration_ms,
|
|
2032
|
-
ip: pinoLog.ip,
|
|
2033
|
-
requestBody: pinoLog.request_body,
|
|
2034
|
-
responseBody: pinoLog.response_body
|
|
2035
|
-
},
|
|
2036
|
-
tags: [
|
|
2037
|
-
source
|
|
2038
|
-
]
|
|
2039
|
-
};
|
|
2040
|
-
} catch (error) {
|
|
2041
|
-
return null;
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
__name(parsePinoLog, "parsePinoLog");
|
|
2045
|
-
function parseStdLog(line, source) {
|
|
2046
|
-
const id = generateUUID();
|
|
2047
|
-
const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
|
|
2048
|
-
if (!match) {
|
|
2049
|
-
return {
|
|
2050
|
-
id,
|
|
2051
|
-
level: "log",
|
|
2052
|
-
timestamp: Date.now(),
|
|
2053
|
-
message: line,
|
|
2054
|
-
context: null,
|
|
2055
|
-
traceId: null,
|
|
2056
|
-
userId: null,
|
|
2057
|
-
appId: null,
|
|
2058
|
-
tenantId: null,
|
|
2059
|
-
stack: null,
|
|
2060
|
-
meta: null,
|
|
2061
|
-
tags: [
|
|
2062
|
-
source
|
|
2063
|
-
]
|
|
2064
|
-
};
|
|
2065
|
-
}
|
|
2066
|
-
const [, timeStr, , content] = match;
|
|
2067
|
-
let timestamp;
|
|
2068
|
-
try {
|
|
2069
|
-
const isoStr = timeStr.replace(" ", "T");
|
|
2070
|
-
timestamp = new Date(isoStr).getTime();
|
|
2071
|
-
if (isNaN(timestamp)) {
|
|
2072
|
-
timestamp = Date.now();
|
|
2073
|
-
}
|
|
2074
|
-
} catch (error) {
|
|
2075
|
-
timestamp = Date.now();
|
|
2076
|
-
}
|
|
2077
|
-
const level = extractLogLevel(content);
|
|
2078
|
-
return {
|
|
2079
|
-
id,
|
|
2080
|
-
level,
|
|
2081
|
-
timestamp,
|
|
2082
|
-
message: content,
|
|
2083
|
-
context: null,
|
|
2084
|
-
traceId: null,
|
|
2085
|
-
userId: null,
|
|
2086
|
-
appId: null,
|
|
2087
|
-
tenantId: null,
|
|
2088
|
-
stack: null,
|
|
2089
|
-
meta: null,
|
|
2090
|
-
tags: [
|
|
2091
|
-
source
|
|
2092
|
-
]
|
|
2093
|
-
};
|
|
2094
|
-
}
|
|
2095
|
-
__name(parseStdLog, "parseStdLog");
|
|
1911
|
+
import { join as join3 } from "path";
|
|
2096
1912
|
|
|
2097
|
-
// src/middlewares/dev-logs/services
|
|
2098
|
-
import { createReadStream } from "fs";
|
|
1913
|
+
// src/middlewares/dev-logs/services.ts
|
|
1914
|
+
import { createReadStream, promises as fs8 } from "fs";
|
|
2099
1915
|
import { createInterface } from "readline";
|
|
2100
1916
|
async function readLogEntriesByTrace(filePath, traceId, limit) {
|
|
2101
1917
|
const exists = await fileExists(filePath);
|
|
@@ -2194,6 +2010,62 @@ async function readRecentTraceCalls(filePath, page, pageSize, pathFilter, method
|
|
|
2194
2010
|
return buildPaginatedResponse(completedCalls, page, pageSize);
|
|
2195
2011
|
}
|
|
2196
2012
|
__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");
|
|
2197
2069
|
async function readLogFilePage(filePath, page, pageSize) {
|
|
2198
2070
|
if (!await fileExists(filePath)) {
|
|
2199
2071
|
return void 0;
|
|
@@ -2249,11 +2121,6 @@ async function readLogFilePage(filePath, page, pageSize) {
|
|
|
2249
2121
|
};
|
|
2250
2122
|
}
|
|
2251
2123
|
__name(readLogFilePage, "readLogFilePage");
|
|
2252
|
-
|
|
2253
|
-
// src/middlewares/dev-logs/services/server-log.service.ts
|
|
2254
|
-
import { createReadStream as createReadStream2 } from "fs";
|
|
2255
|
-
import { createInterface as createInterface2 } from "readline";
|
|
2256
|
-
import { join as join3 } from "path";
|
|
2257
2124
|
async function readServerLogs(logDir, options = {}) {
|
|
2258
2125
|
const limit = options.limit || 100;
|
|
2259
2126
|
const offset = options.offset || 0;
|
|
@@ -2296,19 +2163,20 @@ async function readServerLogs(logDir, options = {}) {
|
|
|
2296
2163
|
}
|
|
2297
2164
|
__name(readServerLogs, "readServerLogs");
|
|
2298
2165
|
async function readLogsBySource(logDir, source) {
|
|
2166
|
+
const { join: join7 } = await import("path");
|
|
2299
2167
|
let filePath;
|
|
2300
2168
|
let parser;
|
|
2301
2169
|
if (source === "server") {
|
|
2302
|
-
filePath =
|
|
2170
|
+
filePath = join7(logDir, "server.log");
|
|
2303
2171
|
parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
|
|
2304
2172
|
} else if (source === "trace") {
|
|
2305
|
-
filePath =
|
|
2173
|
+
filePath = join7(logDir, "trace.log");
|
|
2306
2174
|
parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
|
|
2307
2175
|
} else if (source === "server-std") {
|
|
2308
|
-
filePath =
|
|
2176
|
+
filePath = join7(logDir, "server.std.log");
|
|
2309
2177
|
parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
|
|
2310
2178
|
} else if (source === "client-std") {
|
|
2311
|
-
filePath =
|
|
2179
|
+
filePath = join7(logDir, "client.std.log");
|
|
2312
2180
|
parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
|
|
2313
2181
|
} else {
|
|
2314
2182
|
console.warn(`[readLogsBySource] Unknown source: ${source}`);
|
|
@@ -2322,10 +2190,10 @@ async function readLogsBySource(logDir, source) {
|
|
|
2322
2190
|
let stream = null;
|
|
2323
2191
|
let rl = null;
|
|
2324
2192
|
try {
|
|
2325
|
-
stream =
|
|
2193
|
+
stream = createReadStream(filePath, {
|
|
2326
2194
|
encoding: "utf8"
|
|
2327
2195
|
});
|
|
2328
|
-
rl =
|
|
2196
|
+
rl = createInterface({
|
|
2329
2197
|
input: stream,
|
|
2330
2198
|
crlfDelay: Infinity
|
|
2331
2199
|
});
|
|
@@ -2353,11 +2221,130 @@ async function readLogsBySource(logDir, source) {
|
|
|
2353
2221
|
return logs;
|
|
2354
2222
|
}
|
|
2355
2223
|
__name(readLogsBySource, "readLogsBySource");
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2224
|
+
function parsePinoLog(line, source) {
|
|
2225
|
+
try {
|
|
2226
|
+
const pinoLog = JSON.parse(line);
|
|
2227
|
+
const id = generateUUID();
|
|
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");
|
|
2347
|
+
async function readTriggerList(filePath, trigger, path8, limit, triggerID) {
|
|
2361
2348
|
if (!await fileExists(filePath)) {
|
|
2362
2349
|
return void 0;
|
|
2363
2350
|
}
|
|
@@ -2383,7 +2370,7 @@ async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
|
|
|
2383
2370
|
if (alreadyAdded) {
|
|
2384
2371
|
return false;
|
|
2385
2372
|
}
|
|
2386
|
-
const isAutomationTrigger = builder.path?.endsWith(
|
|
2373
|
+
const isAutomationTrigger = builder.path?.endsWith(path8);
|
|
2387
2374
|
if (!isAutomationTrigger) {
|
|
2388
2375
|
return false;
|
|
2389
2376
|
}
|
|
@@ -2437,176 +2424,64 @@ async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
|
|
|
2437
2424
|
if (!builder.hasCompleted && (message.includes("HTTP request completed") || message.includes("HTTP request failed"))) {
|
|
2438
2425
|
handleRequestCompleted(builder, entry, message);
|
|
2439
2426
|
}
|
|
2440
|
-
if (message.includes("HTTP request started") && !builder.startTime) {
|
|
2441
|
-
builder.startTime = entry.time;
|
|
2442
|
-
}
|
|
2443
|
-
}, "processLogEntry");
|
|
2444
|
-
const processLine = /* @__PURE__ */ __name((line) => {
|
|
2445
|
-
const entry = parseLogLine2(line);
|
|
2446
|
-
if (entry?.trace_id) {
|
|
2447
|
-
processLogEntry(entry);
|
|
2448
|
-
}
|
|
2449
|
-
}, "processLine");
|
|
2450
|
-
await readFileReverse(filePath, config.chunkSize, processLine);
|
|
2451
|
-
return {
|
|
2452
|
-
page: 1,
|
|
2453
|
-
pageSize: completedCalls.length,
|
|
2454
|
-
totalCalls: completedCalls.length,
|
|
2455
|
-
totalPages: 1,
|
|
2456
|
-
calls: completedCalls.map((builder) => ({
|
|
2457
|
-
traceId: builder.traceId,
|
|
2458
|
-
method: builder.method,
|
|
2459
|
-
path: builder.path,
|
|
2460
|
-
startTime: builder.startTime,
|
|
2461
|
-
endTime: builder.endTime,
|
|
2462
|
-
statusCode: builder.statusCode,
|
|
2463
|
-
durationMs: builder.durationMs,
|
|
2464
|
-
entries: builder.entries.slice().reverse()
|
|
2465
|
-
}))
|
|
2466
|
-
};
|
|
2467
|
-
}
|
|
2468
|
-
__name(readTriggerList, "readTriggerList");
|
|
2469
|
-
async function readTriggerDetail(filePath, path7, instanceID) {
|
|
2470
|
-
const exists = await fileExists(filePath);
|
|
2471
|
-
if (!exists) {
|
|
2472
|
-
return void 0;
|
|
2473
|
-
}
|
|
2474
|
-
const matches = [];
|
|
2475
|
-
const stream = createReadStream3(filePath, {
|
|
2476
|
-
encoding: "utf8"
|
|
2477
|
-
});
|
|
2478
|
-
const rl = createInterface3({
|
|
2479
|
-
input: stream,
|
|
2480
|
-
crlfDelay: Infinity
|
|
2481
|
-
});
|
|
2482
|
-
for await (const line of rl) {
|
|
2483
|
-
const entry = parseLogLine2(line);
|
|
2484
|
-
if (!entry) continue;
|
|
2485
|
-
const isAutomationTrigger = entry.path?.endsWith(path7);
|
|
2486
|
-
const hasInstanceID = entry.instance_id === instanceID && entry.trigger;
|
|
2487
|
-
if (!isAutomationTrigger || !hasInstanceID) continue;
|
|
2488
|
-
matches.push(entry);
|
|
2489
|
-
}
|
|
2490
|
-
rl.close();
|
|
2491
|
-
stream.close();
|
|
2492
|
-
return {
|
|
2493
|
-
instanceID,
|
|
2494
|
-
entries: matches
|
|
2495
|
-
};
|
|
2496
|
-
}
|
|
2497
|
-
__name(readTriggerDetail, "readTriggerDetail");
|
|
2498
|
-
|
|
2499
|
-
// src/middlewares/dev-logs/services/capability.service.ts
|
|
2500
|
-
async function readCapabilityTraceList(filePath, capabilityId, limit) {
|
|
2501
|
-
if (!await fileExists(filePath)) {
|
|
2502
|
-
return void 0;
|
|
2503
|
-
}
|
|
2504
|
-
const config = {
|
|
2505
|
-
chunkSize: 64 * 1024
|
|
2506
|
-
};
|
|
2507
|
-
const builders = /* @__PURE__ */ new Map();
|
|
2508
|
-
const completedTraces = [];
|
|
2509
|
-
const createCapabilityTraceBuilder = /* @__PURE__ */ __name((traceId, capId) => ({
|
|
2510
|
-
traceId,
|
|
2511
|
-
capabilityId: capId,
|
|
2512
|
-
hasCompleted: false,
|
|
2513
|
-
hasStartEntry: false
|
|
2514
|
-
}), "createCapabilityTraceBuilder");
|
|
2515
|
-
const shouldIncludeInCompletedTraces = /* @__PURE__ */ __name((builder) => {
|
|
2516
|
-
const alreadyAdded = completedTraces.some((trace) => trace.traceId === builder.traceId);
|
|
2517
|
-
if (alreadyAdded) {
|
|
2518
|
-
return false;
|
|
2519
|
-
}
|
|
2520
|
-
return builder.capabilityId === capabilityId;
|
|
2521
|
-
}, "shouldIncludeInCompletedTraces");
|
|
2522
|
-
const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
|
|
2523
|
-
if (entry.plugin_key && !builder.pluginKey) {
|
|
2524
|
-
builder.pluginKey = String(entry.plugin_key);
|
|
2525
|
-
}
|
|
2526
|
-
if (entry.action && !builder.action) {
|
|
2527
|
-
builder.action = String(entry.action);
|
|
2528
|
-
}
|
|
2529
|
-
const message = entry.message || "";
|
|
2530
|
-
if (message.includes("Executing capability") && !builder.hasStartEntry) {
|
|
2531
|
-
builder.hasStartEntry = true;
|
|
2532
|
-
builder.startTime = entry.time;
|
|
2533
|
-
if (entry.input) {
|
|
2534
|
-
builder.input = String(entry.input);
|
|
2535
|
-
}
|
|
2536
|
-
}
|
|
2537
|
-
if (message.includes("executed successfully")) {
|
|
2538
|
-
builder.hasCompleted = true;
|
|
2539
|
-
builder.endTime = entry.time;
|
|
2540
|
-
builder.status = "success";
|
|
2541
|
-
if (entry.output) {
|
|
2542
|
-
builder.output = String(entry.output);
|
|
2543
|
-
}
|
|
2544
|
-
if (entry.duration_ms) {
|
|
2545
|
-
builder.durationMs = Number(entry.duration_ms);
|
|
2546
|
-
}
|
|
2547
|
-
if (shouldIncludeInCompletedTraces(builder)) {
|
|
2548
|
-
completedTraces.push(builder);
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
if (message.includes("execution failed")) {
|
|
2552
|
-
builder.hasCompleted = true;
|
|
2553
|
-
builder.endTime = entry.time;
|
|
2554
|
-
builder.status = "failed";
|
|
2555
|
-
if (entry.error) {
|
|
2556
|
-
builder.error = {
|
|
2557
|
-
message: String(entry.error)
|
|
2558
|
-
};
|
|
2559
|
-
}
|
|
2560
|
-
if (entry.duration_ms) {
|
|
2561
|
-
builder.durationMs = Number(entry.duration_ms);
|
|
2562
|
-
}
|
|
2563
|
-
if (shouldIncludeInCompletedTraces(builder)) {
|
|
2564
|
-
completedTraces.push(builder);
|
|
2565
|
-
}
|
|
2566
|
-
}
|
|
2567
|
-
}, "updateBuilderMetadata");
|
|
2568
|
-
const processLogEntry = /* @__PURE__ */ __name((entry) => {
|
|
2569
|
-
const { trace_id: traceId, capability_id: capId } = entry;
|
|
2570
|
-
if (!traceId || !capId || capId !== capabilityId) return;
|
|
2571
|
-
let builder = builders.get(traceId);
|
|
2572
|
-
if (!builder) {
|
|
2573
|
-
builder = createCapabilityTraceBuilder(traceId, capId);
|
|
2574
|
-
builders.set(traceId, builder);
|
|
2427
|
+
if (message.includes("HTTP request started") && !builder.startTime) {
|
|
2428
|
+
builder.startTime = entry.time;
|
|
2575
2429
|
}
|
|
2576
|
-
updateBuilderMetadata(builder, entry);
|
|
2577
2430
|
}, "processLogEntry");
|
|
2578
2431
|
const processLine = /* @__PURE__ */ __name((line) => {
|
|
2579
2432
|
const entry = parseLogLine2(line);
|
|
2580
|
-
if (entry?.
|
|
2433
|
+
if (entry?.trace_id) {
|
|
2581
2434
|
processLogEntry(entry);
|
|
2582
2435
|
}
|
|
2583
2436
|
}, "processLine");
|
|
2584
2437
|
await readFileReverse(filePath, config.chunkSize, processLine);
|
|
2585
|
-
completedTraces.sort((a, b) => {
|
|
2586
|
-
const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;
|
|
2587
|
-
const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;
|
|
2588
|
-
return timeB - timeA;
|
|
2589
|
-
});
|
|
2590
|
-
const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;
|
|
2591
2438
|
return {
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2439
|
+
page: 1,
|
|
2440
|
+
pageSize: completedCalls.length,
|
|
2441
|
+
totalCalls: completedCalls.length,
|
|
2442
|
+
totalPages: 1,
|
|
2443
|
+
calls: completedCalls.map((builder) => ({
|
|
2595
2444
|
traceId: builder.traceId,
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
action: builder.action,
|
|
2445
|
+
method: builder.method,
|
|
2446
|
+
path: builder.path,
|
|
2599
2447
|
startTime: builder.startTime,
|
|
2600
2448
|
endTime: builder.endTime,
|
|
2449
|
+
statusCode: builder.statusCode,
|
|
2601
2450
|
durationMs: builder.durationMs,
|
|
2602
|
-
|
|
2603
|
-
input: builder.input,
|
|
2604
|
-
output: builder.output,
|
|
2605
|
-
error: builder.error
|
|
2451
|
+
entries: builder.entries.slice().reverse()
|
|
2606
2452
|
}))
|
|
2607
2453
|
};
|
|
2608
2454
|
}
|
|
2609
|
-
__name(
|
|
2455
|
+
__name(readTriggerList, "readTriggerList");
|
|
2456
|
+
async function readTriggerDetail(filePath, path8, instanceID) {
|
|
2457
|
+
const exists = await fileExists(filePath);
|
|
2458
|
+
if (!exists) {
|
|
2459
|
+
return void 0;
|
|
2460
|
+
}
|
|
2461
|
+
const matches = [];
|
|
2462
|
+
const stream = createReadStream(filePath, {
|
|
2463
|
+
encoding: "utf8"
|
|
2464
|
+
});
|
|
2465
|
+
const rl = createInterface({
|
|
2466
|
+
input: stream,
|
|
2467
|
+
crlfDelay: Infinity
|
|
2468
|
+
});
|
|
2469
|
+
for await (const line of rl) {
|
|
2470
|
+
const entry = parseLogLine2(line);
|
|
2471
|
+
if (!entry) continue;
|
|
2472
|
+
const isAutomationTrigger = entry.path?.endsWith(path8);
|
|
2473
|
+
const hasInstanceID = entry.instance_id === instanceID && entry.trigger;
|
|
2474
|
+
if (!isAutomationTrigger || !hasInstanceID) continue;
|
|
2475
|
+
matches.push(entry);
|
|
2476
|
+
}
|
|
2477
|
+
rl.close();
|
|
2478
|
+
stream.close();
|
|
2479
|
+
return {
|
|
2480
|
+
instanceID,
|
|
2481
|
+
entries: matches
|
|
2482
|
+
};
|
|
2483
|
+
}
|
|
2484
|
+
__name(readTriggerDetail, "readTriggerDetail");
|
|
2610
2485
|
|
|
2611
2486
|
// src/middlewares/dev-logs/controller.ts
|
|
2612
2487
|
function handleNotFound(res, filePath, message = "Log file not found") {
|
|
@@ -2623,7 +2498,7 @@ function handleError(res, error, message = "Failed to read log file") {
|
|
|
2623
2498
|
}
|
|
2624
2499
|
__name(handleError, "handleError");
|
|
2625
2500
|
function createGetTraceEntriesHandler(logDir) {
|
|
2626
|
-
const appLogPath =
|
|
2501
|
+
const appLogPath = join3(logDir, "server.log");
|
|
2627
2502
|
return async (req, res) => {
|
|
2628
2503
|
const traceId = (req.params.traceId || "").trim();
|
|
2629
2504
|
if (!traceId) {
|
|
@@ -2650,7 +2525,7 @@ function createGetTraceEntriesHandler(logDir) {
|
|
|
2650
2525
|
}
|
|
2651
2526
|
__name(createGetTraceEntriesHandler, "createGetTraceEntriesHandler");
|
|
2652
2527
|
function createGetRecentTracesHandler(logDir) {
|
|
2653
|
-
const traceLogPath =
|
|
2528
|
+
const traceLogPath = join3(logDir, "trace.log");
|
|
2654
2529
|
return async (req, res) => {
|
|
2655
2530
|
const page = parsePositiveInt(req.query.page, 1);
|
|
2656
2531
|
const pageSize = parseLimit(req.query.pageSize, 10, 100);
|
|
@@ -2727,7 +2602,7 @@ function createGetServerLogsHandler(logDir) {
|
|
|
2727
2602
|
}
|
|
2728
2603
|
__name(createGetServerLogsHandler, "createGetServerLogsHandler");
|
|
2729
2604
|
function createGetTriggerListHandler(logDir) {
|
|
2730
|
-
const traceLogPath =
|
|
2605
|
+
const traceLogPath = join3(logDir, "trace.log");
|
|
2731
2606
|
return async (req, res) => {
|
|
2732
2607
|
const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
|
|
2733
2608
|
if (!trigger) {
|
|
@@ -2736,16 +2611,16 @@ function createGetTriggerListHandler(logDir) {
|
|
|
2736
2611
|
});
|
|
2737
2612
|
}
|
|
2738
2613
|
const triggerID = typeof req.query.triggerID === "string" ? req.query.triggerID.trim() : void 0;
|
|
2739
|
-
const
|
|
2614
|
+
const path8 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
|
|
2740
2615
|
const limit = parseLimit(req.query.limit, 10, 200);
|
|
2741
2616
|
try {
|
|
2742
|
-
const result = await readTriggerList(traceLogPath, trigger,
|
|
2617
|
+
const result = await readTriggerList(traceLogPath, trigger, path8, limit, triggerID);
|
|
2743
2618
|
if (!result) {
|
|
2744
2619
|
return handleNotFound(res, traceLogPath);
|
|
2745
2620
|
}
|
|
2746
2621
|
res.json({
|
|
2747
2622
|
file: getRelativePath(traceLogPath),
|
|
2748
|
-
path:
|
|
2623
|
+
path: path8,
|
|
2749
2624
|
...result
|
|
2750
2625
|
});
|
|
2751
2626
|
} catch (error) {
|
|
@@ -2755,7 +2630,7 @@ function createGetTriggerListHandler(logDir) {
|
|
|
2755
2630
|
}
|
|
2756
2631
|
__name(createGetTriggerListHandler, "createGetTriggerListHandler");
|
|
2757
2632
|
function createGetTriggerDetailHandler(logDir) {
|
|
2758
|
-
const traceLogPath =
|
|
2633
|
+
const traceLogPath = join3(logDir, "server.log");
|
|
2759
2634
|
return async (req, res) => {
|
|
2760
2635
|
const instanceID = (req.params.instanceID || "").trim();
|
|
2761
2636
|
if (!instanceID) {
|
|
@@ -2763,9 +2638,9 @@ function createGetTriggerDetailHandler(logDir) {
|
|
|
2763
2638
|
message: "instanceID is required"
|
|
2764
2639
|
});
|
|
2765
2640
|
}
|
|
2766
|
-
const
|
|
2641
|
+
const path8 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
|
|
2767
2642
|
try {
|
|
2768
|
-
const result = await readTriggerDetail(traceLogPath,
|
|
2643
|
+
const result = await readTriggerDetail(traceLogPath, path8, instanceID);
|
|
2769
2644
|
if (!result) {
|
|
2770
2645
|
return handleNotFound(res, traceLogPath);
|
|
2771
2646
|
}
|
|
@@ -2779,31 +2654,6 @@ function createGetTriggerDetailHandler(logDir) {
|
|
|
2779
2654
|
};
|
|
2780
2655
|
}
|
|
2781
2656
|
__name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
|
|
2782
|
-
function createGetCapabilityTraceListHandler(logDir) {
|
|
2783
|
-
const serverLogPath = join4(logDir, "server.log");
|
|
2784
|
-
return async (req, res) => {
|
|
2785
|
-
const capabilityId = typeof req.query.capability_id === "string" ? req.query.capability_id.trim() : void 0;
|
|
2786
|
-
if (!capabilityId) {
|
|
2787
|
-
return res.status(400).json({
|
|
2788
|
-
message: "capability_id is required"
|
|
2789
|
-
});
|
|
2790
|
-
}
|
|
2791
|
-
const limit = parseLimit(req.query.limit, 10, 200);
|
|
2792
|
-
try {
|
|
2793
|
-
const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);
|
|
2794
|
-
if (!result) {
|
|
2795
|
-
return handleNotFound(res, serverLogPath);
|
|
2796
|
-
}
|
|
2797
|
-
res.json({
|
|
2798
|
-
file: getRelativePath(serverLogPath),
|
|
2799
|
-
...result
|
|
2800
|
-
});
|
|
2801
|
-
} catch (error) {
|
|
2802
|
-
handleError(res, error, "Failed to read server log");
|
|
2803
|
-
}
|
|
2804
|
-
};
|
|
2805
|
-
}
|
|
2806
|
-
__name(createGetCapabilityTraceListHandler, "createGetCapabilityTraceListHandler");
|
|
2807
2657
|
|
|
2808
2658
|
// src/middlewares/dev-logs/health.controller.ts
|
|
2809
2659
|
import http2 from "http";
|
|
@@ -2872,6 +2722,521 @@ function createHealthCheckHandler(options = {}) {
|
|
|
2872
2722
|
}
|
|
2873
2723
|
__name(createHealthCheckHandler, "createHealthCheckHandler");
|
|
2874
2724
|
|
|
2725
|
+
// src/middlewares/dev-logs/sse/log-watcher.ts
|
|
2726
|
+
import * as fs9 from "fs";
|
|
2727
|
+
import * as path6 from "path";
|
|
2728
|
+
function mapPinoLevelToServerLogLevel2(pinoLevel) {
|
|
2729
|
+
if (typeof pinoLevel === "string") {
|
|
2730
|
+
const lower = pinoLevel.toLowerCase();
|
|
2731
|
+
if (lower === "fatal") return "fatal";
|
|
2732
|
+
if (lower === "error") return "error";
|
|
2733
|
+
if (lower === "warn" || lower === "warning") return "warn";
|
|
2734
|
+
if (lower === "info" || lower === "log") return "log";
|
|
2735
|
+
if (lower === "debug") return "debug";
|
|
2736
|
+
if (lower === "trace" || lower === "verbose") return "verbose";
|
|
2737
|
+
return "log";
|
|
2738
|
+
}
|
|
2739
|
+
if (pinoLevel >= 60) return "fatal";
|
|
2740
|
+
if (pinoLevel >= 50) return "error";
|
|
2741
|
+
if (pinoLevel >= 40) return "warn";
|
|
2742
|
+
if (pinoLevel >= 30) return "log";
|
|
2743
|
+
if (pinoLevel >= 20) return "debug";
|
|
2744
|
+
return "verbose";
|
|
2745
|
+
}
|
|
2746
|
+
__name(mapPinoLevelToServerLogLevel2, "mapPinoLevelToServerLogLevel");
|
|
2747
|
+
function extractLogLevel2(text) {
|
|
2748
|
+
const lower = text.toLowerCase();
|
|
2749
|
+
if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
|
|
2750
|
+
if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
|
|
2751
|
+
if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
|
|
2752
|
+
if (lower.includes("debug") || lower.includes("<d>")) return "debug";
|
|
2753
|
+
if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
|
|
2754
|
+
return "log";
|
|
2755
|
+
}
|
|
2756
|
+
__name(extractLogLevel2, "extractLogLevel");
|
|
2757
|
+
function generateUUID2() {
|
|
2758
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
2759
|
+
const r = Math.random() * 16 | 0;
|
|
2760
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
2761
|
+
return v.toString(16);
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2764
|
+
__name(generateUUID2, "generateUUID");
|
|
2765
|
+
function parsePinoLog2(line, source) {
|
|
2766
|
+
try {
|
|
2767
|
+
const pinoLog = JSON.parse(line);
|
|
2768
|
+
const id = generateUUID2();
|
|
2769
|
+
return {
|
|
2770
|
+
id,
|
|
2771
|
+
level: mapPinoLevelToServerLogLevel2(pinoLog.level),
|
|
2772
|
+
timestamp: new Date(pinoLog.time).getTime(),
|
|
2773
|
+
message: pinoLog.message || pinoLog.msg || "",
|
|
2774
|
+
context: pinoLog.context || null,
|
|
2775
|
+
traceId: pinoLog.trace_id || null,
|
|
2776
|
+
userId: pinoLog.user_id || null,
|
|
2777
|
+
appId: pinoLog.app_id || null,
|
|
2778
|
+
tenantId: pinoLog.tenant_id || null,
|
|
2779
|
+
stack: pinoLog.stack || null,
|
|
2780
|
+
meta: {
|
|
2781
|
+
pid: pinoLog.pid,
|
|
2782
|
+
hostname: pinoLog.hostname,
|
|
2783
|
+
path: pinoLog.path,
|
|
2784
|
+
method: pinoLog.method,
|
|
2785
|
+
statusCode: pinoLog.status_code,
|
|
2786
|
+
durationMs: pinoLog.duration_ms,
|
|
2787
|
+
ip: pinoLog.ip,
|
|
2788
|
+
requestBody: pinoLog.request_body,
|
|
2789
|
+
responseBody: pinoLog.response_body
|
|
2790
|
+
},
|
|
2791
|
+
tags: [
|
|
2792
|
+
source
|
|
2793
|
+
]
|
|
2794
|
+
};
|
|
2795
|
+
} catch {
|
|
2796
|
+
return null;
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
__name(parsePinoLog2, "parsePinoLog");
|
|
2800
|
+
function parseStdLog2(line, source) {
|
|
2801
|
+
const id = generateUUID2();
|
|
2802
|
+
const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
|
|
2803
|
+
if (!match) {
|
|
2804
|
+
return {
|
|
2805
|
+
id,
|
|
2806
|
+
level: extractLogLevel2(line),
|
|
2807
|
+
timestamp: Date.now(),
|
|
2808
|
+
message: line,
|
|
2809
|
+
context: null,
|
|
2810
|
+
traceId: null,
|
|
2811
|
+
userId: null,
|
|
2812
|
+
appId: null,
|
|
2813
|
+
tenantId: null,
|
|
2814
|
+
stack: null,
|
|
2815
|
+
meta: null,
|
|
2816
|
+
tags: [
|
|
2817
|
+
source
|
|
2818
|
+
]
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
const [, timeStr, , content] = match;
|
|
2822
|
+
let timestamp;
|
|
2823
|
+
try {
|
|
2824
|
+
const isoStr = timeStr.replace(" ", "T");
|
|
2825
|
+
timestamp = new Date(isoStr).getTime();
|
|
2826
|
+
if (isNaN(timestamp)) {
|
|
2827
|
+
timestamp = Date.now();
|
|
2828
|
+
}
|
|
2829
|
+
} catch {
|
|
2830
|
+
timestamp = Date.now();
|
|
2831
|
+
}
|
|
2832
|
+
return {
|
|
2833
|
+
id,
|
|
2834
|
+
level: extractLogLevel2(content),
|
|
2835
|
+
timestamp,
|
|
2836
|
+
message: content,
|
|
2837
|
+
context: null,
|
|
2838
|
+
traceId: null,
|
|
2839
|
+
userId: null,
|
|
2840
|
+
appId: null,
|
|
2841
|
+
tenantId: null,
|
|
2842
|
+
stack: null,
|
|
2843
|
+
meta: null,
|
|
2844
|
+
tags: [
|
|
2845
|
+
source
|
|
2846
|
+
]
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
__name(parseStdLog2, "parseStdLog");
|
|
2850
|
+
var LogWatcher = class {
|
|
2851
|
+
static {
|
|
2852
|
+
__name(this, "LogWatcher");
|
|
2853
|
+
}
|
|
2854
|
+
logDir = "";
|
|
2855
|
+
watchers = /* @__PURE__ */ new Map();
|
|
2856
|
+
filePositions = /* @__PURE__ */ new Map();
|
|
2857
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
2858
|
+
isRunning = false;
|
|
2859
|
+
debug = false;
|
|
2860
|
+
logFiles = [
|
|
2861
|
+
{
|
|
2862
|
+
fileName: "server.log",
|
|
2863
|
+
source: "server",
|
|
2864
|
+
parser: parsePinoLog2
|
|
2865
|
+
},
|
|
2866
|
+
{
|
|
2867
|
+
fileName: "trace.log",
|
|
2868
|
+
source: "trace",
|
|
2869
|
+
parser: parsePinoLog2
|
|
2870
|
+
},
|
|
2871
|
+
{
|
|
2872
|
+
fileName: "server.std.log",
|
|
2873
|
+
source: "server-std",
|
|
2874
|
+
parser: parseStdLog2
|
|
2875
|
+
},
|
|
2876
|
+
{
|
|
2877
|
+
fileName: "client.std.log",
|
|
2878
|
+
source: "client-std",
|
|
2879
|
+
parser: parseStdLog2
|
|
2880
|
+
}
|
|
2881
|
+
];
|
|
2882
|
+
constructor(options = {}) {
|
|
2883
|
+
this.debug = options.debug ?? false;
|
|
2884
|
+
}
|
|
2885
|
+
log(...args) {
|
|
2886
|
+
if (this.debug) {
|
|
2887
|
+
console.log("[LogWatcher]", ...args);
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Start watching log files
|
|
2892
|
+
*/
|
|
2893
|
+
start(logDir) {
|
|
2894
|
+
if (this.isRunning) {
|
|
2895
|
+
this.log("Already running, ignoring start call");
|
|
2896
|
+
return;
|
|
2897
|
+
}
|
|
2898
|
+
this.logDir = logDir;
|
|
2899
|
+
this.isRunning = true;
|
|
2900
|
+
this.log(`Starting to watch log files in: ${logDir}`);
|
|
2901
|
+
for (const config of this.logFiles) {
|
|
2902
|
+
this.watchFile(config);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
/**
|
|
2906
|
+
* Stop watching all files
|
|
2907
|
+
*/
|
|
2908
|
+
stop() {
|
|
2909
|
+
if (!this.isRunning) {
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2912
|
+
this.log("Stopping file watchers");
|
|
2913
|
+
this.isRunning = false;
|
|
2914
|
+
Array.from(this.watchers.entries()).forEach(([fileName, watcher]) => {
|
|
2915
|
+
watcher.close();
|
|
2916
|
+
this.log(`Closed watcher for: ${fileName}`);
|
|
2917
|
+
});
|
|
2918
|
+
this.watchers.clear();
|
|
2919
|
+
this.filePositions.clear();
|
|
2920
|
+
}
|
|
2921
|
+
/**
|
|
2922
|
+
* Subscribe to new log events
|
|
2923
|
+
*/
|
|
2924
|
+
onLog(callback) {
|
|
2925
|
+
this.subscribers.add(callback);
|
|
2926
|
+
this.log(`Subscriber added, total: ${this.subscribers.size}`);
|
|
2927
|
+
return () => {
|
|
2928
|
+
this.subscribers.delete(callback);
|
|
2929
|
+
this.log(`Subscriber removed, total: ${this.subscribers.size}`);
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
/**
|
|
2933
|
+
* Get subscriber count
|
|
2934
|
+
*/
|
|
2935
|
+
getSubscriberCount() {
|
|
2936
|
+
return this.subscribers.size;
|
|
2937
|
+
}
|
|
2938
|
+
/**
|
|
2939
|
+
* Watch a single log file
|
|
2940
|
+
*/
|
|
2941
|
+
watchFile(config) {
|
|
2942
|
+
const filePath = path6.join(this.logDir, config.fileName);
|
|
2943
|
+
if (!fs9.existsSync(filePath)) {
|
|
2944
|
+
this.log(`File not found, skipping: ${config.fileName}`);
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
try {
|
|
2948
|
+
const stats = fs9.statSync(filePath);
|
|
2949
|
+
this.filePositions.set(config.fileName, stats.size);
|
|
2950
|
+
this.log(`Initialized position for ${config.fileName}: ${stats.size} bytes`);
|
|
2951
|
+
} catch (error) {
|
|
2952
|
+
this.log(`Failed to get initial position for ${config.fileName}:`, error);
|
|
2953
|
+
this.filePositions.set(config.fileName, 0);
|
|
2954
|
+
}
|
|
2955
|
+
try {
|
|
2956
|
+
const watcher = fs9.watch(filePath, (eventType) => {
|
|
2957
|
+
if (eventType === "change") {
|
|
2958
|
+
this.handleFileChange(config);
|
|
2959
|
+
}
|
|
2960
|
+
});
|
|
2961
|
+
watcher.on("error", (error) => {
|
|
2962
|
+
this.log(`Watcher error for ${config.fileName}:`, error);
|
|
2963
|
+
this.restartWatcher(config);
|
|
2964
|
+
});
|
|
2965
|
+
this.watchers.set(config.fileName, watcher);
|
|
2966
|
+
this.log(`Started watching: ${config.fileName}`);
|
|
2967
|
+
} catch (error) {
|
|
2968
|
+
this.log(`Failed to start watcher for ${config.fileName}:`, error);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
/**
|
|
2972
|
+
* Restart a file watcher after error
|
|
2973
|
+
*/
|
|
2974
|
+
restartWatcher(config) {
|
|
2975
|
+
const existingWatcher = this.watchers.get(config.fileName);
|
|
2976
|
+
if (existingWatcher) {
|
|
2977
|
+
existingWatcher.close();
|
|
2978
|
+
this.watchers.delete(config.fileName);
|
|
2979
|
+
}
|
|
2980
|
+
setTimeout(() => {
|
|
2981
|
+
if (this.isRunning) {
|
|
2982
|
+
this.log(`Restarting watcher for: ${config.fileName}`);
|
|
2983
|
+
this.watchFile(config);
|
|
2984
|
+
}
|
|
2985
|
+
}, 1e3);
|
|
2986
|
+
}
|
|
2987
|
+
/**
|
|
2988
|
+
* Handle file change event - read new content
|
|
2989
|
+
*/
|
|
2990
|
+
handleFileChange(config) {
|
|
2991
|
+
const filePath = path6.join(this.logDir, config.fileName);
|
|
2992
|
+
const lastPosition = this.filePositions.get(config.fileName) || 0;
|
|
2993
|
+
try {
|
|
2994
|
+
const stats = fs9.statSync(filePath);
|
|
2995
|
+
const currentSize = stats.size;
|
|
2996
|
+
if (currentSize < lastPosition) {
|
|
2997
|
+
this.log(`File ${config.fileName} was truncated, resetting position`);
|
|
2998
|
+
this.filePositions.set(config.fileName, 0);
|
|
2999
|
+
this.handleFileChange(config);
|
|
3000
|
+
return;
|
|
3001
|
+
}
|
|
3002
|
+
if (currentSize === lastPosition) {
|
|
3003
|
+
return;
|
|
3004
|
+
}
|
|
3005
|
+
const readSize = currentSize - lastPosition;
|
|
3006
|
+
const buffer = Buffer.alloc(readSize);
|
|
3007
|
+
const fd = fs9.openSync(filePath, "r");
|
|
3008
|
+
try {
|
|
3009
|
+
fs9.readSync(fd, buffer, 0, readSize, lastPosition);
|
|
3010
|
+
} finally {
|
|
3011
|
+
fs9.closeSync(fd);
|
|
3012
|
+
}
|
|
3013
|
+
this.filePositions.set(config.fileName, currentSize);
|
|
3014
|
+
const content = buffer.toString("utf8");
|
|
3015
|
+
const lines = content.split("\n");
|
|
3016
|
+
for (const line of lines) {
|
|
3017
|
+
if (!line.trim()) continue;
|
|
3018
|
+
try {
|
|
3019
|
+
const log = config.parser(line, config.source);
|
|
3020
|
+
if (log) {
|
|
3021
|
+
this.notifySubscribers(log);
|
|
3022
|
+
}
|
|
3023
|
+
} catch {
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
} catch (error) {
|
|
3027
|
+
this.log(`Error reading file ${config.fileName}:`, error);
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* Notify all subscribers of new log
|
|
3032
|
+
*/
|
|
3033
|
+
notifySubscribers(log) {
|
|
3034
|
+
Array.from(this.subscribers).forEach((subscriber) => {
|
|
3035
|
+
try {
|
|
3036
|
+
subscriber(log);
|
|
3037
|
+
} catch (error) {
|
|
3038
|
+
this.log("Subscriber error:", error);
|
|
3039
|
+
}
|
|
3040
|
+
});
|
|
3041
|
+
}
|
|
3042
|
+
};
|
|
3043
|
+
|
|
3044
|
+
// src/middlewares/dev-logs/sse/client-manager.ts
|
|
3045
|
+
var ClientManager = class {
|
|
3046
|
+
static {
|
|
3047
|
+
__name(this, "ClientManager");
|
|
3048
|
+
}
|
|
3049
|
+
clients = /* @__PURE__ */ new Map();
|
|
3050
|
+
debug = false;
|
|
3051
|
+
constructor(options = {}) {
|
|
3052
|
+
this.debug = options.debug ?? false;
|
|
3053
|
+
}
|
|
3054
|
+
log(...args) {
|
|
3055
|
+
if (this.debug) {
|
|
3056
|
+
console.log("[ClientManager]", ...args);
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
/**
|
|
3060
|
+
* Generate a unique client ID
|
|
3061
|
+
*/
|
|
3062
|
+
generateClientId() {
|
|
3063
|
+
return `client_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
3064
|
+
}
|
|
3065
|
+
/**
|
|
3066
|
+
* Add a new client connection
|
|
3067
|
+
*/
|
|
3068
|
+
addClient(id, res) {
|
|
3069
|
+
this.clients.set(id, {
|
|
3070
|
+
id,
|
|
3071
|
+
res,
|
|
3072
|
+
connectedAt: Date.now()
|
|
3073
|
+
});
|
|
3074
|
+
this.log(`Client connected: ${id}, total clients: ${this.clients.size}`);
|
|
3075
|
+
}
|
|
3076
|
+
/**
|
|
3077
|
+
* Remove a client connection
|
|
3078
|
+
*/
|
|
3079
|
+
removeClient(id) {
|
|
3080
|
+
if (this.clients.has(id)) {
|
|
3081
|
+
this.clients.delete(id);
|
|
3082
|
+
this.log(`Client disconnected: ${id}, total clients: ${this.clients.size}`);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
/**
|
|
3086
|
+
* Get current client count
|
|
3087
|
+
*/
|
|
3088
|
+
getClientCount() {
|
|
3089
|
+
return this.clients.size;
|
|
3090
|
+
}
|
|
3091
|
+
/**
|
|
3092
|
+
* Check if a client exists
|
|
3093
|
+
*/
|
|
3094
|
+
hasClient(id) {
|
|
3095
|
+
return this.clients.has(id);
|
|
3096
|
+
}
|
|
3097
|
+
/**
|
|
3098
|
+
* Send SSE event to a specific client
|
|
3099
|
+
*/
|
|
3100
|
+
sendToClient(clientId, event, data) {
|
|
3101
|
+
const client = this.clients.get(clientId);
|
|
3102
|
+
if (!client) {
|
|
3103
|
+
return false;
|
|
3104
|
+
}
|
|
3105
|
+
try {
|
|
3106
|
+
const message = this.formatSSEMessage(event, data);
|
|
3107
|
+
client.res.write(message);
|
|
3108
|
+
return true;
|
|
3109
|
+
} catch (error) {
|
|
3110
|
+
this.log(`Failed to send to client ${clientId}:`, error);
|
|
3111
|
+
this.removeClient(clientId);
|
|
3112
|
+
return false;
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
/**
|
|
3116
|
+
* Broadcast SSE event to all clients
|
|
3117
|
+
*/
|
|
3118
|
+
broadcast(event, data) {
|
|
3119
|
+
const message = this.formatSSEMessage(event, data);
|
|
3120
|
+
const failedClients = [];
|
|
3121
|
+
Array.from(this.clients.entries()).forEach(([id, client]) => {
|
|
3122
|
+
try {
|
|
3123
|
+
client.res.write(message);
|
|
3124
|
+
} catch (error) {
|
|
3125
|
+
this.log(`Broadcast failed for client ${id}:`, error);
|
|
3126
|
+
failedClients.push(id);
|
|
3127
|
+
}
|
|
3128
|
+
});
|
|
3129
|
+
failedClients.forEach((id) => {
|
|
3130
|
+
this.removeClient(id);
|
|
3131
|
+
});
|
|
3132
|
+
}
|
|
3133
|
+
/**
|
|
3134
|
+
* Format SSE message
|
|
3135
|
+
* SSE format: event: <event>\ndata: <json>\n\n
|
|
3136
|
+
*/
|
|
3137
|
+
formatSSEMessage(event, data) {
|
|
3138
|
+
const jsonData = JSON.stringify(data);
|
|
3139
|
+
return `event: ${event}
|
|
3140
|
+
data: ${jsonData}
|
|
3141
|
+
|
|
3142
|
+
`;
|
|
3143
|
+
}
|
|
3144
|
+
/**
|
|
3145
|
+
* Get all client IDs
|
|
3146
|
+
*/
|
|
3147
|
+
getClientIds() {
|
|
3148
|
+
return Array.from(this.clients.keys());
|
|
3149
|
+
}
|
|
3150
|
+
/**
|
|
3151
|
+
* Get client info
|
|
3152
|
+
*/
|
|
3153
|
+
getClientInfo(id) {
|
|
3154
|
+
const client = this.clients.get(id);
|
|
3155
|
+
if (!client) {
|
|
3156
|
+
return null;
|
|
3157
|
+
}
|
|
3158
|
+
return {
|
|
3159
|
+
id: client.id,
|
|
3160
|
+
connectedAt: client.connectedAt
|
|
3161
|
+
};
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* Close all client connections
|
|
3165
|
+
*/
|
|
3166
|
+
closeAll() {
|
|
3167
|
+
this.log(`Closing all ${this.clients.size} clients`);
|
|
3168
|
+
Array.from(this.clients.entries()).forEach(([id, client]) => {
|
|
3169
|
+
try {
|
|
3170
|
+
client.res.end();
|
|
3171
|
+
} catch (error) {
|
|
3172
|
+
this.log(`Error closing client ${id}:`, error);
|
|
3173
|
+
}
|
|
3174
|
+
});
|
|
3175
|
+
this.clients.clear();
|
|
3176
|
+
}
|
|
3177
|
+
};
|
|
3178
|
+
|
|
3179
|
+
// src/middlewares/dev-logs/sse/sse.controller.ts
|
|
3180
|
+
function createSSEHandler(logDir, options = {}) {
|
|
3181
|
+
const { debug = false, heartbeatInterval = 3e4 } = options;
|
|
3182
|
+
const logWatcher = new LogWatcher({
|
|
3183
|
+
debug
|
|
3184
|
+
});
|
|
3185
|
+
const clientManager = new ClientManager({
|
|
3186
|
+
debug
|
|
3187
|
+
});
|
|
3188
|
+
const log = /* @__PURE__ */ __name((...args) => {
|
|
3189
|
+
if (debug) {
|
|
3190
|
+
console.log("[SSEHandler]", ...args);
|
|
3191
|
+
}
|
|
3192
|
+
}, "log");
|
|
3193
|
+
return (req, res) => {
|
|
3194
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
3195
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
3196
|
+
res.setHeader("Connection", "keep-alive");
|
|
3197
|
+
res.setHeader("X-Accel-Buffering", "no");
|
|
3198
|
+
res.setTimeout(0);
|
|
3199
|
+
const clientId = clientManager.generateClientId();
|
|
3200
|
+
clientManager.addClient(clientId, res);
|
|
3201
|
+
log(`New SSE connection: ${clientId}`);
|
|
3202
|
+
if (clientManager.getClientCount() === 1) {
|
|
3203
|
+
log("First client connected, starting log watcher");
|
|
3204
|
+
logWatcher.start(logDir);
|
|
3205
|
+
}
|
|
3206
|
+
const unsubscribe = logWatcher.onLog((logEntry) => {
|
|
3207
|
+
clientManager.sendToClient(clientId, "log", logEntry);
|
|
3208
|
+
});
|
|
3209
|
+
clientManager.sendToClient(clientId, "connected", {
|
|
3210
|
+
clientId,
|
|
3211
|
+
timestamp: Date.now()
|
|
3212
|
+
});
|
|
3213
|
+
const heartbeat = setInterval(() => {
|
|
3214
|
+
const success = clientManager.sendToClient(clientId, "heartbeat", {
|
|
3215
|
+
timestamp: Date.now()
|
|
3216
|
+
});
|
|
3217
|
+
if (!success) {
|
|
3218
|
+
clearInterval(heartbeat);
|
|
3219
|
+
}
|
|
3220
|
+
}, heartbeatInterval);
|
|
3221
|
+
const cleanup = /* @__PURE__ */ __name(() => {
|
|
3222
|
+
log(`Client disconnected: ${clientId}`);
|
|
3223
|
+
clearInterval(heartbeat);
|
|
3224
|
+
unsubscribe();
|
|
3225
|
+
clientManager.removeClient(clientId);
|
|
3226
|
+
if (clientManager.getClientCount() === 0) {
|
|
3227
|
+
log("No more clients, stopping log watcher");
|
|
3228
|
+
logWatcher.stop();
|
|
3229
|
+
}
|
|
3230
|
+
}, "cleanup");
|
|
3231
|
+
req.on("close", cleanup);
|
|
3232
|
+
req.on("error", (error) => {
|
|
3233
|
+
log(`Client error ${clientId}:`, error);
|
|
3234
|
+
cleanup();
|
|
3235
|
+
});
|
|
3236
|
+
};
|
|
3237
|
+
}
|
|
3238
|
+
__name(createSSEHandler, "createSSEHandler");
|
|
3239
|
+
|
|
2875
3240
|
// src/middlewares/dev-logs/router.ts
|
|
2876
3241
|
function createDevLogRouter(options = {}) {
|
|
2877
3242
|
const logDir = resolveLogDir(options.logDir);
|
|
@@ -2880,9 +3245,9 @@ function createDevLogRouter(options = {}) {
|
|
|
2880
3245
|
router.get("/trace/recent", createGetRecentTracesHandler(logDir));
|
|
2881
3246
|
router.get("/files/:fileName", createGetLogFileHandler(logDir));
|
|
2882
3247
|
router.get("/server-logs", createGetServerLogsHandler(logDir));
|
|
3248
|
+
router.get("/server-logs/stream", createSSEHandler(logDir));
|
|
2883
3249
|
router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
|
|
2884
3250
|
router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
|
|
2885
|
-
router.get("/trace/capability/list", createGetCapabilityTraceListHandler(logDir));
|
|
2886
3251
|
router.get("/health", createHealthCheckHandler());
|
|
2887
3252
|
return router;
|
|
2888
3253
|
}
|
|
@@ -2942,11 +3307,11 @@ import express3 from "express";
|
|
|
2942
3307
|
|
|
2943
3308
|
// src/middlewares/collect-logs/controller.ts
|
|
2944
3309
|
import { join as join6 } from "path";
|
|
2945
|
-
import
|
|
3310
|
+
import fs11 from "fs";
|
|
2946
3311
|
|
|
2947
3312
|
// src/middlewares/collect-logs/utils.ts
|
|
2948
3313
|
import { isAbsolute as isAbsolute2, join as join5 } from "path";
|
|
2949
|
-
import
|
|
3314
|
+
import fs10 from "fs";
|
|
2950
3315
|
function resolveLogDir2(provided) {
|
|
2951
3316
|
if (!provided) {
|
|
2952
3317
|
return join5(process.cwd(), "logs");
|
|
@@ -2955,8 +3320,8 @@ function resolveLogDir2(provided) {
|
|
|
2955
3320
|
}
|
|
2956
3321
|
__name(resolveLogDir2, "resolveLogDir");
|
|
2957
3322
|
function ensureDir(dir) {
|
|
2958
|
-
if (!
|
|
2959
|
-
|
|
3323
|
+
if (!fs10.existsSync(dir)) {
|
|
3324
|
+
fs10.mkdirSync(dir, {
|
|
2960
3325
|
recursive: true
|
|
2961
3326
|
});
|
|
2962
3327
|
}
|
|
@@ -2988,7 +3353,7 @@ function collectLogsHandler(logDir, fileName) {
|
|
|
2988
3353
|
...logContent,
|
|
2989
3354
|
server_time: (/* @__PURE__ */ new Date()).toISOString()
|
|
2990
3355
|
}) + "\n";
|
|
2991
|
-
await
|
|
3356
|
+
await fs11.promises.appendFile(filePath, logLine);
|
|
2992
3357
|
res.json({
|
|
2993
3358
|
success: true
|
|
2994
3359
|
});
|
|
@@ -3016,7 +3381,7 @@ function collectLogsBatchHandler(logDir, fileName) {
|
|
|
3016
3381
|
server_time: (/* @__PURE__ */ new Date()).toISOString()
|
|
3017
3382
|
}) + "\n");
|
|
3018
3383
|
}
|
|
3019
|
-
await
|
|
3384
|
+
await fs11.promises.appendFile(filePath, logLines.join(""));
|
|
3020
3385
|
res.json({
|
|
3021
3386
|
success: true
|
|
3022
3387
|
});
|
|
@@ -3079,7 +3444,7 @@ function isGlobalMiddleware(middleware) {
|
|
|
3079
3444
|
}
|
|
3080
3445
|
__name(isGlobalMiddleware, "isGlobalMiddleware");
|
|
3081
3446
|
function computeMountPath(basePath, mountPath) {
|
|
3082
|
-
const routePath =
|
|
3447
|
+
const routePath = path7.posix.join(basePath, mountPath);
|
|
3083
3448
|
return routePath.startsWith("/") ? routePath : `/${routePath}`;
|
|
3084
3449
|
}
|
|
3085
3450
|
__name(computeMountPath, "computeMountPath");
|
|
@@ -3087,7 +3452,7 @@ function logMiddlewareRegistration(middleware, fullMountPath) {
|
|
|
3087
3452
|
if (middleware.routes && middleware.routes.length > 0) {
|
|
3088
3453
|
console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);
|
|
3089
3454
|
middleware.routes.forEach((route) => {
|
|
3090
|
-
const routePath = route.path === "/" ? fullMountPath :
|
|
3455
|
+
const routePath = route.path === "/" ? fullMountPath : path7.posix.join(fullMountPath, route.path);
|
|
3091
3456
|
console.log(` ${route.method} ${routePath} - ${route.description}`);
|
|
3092
3457
|
});
|
|
3093
3458
|
} else {
|