@lark-apaas/devtool-kits 1.2.4 → 1.2.5-alpha.1

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 CHANGED
@@ -2136,6 +2136,229 @@ async function readLogFilePage(filePath, page, pageSize) {
2136
2136
  };
2137
2137
  }
2138
2138
  __name(readLogFilePage, "readLogFilePage");
2139
+ async function readServerLogs(logDir, options = {}) {
2140
+ const limit = options.limit || 100;
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
+ }
2164
+ return void 0;
2165
+ }
2166
+ let filteredLogs = allLogs;
2167
+ if (options.levels && options.levels.length > 0) {
2168
+ filteredLogs = allLogs.filter((log) => options.levels.includes(log.level));
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
2177
+ };
2178
+ }
2179
+ __name(readServerLogs, "readServerLogs");
2180
+ async function readLogsBySource(logDir, source) {
2181
+ const { join: join6 } = await import("path");
2182
+ let filePath;
2183
+ let parser;
2184
+ if (source === "server") {
2185
+ filePath = join6(logDir, "server.log");
2186
+ parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
2187
+ } else if (source === "trace") {
2188
+ filePath = join6(logDir, "trace.log");
2189
+ parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
2190
+ } else if (source === "server-std") {
2191
+ filePath = join6(logDir, "server.std.log");
2192
+ parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
2193
+ } else if (source === "client-std") {
2194
+ filePath = join6(logDir, "client.std.log");
2195
+ parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
2196
+ } else {
2197
+ console.warn(`[readLogsBySource] Unknown source: ${source}`);
2198
+ return [];
2199
+ }
2200
+ if (!await fileExists(filePath)) {
2201
+ console.warn(`[readLogsBySource] File not found: ${filePath}`);
2202
+ return [];
2203
+ }
2204
+ const logs = [];
2205
+ let stream = null;
2206
+ let rl = null;
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) {
2223
+ }
2224
+ }
2225
+ } catch (error) {
2226
+ console.error(`[readLogsBySource] Error reading ${filePath}:`, error);
2227
+ throw error;
2228
+ } finally {
2229
+ if (rl) {
2230
+ rl.close();
2231
+ }
2232
+ if (stream) {
2233
+ stream.close();
2234
+ }
2235
+ }
2236
+ return logs;
2237
+ }
2238
+ __name(readLogsBySource, "readLogsBySource");
2239
+ function parsePinoLog(line, source) {
2240
+ try {
2241
+ const pinoLog = JSON.parse(line);
2242
+ const id = generateUUID();
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();
2302
+ }
2303
+ } catch (error) {
2304
+ timestamp = Date.now();
2305
+ }
2306
+ const level = extractLogLevel(content);
2307
+ return {
2308
+ id,
2309
+ level,
2310
+ timestamp,
2311
+ message: content,
2312
+ context: null,
2313
+ traceId: null,
2314
+ userId: null,
2315
+ appId: null,
2316
+ tenantId: null,
2317
+ stack: null,
2318
+ meta: null,
2319
+ tags: [
2320
+ source
2321
+ ]
2322
+ };
2323
+ }
2324
+ __name(parseStdLog, "parseStdLog");
2325
+ function mapPinoLevelToServerLogLevel(pinoLevel) {
2326
+ if (typeof pinoLevel === "string") {
2327
+ const lower = pinoLevel.toLowerCase();
2328
+ if (lower === "fatal") return "fatal";
2329
+ if (lower === "error") return "error";
2330
+ if (lower === "warn" || lower === "warning") return "warn";
2331
+ if (lower === "info" || lower === "log") return "log";
2332
+ if (lower === "debug") return "debug";
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);
2359
+ });
2360
+ }
2361
+ __name(generateUUID, "generateUUID");
2139
2362
 
2140
2363
  // src/middlewares/dev-logs/controller.ts
2141
2364
  function handleNotFound(res, filePath, message = "Log file not found") {
@@ -2229,6 +2452,32 @@ function createGetLogFileHandler(logDir) {
2229
2452
  };
2230
2453
  }
2231
2454
  __name(createGetLogFileHandler, "createGetLogFileHandler");
2455
+ function createGetServerLogsHandler(logDir) {
2456
+ return async (req, res) => {
2457
+ const limit = parseLimit(req.query.limit, 100, 1e3);
2458
+ const offset = parsePositiveInt(req.query.offset, 0);
2459
+ const levels = req.query.levels ? String(req.query.levels).split(",").map((l) => l.trim()).filter(Boolean) : void 0;
2460
+ const sources = req.query.sources ? String(req.query.sources).split(",").map((s) => s.trim()).filter(Boolean) : void 0;
2461
+ try {
2462
+ const result = await readServerLogs(logDir, {
2463
+ limit,
2464
+ offset,
2465
+ levels,
2466
+ sources
2467
+ });
2468
+ if (!result) {
2469
+ return res.status(404).json({
2470
+ message: "No server log files found",
2471
+ hint: "Expected files: server.log, trace.log, server.std.log, client.std.log"
2472
+ });
2473
+ }
2474
+ res.json(result);
2475
+ } catch (error) {
2476
+ handleError(res, error, "Failed to read server logs");
2477
+ }
2478
+ };
2479
+ }
2480
+ __name(createGetServerLogsHandler, "createGetServerLogsHandler");
2232
2481
 
2233
2482
  // src/middlewares/dev-logs/health.controller.ts
2234
2483
  var import_node_http2 = __toESM(require("http"), 1);
@@ -2304,6 +2553,7 @@ function createDevLogRouter(options = {}) {
2304
2553
  router.get("/app/trace/:traceId", createGetTraceEntriesHandler(logDir));
2305
2554
  router.get("/trace/recent", createGetRecentTracesHandler(logDir));
2306
2555
  router.get("/files/:fileName", createGetLogFileHandler(logDir));
2556
+ router.get("/server-logs", createGetServerLogsHandler(logDir));
2307
2557
  router.get("/health", createHealthCheckHandler());
2308
2558
  return router;
2309
2559
  }
@@ -2325,6 +2575,11 @@ var DEV_LOGS_ROUTES = [
2325
2575
  method: "GET",
2326
2576
  path: "/files/:fileName",
2327
2577
  description: "Get paginated log file content by file name"
2578
+ },
2579
+ {
2580
+ method: "GET",
2581
+ path: "/server-logs",
2582
+ description: "Get server logs in ServerLog format (compatible with frontend)"
2328
2583
  }
2329
2584
  ];
2330
2585
  function createDevLogsMiddleware(options = {}) {