ylib-syim 0.0.20 → 0.0.22

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.
@@ -52,15 +52,18 @@ process.on("unhandledRejection", (reason) => {
52
52
  | ((payload: Record<string, unknown>) => void)
53
53
  | undefined;
54
54
  const nowIso = new Date().toISOString();
55
- sink?.({
56
- platform: "dingtalk",
57
- bot_account_id: payload.accountId,
58
- link_status: payload.linkStatus,
59
- last_error: payload.lastError || null,
60
- status_source: "event",
61
- last_event_at: nowIso,
62
- last_heartbeat_at: nowIso,
63
- });
55
+ if (sink) {
56
+ sink({
57
+ platform: "dingtalk",
58
+ bot_account_id: payload.accountId,
59
+ link_status: payload.linkStatus,
60
+ last_error: payload.lastError || null,
61
+ status_source: "event",
62
+ last_event_at: nowIso,
63
+ last_heartbeat_at: nowIso,
64
+ });
65
+ return Promise.resolve({ ok: true, transport: "in_process_sink" });
66
+ }
64
67
  } catch {
65
68
  // ignore
66
69
  }
@@ -52,15 +52,18 @@ process.on("unhandledRejection", (reason) => {
52
52
  | ((payload: Record<string, unknown>) => void)
53
53
  | undefined;
54
54
  const nowIso = new Date().toISOString();
55
- sink?.({
56
- platform: "feishu",
57
- bot_account_id: payload.accountId,
58
- link_status: payload.linkStatus,
59
- last_error: payload.lastError || null,
60
- status_source: "event",
61
- last_event_at: nowIso,
62
- last_heartbeat_at: nowIso,
63
- });
55
+ if (sink) {
56
+ sink({
57
+ platform: "feishu",
58
+ bot_account_id: payload.accountId,
59
+ link_status: payload.linkStatus,
60
+ last_error: payload.lastError || null,
61
+ status_source: "event",
62
+ last_event_at: nowIso,
63
+ last_heartbeat_at: nowIso,
64
+ });
65
+ return Promise.resolve({ ok: true, transport: "in_process_sink" });
66
+ }
64
67
  } catch {
65
68
  // ignore
66
69
  }
package/bridges/logger.ts CHANGED
@@ -5,11 +5,28 @@ import type { WriteStream } from "node:fs";
5
5
 
6
6
  type ConsoleMethod = (...args: unknown[]) => void;
7
7
 
8
+ type BridgeLogLevel = "log" | "info" | "warn" | "error" | "debug" | "system";
9
+ type BridgeLoggerWriteFn = (level: BridgeLogLevel, message: string) => void;
10
+
8
11
  type BridgeLoggerState = {
9
12
  enabled: boolean;
10
13
  logFilePath: string;
14
+ write?: BridgeLoggerWriteFn;
11
15
  };
12
16
 
17
+ const BEIJING_OFFSET_MS = 8 * 60 * 60 * 1000;
18
+
19
+ function padFixed(value: number, size = 2): string {
20
+ return String(value).padStart(size, "0");
21
+ }
22
+
23
+ export function formatBeijingLogTimestamp(date: Date = new Date()): string {
24
+ const shifted = new Date(date.getTime() + BEIJING_OFFSET_MS);
25
+ const datePart = `${shifted.getUTCFullYear()}-${padFixed(shifted.getUTCMonth() + 1)}-${padFixed(shifted.getUTCDate())}`;
26
+ const timePart = `${padFixed(shifted.getUTCHours())}:${padFixed(shifted.getUTCMinutes())}:${padFixed(shifted.getUTCSeconds())}.${padFixed(shifted.getUTCMilliseconds(), 3)}`;
27
+ return `${datePart}T${timePart}+08:00`;
28
+ }
29
+
13
30
  declare global {
14
31
  // eslint-disable-next-line no-var
15
32
  var __imAgentHubBridgeLogger: BridgeLoggerState | undefined;
@@ -18,10 +35,33 @@ declare global {
18
35
  function buildLogFilePath(prefix: string): string {
19
36
  const logsDir = path.join(process.cwd(), "logs");
20
37
  fs.mkdirSync(logsDir, { recursive: true });
21
- const stamp = new Date().toISOString().replace(/[:.]/g, "-");
38
+ const stamp = formatBeijingLogTimestamp().replace(/[:.]/g, "-");
22
39
  return path.join(logsDir, `${prefix}-${stamp}-${process.pid}.log`);
23
40
  }
24
41
 
42
+ export function writeBridgeStructuredLog(
43
+ level: BridgeLogLevel,
44
+ message: string,
45
+ ): void {
46
+ const state = globalThis.__imAgentHubBridgeLogger;
47
+ if (!state?.enabled) return;
48
+ if (typeof state.write === "function") {
49
+ state.write(level, message);
50
+ return;
51
+ }
52
+ const logFilePath = String(state.logFilePath || "").trim();
53
+ if (!logFilePath) return;
54
+ try {
55
+ fs.appendFileSync(
56
+ logFilePath,
57
+ `[${formatBeijingLogTimestamp()}] [${level}] ${message}\n`,
58
+ "utf-8",
59
+ );
60
+ } catch {
61
+ // logger 写入失败必须静默
62
+ }
63
+ }
64
+
25
65
  function patchConsole(writeLine: (line: string) => void): void {
26
66
  const methods: Array<keyof Console> = ["log", "info", "warn", "error", "debug"];
27
67
  for (const method of methods) {
@@ -29,7 +69,7 @@ function patchConsole(writeLine: (line: string) => void): void {
29
69
  console[method] = (...args: unknown[]) => {
30
70
  const line = format(...args);
31
71
  try {
32
- writeLine(`[${new Date().toISOString()}] [${method}] ${line}`);
72
+ writeLine(`[${formatBeijingLogTimestamp()}] [${method}] ${line}`);
33
73
  } catch {
34
74
  // logger 必须永不影响主进程
35
75
  }
@@ -138,9 +178,19 @@ export function setupBridgeLogger(prefix: string): string {
138
178
  }
139
179
  }
140
180
 
141
- writeRaw(`[${new Date().toISOString()}] [system] bridge logger started\n`);
181
+ writeRaw(`[${formatBeijingLogTimestamp()}] [system] bridge logger started\n`);
142
182
  writtenLines += 1;
143
183
 
184
+ const appendStructuredLog: BridgeLoggerWriteFn = (level, message) => {
185
+ writeRaw(
186
+ `[${formatBeijingLogTimestamp()}] [${level}] ${String(message || "")}\n`,
187
+ );
188
+ writtenLines += 1;
189
+ if (maxLines > 0 && writtenLines > maxLines + trimBatch && !trimming) {
190
+ void trimToLastLines();
191
+ }
192
+ };
193
+
144
194
  patchConsole((line) => {
145
195
  writeRaw(`${line}\n`);
146
196
  writtenLines += 1;
@@ -148,10 +198,17 @@ export function setupBridgeLogger(prefix: string): string {
148
198
  void trimToLastLines();
149
199
  }
150
200
  });
151
- globalThis.__imAgentHubBridgeLogger = { enabled: true, logFilePath };
201
+ globalThis.__imAgentHubBridgeLogger = {
202
+ enabled: true,
203
+ logFilePath,
204
+ write: appendStructuredLog,
205
+ };
152
206
  return logFilePath;
153
207
  } catch {
154
- globalThis.__imAgentHubBridgeLogger = { enabled: false, logFilePath: "" };
208
+ globalThis.__imAgentHubBridgeLogger = {
209
+ enabled: false,
210
+ logFilePath: "",
211
+ };
155
212
  return "";
156
213
  }
157
214
  }