@lark-apaas/devtool-kits 1.2.5-alpha.1 → 1.2.5-alpha.2
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 +178 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +178 -230
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2136,229 +2136,146 @@ async function readLogFilePage(filePath, page, pageSize) {
|
|
|
2136
2136
|
};
|
|
2137
2137
|
}
|
|
2138
2138
|
__name(readLogFilePage, "readLogFilePage");
|
|
2139
|
-
async function
|
|
2140
|
-
|
|
2141
|
-
const offset = options.offset || 0;
|
|
2142
|
-
const sources = options.sources || [
|
|
2143
|
-
"server",
|
|
2144
|
-
"trace",
|
|
2145
|
-
"server-std",
|
|
2146
|
-
"client-std"
|
|
2147
|
-
];
|
|
2148
|
-
const allLogs = [];
|
|
2149
|
-
const errors = [];
|
|
2150
|
-
for (const source of sources) {
|
|
2151
|
-
try {
|
|
2152
|
-
const logs = await readLogsBySource(logDir, source);
|
|
2153
|
-
allLogs.push(...logs);
|
|
2154
|
-
} catch (error) {
|
|
2155
|
-
const errorMsg = `Failed to read ${source}: ${error instanceof Error ? error.message : String(error)}`;
|
|
2156
|
-
errors.push(errorMsg);
|
|
2157
|
-
console.warn(`[readServerLogs] ${errorMsg}`);
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
if (allLogs.length === 0) {
|
|
2161
|
-
if (errors.length > 0) {
|
|
2162
|
-
console.warn(`[readServerLogs] No logs found. Errors: ${errors.join(", ")}`);
|
|
2163
|
-
}
|
|
2139
|
+
async function readTriggerList(filePath, trigger, path7, limit) {
|
|
2140
|
+
if (!await fileExists(filePath)) {
|
|
2164
2141
|
return void 0;
|
|
2165
2142
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
}
|
|
2170
|
-
filteredLogs.sort((a, b) => b.timestamp - a.timestamp);
|
|
2171
|
-
const total = filteredLogs.length;
|
|
2172
|
-
const paginatedLogs = filteredLogs.slice(offset, offset + limit);
|
|
2173
|
-
return {
|
|
2174
|
-
logs: paginatedLogs,
|
|
2175
|
-
total,
|
|
2176
|
-
hasMore: offset + limit < total
|
|
2143
|
+
const config = {
|
|
2144
|
+
maxEntriesPerTrace: 10,
|
|
2145
|
+
chunkSize: 64 * 1024
|
|
2177
2146
|
};
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
}
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
try {
|
|
2208
|
-
stream = (0, import_node_fs7.createReadStream)(filePath, {
|
|
2209
|
-
encoding: "utf8"
|
|
2210
|
-
});
|
|
2211
|
-
rl = (0, import_node_readline.createInterface)({
|
|
2212
|
-
input: stream,
|
|
2213
|
-
crlfDelay: Infinity
|
|
2214
|
-
});
|
|
2215
|
-
for await (const line of rl) {
|
|
2216
|
-
if (!line.trim()) continue;
|
|
2217
|
-
try {
|
|
2218
|
-
const log = parser(line);
|
|
2219
|
-
if (log) {
|
|
2220
|
-
logs.push(log);
|
|
2221
|
-
}
|
|
2222
|
-
} catch (parseError) {
|
|
2147
|
+
const builders = /* @__PURE__ */ new Map();
|
|
2148
|
+
const completedCalls = [];
|
|
2149
|
+
const createTraceBuilder = /* @__PURE__ */ __name((traceId) => ({
|
|
2150
|
+
traceId,
|
|
2151
|
+
entries: [],
|
|
2152
|
+
method: void 0,
|
|
2153
|
+
path: void 0,
|
|
2154
|
+
startTime: void 0,
|
|
2155
|
+
endTime: void 0,
|
|
2156
|
+
statusCode: void 0,
|
|
2157
|
+
durationMs: void 0,
|
|
2158
|
+
hasCompleted: false
|
|
2159
|
+
}), "createTraceBuilder");
|
|
2160
|
+
const shouldIncludeInCompletedCalls = /* @__PURE__ */ __name((builder) => {
|
|
2161
|
+
const alreadyAdded = completedCalls.some((call) => call.traceId === builder.traceId);
|
|
2162
|
+
if (alreadyAdded) {
|
|
2163
|
+
return false;
|
|
2164
|
+
}
|
|
2165
|
+
if (!builder.hasCompleted) {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
const isAutomationTrigger = builder.path === path7;
|
|
2169
|
+
if (!isAutomationTrigger) {
|
|
2170
|
+
return false;
|
|
2171
|
+
}
|
|
2172
|
+
if (trigger && builder.entries.length > 0) {
|
|
2173
|
+
const requestEntry = builder.entries.find((e) => e.request_body?.trigger);
|
|
2174
|
+
if (requestEntry?.request_body?.trigger) {
|
|
2175
|
+
return String(requestEntry.request_body.trigger) === trigger;
|
|
2223
2176
|
}
|
|
2177
|
+
return false;
|
|
2224
2178
|
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
if (
|
|
2230
|
-
|
|
2179
|
+
return true;
|
|
2180
|
+
}, "shouldIncludeInCompletedCalls");
|
|
2181
|
+
const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
|
|
2182
|
+
if (entry.method && !builder.method) builder.method = String(entry.method);
|
|
2183
|
+
if (entry.path && !builder.path) builder.path = String(entry.path);
|
|
2184
|
+
builder.entries.push(entry);
|
|
2185
|
+
if (builder.entries.length > config.maxEntriesPerTrace) {
|
|
2186
|
+
builder.entries.shift();
|
|
2231
2187
|
}
|
|
2232
|
-
if (
|
|
2233
|
-
|
|
2188
|
+
if (shouldIncludeInCompletedCalls(builder)) {
|
|
2189
|
+
completedCalls.push(builder);
|
|
2190
|
+
if (limit && completedCalls.length > limit) {
|
|
2191
|
+
completedCalls.shift();
|
|
2192
|
+
}
|
|
2234
2193
|
}
|
|
2235
|
-
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
return {
|
|
2244
|
-
id,
|
|
2245
|
-
level: mapPinoLevelToServerLogLevel(pinoLog.level),
|
|
2246
|
-
timestamp: new Date(pinoLog.time).getTime(),
|
|
2247
|
-
message: pinoLog.message || pinoLog.msg || "",
|
|
2248
|
-
context: pinoLog.context || null,
|
|
2249
|
-
traceId: pinoLog.trace_id || null,
|
|
2250
|
-
userId: pinoLog.user_id || null,
|
|
2251
|
-
appId: pinoLog.app_id || null,
|
|
2252
|
-
tenantId: pinoLog.tenant_id || null,
|
|
2253
|
-
stack: pinoLog.stack || null,
|
|
2254
|
-
meta: {
|
|
2255
|
-
pid: pinoLog.pid,
|
|
2256
|
-
hostname: pinoLog.hostname,
|
|
2257
|
-
path: pinoLog.path,
|
|
2258
|
-
method: pinoLog.method,
|
|
2259
|
-
statusCode: pinoLog.status_code,
|
|
2260
|
-
durationMs: pinoLog.duration_ms,
|
|
2261
|
-
ip: pinoLog.ip,
|
|
2262
|
-
requestBody: pinoLog.request_body,
|
|
2263
|
-
responseBody: pinoLog.response_body
|
|
2264
|
-
},
|
|
2265
|
-
tags: [
|
|
2266
|
-
source
|
|
2267
|
-
]
|
|
2268
|
-
};
|
|
2269
|
-
} catch (error) {
|
|
2270
|
-
return null;
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
__name(parsePinoLog, "parsePinoLog");
|
|
2274
|
-
function parseStdLog(line, source) {
|
|
2275
|
-
const id = generateUUID();
|
|
2276
|
-
const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
|
|
2277
|
-
if (!match) {
|
|
2278
|
-
return {
|
|
2279
|
-
id,
|
|
2280
|
-
level: "log",
|
|
2281
|
-
timestamp: Date.now(),
|
|
2282
|
-
message: line,
|
|
2283
|
-
context: null,
|
|
2284
|
-
traceId: null,
|
|
2285
|
-
userId: null,
|
|
2286
|
-
appId: null,
|
|
2287
|
-
tenantId: null,
|
|
2288
|
-
stack: null,
|
|
2289
|
-
meta: null,
|
|
2290
|
-
tags: [
|
|
2291
|
-
source
|
|
2292
|
-
]
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
const [, timeStr, , content] = match;
|
|
2296
|
-
let timestamp;
|
|
2297
|
-
try {
|
|
2298
|
-
const isoStr = timeStr.replace(" ", "T");
|
|
2299
|
-
timestamp = new Date(isoStr).getTime();
|
|
2300
|
-
if (isNaN(timestamp)) {
|
|
2301
|
-
timestamp = Date.now();
|
|
2194
|
+
}, "updateBuilderMetadata");
|
|
2195
|
+
const handleRequestCompleted = /* @__PURE__ */ __name((builder, entry, message) => {
|
|
2196
|
+
builder.hasCompleted = true;
|
|
2197
|
+
builder.endTime = entry.time;
|
|
2198
|
+
builder.statusCode = extractNumber(message, /status_code:\s*(\d+)/);
|
|
2199
|
+
builder.durationMs = extractNumber(message, /duration_ms:\s*(\d+)/);
|
|
2200
|
+
if (!builder.path && entry.path) {
|
|
2201
|
+
builder.path = String(entry.path);
|
|
2302
2202
|
}
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2203
|
+
if (shouldIncludeInCompletedCalls(builder)) {
|
|
2204
|
+
completedCalls.push(builder);
|
|
2205
|
+
if (limit && completedCalls.length > limit) {
|
|
2206
|
+
completedCalls.shift();
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}, "handleRequestCompleted");
|
|
2210
|
+
const processLogEntry = /* @__PURE__ */ __name((entry) => {
|
|
2211
|
+
const { trace_id: traceId, message = "" } = entry;
|
|
2212
|
+
if (!traceId) return;
|
|
2213
|
+
let builder = builders.get(traceId);
|
|
2214
|
+
if (!builder) {
|
|
2215
|
+
builder = createTraceBuilder(traceId);
|
|
2216
|
+
builders.set(traceId, builder);
|
|
2217
|
+
}
|
|
2218
|
+
updateBuilderMetadata(builder, entry);
|
|
2219
|
+
if (!builder.hasCompleted && (message.includes("HTTP request completed") || message.includes("HTTP request failed"))) {
|
|
2220
|
+
handleRequestCompleted(builder, entry, message);
|
|
2221
|
+
}
|
|
2222
|
+
if (message.includes("HTTP request started") && !builder.startTime) {
|
|
2223
|
+
builder.startTime = entry.time;
|
|
2224
|
+
}
|
|
2225
|
+
}, "processLogEntry");
|
|
2226
|
+
const processLine = /* @__PURE__ */ __name((line) => {
|
|
2227
|
+
const entry = parseLogLine2(line);
|
|
2228
|
+
if (entry?.trace_id) {
|
|
2229
|
+
processLogEntry(entry);
|
|
2230
|
+
}
|
|
2231
|
+
}, "processLine");
|
|
2232
|
+
await readFileReverse(filePath, config.chunkSize, processLine);
|
|
2307
2233
|
return {
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2234
|
+
page: 1,
|
|
2235
|
+
pageSize: completedCalls.length,
|
|
2236
|
+
totalCalls: completedCalls.length,
|
|
2237
|
+
totalPages: 1,
|
|
2238
|
+
calls: completedCalls.map((builder) => ({
|
|
2239
|
+
traceId: builder.traceId,
|
|
2240
|
+
method: builder.method,
|
|
2241
|
+
path: builder.path,
|
|
2242
|
+
startTime: builder.startTime,
|
|
2243
|
+
endTime: builder.endTime,
|
|
2244
|
+
statusCode: builder.statusCode,
|
|
2245
|
+
durationMs: builder.durationMs,
|
|
2246
|
+
entries: builder.entries.slice().reverse()
|
|
2247
|
+
}))
|
|
2322
2248
|
};
|
|
2323
2249
|
}
|
|
2324
|
-
__name(
|
|
2325
|
-
function
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
if (lower === "trace" || lower === "verbose") return "verbose";
|
|
2334
|
-
return "log";
|
|
2335
|
-
}
|
|
2336
|
-
if (pinoLevel >= 60) return "fatal";
|
|
2337
|
-
if (pinoLevel >= 50) return "error";
|
|
2338
|
-
if (pinoLevel >= 40) return "warn";
|
|
2339
|
-
if (pinoLevel >= 30) return "log";
|
|
2340
|
-
if (pinoLevel >= 20) return "debug";
|
|
2341
|
-
return "verbose";
|
|
2342
|
-
}
|
|
2343
|
-
__name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
|
|
2344
|
-
function extractLogLevel(text) {
|
|
2345
|
-
const lower = text.toLowerCase();
|
|
2346
|
-
if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
|
|
2347
|
-
if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
|
|
2348
|
-
if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
|
|
2349
|
-
if (lower.includes("debug") || lower.includes("<d>")) return "debug";
|
|
2350
|
-
if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
|
|
2351
|
-
return "log";
|
|
2352
|
-
}
|
|
2353
|
-
__name(extractLogLevel, "extractLogLevel");
|
|
2354
|
-
function generateUUID() {
|
|
2355
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
2356
|
-
const r = Math.random() * 16 | 0;
|
|
2357
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
2358
|
-
return v.toString(16);
|
|
2250
|
+
__name(readTriggerList, "readTriggerList");
|
|
2251
|
+
async function readTriggerDetail(filePath, instanceID) {
|
|
2252
|
+
const exists = await fileExists(filePath);
|
|
2253
|
+
if (!exists) {
|
|
2254
|
+
return void 0;
|
|
2255
|
+
}
|
|
2256
|
+
const matches = [];
|
|
2257
|
+
const stream = (0, import_node_fs7.createReadStream)(filePath, {
|
|
2258
|
+
encoding: "utf8"
|
|
2359
2259
|
});
|
|
2260
|
+
const rl = (0, import_node_readline.createInterface)({
|
|
2261
|
+
input: stream,
|
|
2262
|
+
crlfDelay: Infinity
|
|
2263
|
+
});
|
|
2264
|
+
for await (const line of rl) {
|
|
2265
|
+
const entry = parseLogLine2(line);
|
|
2266
|
+
if (!entry) continue;
|
|
2267
|
+
const hasInstanceID = entry.message?.includes(`instanceID=${instanceID}`);
|
|
2268
|
+
if (!hasInstanceID) continue;
|
|
2269
|
+
matches.push(entry);
|
|
2270
|
+
}
|
|
2271
|
+
rl.close();
|
|
2272
|
+
stream.close();
|
|
2273
|
+
return {
|
|
2274
|
+
instanceID,
|
|
2275
|
+
entries: matches
|
|
2276
|
+
};
|
|
2360
2277
|
}
|
|
2361
|
-
__name(
|
|
2278
|
+
__name(readTriggerDetail, "readTriggerDetail");
|
|
2362
2279
|
|
|
2363
2280
|
// src/middlewares/dev-logs/controller.ts
|
|
2364
2281
|
function handleNotFound(res, filePath, message = "Log file not found") {
|
|
@@ -2452,32 +2369,57 @@ function createGetLogFileHandler(logDir) {
|
|
|
2452
2369
|
};
|
|
2453
2370
|
}
|
|
2454
2371
|
__name(createGetLogFileHandler, "createGetLogFileHandler");
|
|
2455
|
-
function
|
|
2372
|
+
function createGetTriggerListHandler(logDir) {
|
|
2373
|
+
const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
|
|
2456
2374
|
return async (req, res) => {
|
|
2457
|
-
const
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2375
|
+
const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
|
|
2376
|
+
if (!trigger) {
|
|
2377
|
+
return res.status(400).json({
|
|
2378
|
+
message: "trigger is required"
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
const path7 = typeof req.query.path === "string" ? req.query.path.trim() : "/__innerapi__/automation/invoke";
|
|
2382
|
+
const limit = parseLimit(req.query.limit, 10, 200);
|
|
2461
2383
|
try {
|
|
2462
|
-
const result = await
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2384
|
+
const result = await readTriggerList(traceLogPath, trigger, path7, limit);
|
|
2385
|
+
if (!result) {
|
|
2386
|
+
return handleNotFound(res, traceLogPath);
|
|
2387
|
+
}
|
|
2388
|
+
res.json({
|
|
2389
|
+
file: getRelativePath(traceLogPath),
|
|
2390
|
+
path: path7,
|
|
2391
|
+
...result
|
|
2467
2392
|
});
|
|
2393
|
+
} catch (error) {
|
|
2394
|
+
handleError(res, error, "Failed to read trace log");
|
|
2395
|
+
}
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
__name(createGetTriggerListHandler, "createGetTriggerListHandler");
|
|
2399
|
+
function createGetTriggerDetailHandler(logDir) {
|
|
2400
|
+
const traceLogPath = (0, import_node_path7.join)(logDir, "server.log");
|
|
2401
|
+
return async (req, res) => {
|
|
2402
|
+
const instanceID = (req.params.instanceID || "").trim();
|
|
2403
|
+
if (!instanceID) {
|
|
2404
|
+
return res.status(400).json({
|
|
2405
|
+
message: "instanceID is required"
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
try {
|
|
2409
|
+
const result = await readTriggerDetail(traceLogPath, instanceID);
|
|
2468
2410
|
if (!result) {
|
|
2469
|
-
return res
|
|
2470
|
-
message: "No server log files found",
|
|
2471
|
-
hint: "Expected files: server.log, trace.log, server.std.log, client.std.log"
|
|
2472
|
-
});
|
|
2411
|
+
return handleNotFound(res, traceLogPath);
|
|
2473
2412
|
}
|
|
2474
|
-
res.json(
|
|
2413
|
+
res.json({
|
|
2414
|
+
file: getRelativePath(traceLogPath),
|
|
2415
|
+
...result
|
|
2416
|
+
});
|
|
2475
2417
|
} catch (error) {
|
|
2476
|
-
handleError(res, error, "Failed to read
|
|
2418
|
+
handleError(res, error, "Failed to read trace log");
|
|
2477
2419
|
}
|
|
2478
2420
|
};
|
|
2479
2421
|
}
|
|
2480
|
-
__name(
|
|
2422
|
+
__name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
|
|
2481
2423
|
|
|
2482
2424
|
// src/middlewares/dev-logs/health.controller.ts
|
|
2483
2425
|
var import_node_http2 = __toESM(require("http"), 1);
|
|
@@ -2553,7 +2495,8 @@ function createDevLogRouter(options = {}) {
|
|
|
2553
2495
|
router.get("/app/trace/:traceId", createGetTraceEntriesHandler(logDir));
|
|
2554
2496
|
router.get("/trace/recent", createGetRecentTracesHandler(logDir));
|
|
2555
2497
|
router.get("/files/:fileName", createGetLogFileHandler(logDir));
|
|
2556
|
-
router.get("/
|
|
2498
|
+
router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
|
|
2499
|
+
router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
|
|
2557
2500
|
router.get("/health", createHealthCheckHandler());
|
|
2558
2501
|
return router;
|
|
2559
2502
|
}
|
|
@@ -2578,8 +2521,13 @@ var DEV_LOGS_ROUTES = [
|
|
|
2578
2521
|
},
|
|
2579
2522
|
{
|
|
2580
2523
|
method: "GET",
|
|
2581
|
-
path: "/
|
|
2582
|
-
description: "Get
|
|
2524
|
+
path: "/trace/trigger/list",
|
|
2525
|
+
description: "Get trigger list (automation trigger) in trace.log"
|
|
2526
|
+
},
|
|
2527
|
+
{
|
|
2528
|
+
method: "GET",
|
|
2529
|
+
path: "/trace/trigger/:instanceID",
|
|
2530
|
+
description: "Get trigger detail (automation trigger) in trace.log by instanceID"
|
|
2583
2531
|
}
|
|
2584
2532
|
];
|
|
2585
2533
|
function createDevLogsMiddleware(options = {}) {
|