@fuzionx/core 0.1.28 → 0.1.30

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.
Files changed (2) hide show
  1. package/lib/logger.js +56 -51
  2. package/package.json +2 -2
package/lib/logger.js CHANGED
@@ -11,74 +11,88 @@
11
11
  import { format } from 'node:util';
12
12
 
13
13
  /**
14
- * JS 호출 스택에서 실제 호출 위치(파일:라인)를 추출한다.
15
- * error/warn 레벨에서만 사용 (new Error().stack 비용 고려).
14
+ * 스택 프레임 문자열에서 파일:라인을 추출한다.
15
+ * @param {string} frameLine - 스택 프레임 한 줄
16
+ * @returns {string} 파일:라인 또는 빈 문자열
17
+ */
18
+ function parseFrame(frameLine) {
19
+ const matchParen = frameLine.match(/\((.+):(\d+):\d+\)/);
20
+ if (matchParen) return `${matchParen[1]}:${matchParen[2]}`;
21
+ const matchDirect = frameLine.match(/at (.+):(\d+):\d+/);
22
+ if (matchDirect) return `${matchDirect[1]}:${matchDirect[2]}`;
23
+ return '';
24
+ }
25
+
26
+ /** 로거/프레임워크 내부 파일 — 호출 위치 추출 시 건너뜀 */
27
+ const SKIP_PATTERNS = ['/logger.js:', '/Logger.js:', '/ErrorHandler.js:'];
28
+
29
+ /**
30
+ * 인자 목록에서 Error 객체를 찾아 throw 위치를 반환한다.
31
+ * @param {any[]} args
32
+ * @returns {string} 파일:라인 또는 빈 문자열
33
+ */
34
+ function findErrorOrigin(args) {
35
+ for (const arg of args) {
36
+ if (arg instanceof Error && arg.stack) {
37
+ return parseFrame(arg.stack.split('\n')[1] || '');
38
+ }
39
+ }
40
+ return '';
41
+ }
42
+
43
+ /**
44
+ * 호출 스택에서 로거/프레임워크 내부 파일을 건너뛴 첫 외부 호출 위치를 반환한다.
45
+ * depth 기반이 아니라 파일명 패턴 기반이므로 호출 체인 변경에 안전하다.
16
46
  *
17
- * @param {number} depth - 스택 프레임 깊이 (기본 3: Error → getCallSite → logWarn → 실제 호출)
18
- * @returns {string} 파일:라인 문자열 (예: "server.js:42") 또는 빈 문자열
47
+ * @returns {string} 파일:라인 또는 문자열
19
48
  */
20
- function getCallSite(depth = 3) {
49
+ function getExternalCallSite() {
21
50
  const stack = new Error().stack;
22
51
  if (!stack) return '';
23
-
24
52
  const lines = stack.split('\n');
25
- // depth번째 라인이 실제 호출자
26
- const line = lines[depth] || '';
27
-
28
- // " at Object.<anonymous> (/app/server.js:42:5)" 패턴
29
- const matchParen = line.match(/\((.+):(\d+):\d+\)/);
30
- if (matchParen) return `${matchParen[1]}:${matchParen[2]}`;
31
-
32
- // " at /app/server.js:42:5" 패턴 (익명 호출)
33
- const matchDirect = line.match(/at (.+):(\d+):\d+/);
34
- if (matchDirect) return `${matchDirect[1]}:${matchDirect[2]}`;
35
-
53
+ for (let i = 1; i < lines.length; i++) {
54
+ const frame = lines[i];
55
+ // 로거/프레임워크 내부 프레임 스킵
56
+ if (SKIP_PATTERNS.some(p => frame.includes(p))) continue;
57
+ return parseFrame(frame);
58
+ }
36
59
  return '';
37
60
  }
38
61
 
62
+ /**
63
+ * 에러/경고 로그의 위치를 결정한다.
64
+ * 1. 인자에 Error 객체가 있으면 → err.stack에서 throw 위치
65
+ * 2. 없으면 → 호출 스택에서 로거 파일을 건너뛴 외부 호출 위치
66
+ *
67
+ * @param {any[]} args
68
+ * @returns {string}
69
+ */
70
+ function resolveLocation(args) {
71
+ return findErrorOrigin(args) || getExternalCallSite();
72
+ }
73
+
39
74
  /**
40
75
  * Rust N-API bridge를 통한 로거 객체를 생성한다.
41
76
  *
42
77
  * @param {object} bridge - fuzionx-bridge N-API 모듈
43
78
  * @returns {{ info: Function, warn: Function, error: Function, debug: Function }}
44
- *
45
- * @example
46
- * const logger = createLogger(bridge);
47
- * logger.info('서버 시작');
48
- * logger.error('DB 연결 실패'); // → [server.js:42] DB 연결 실패
49
79
  */
50
80
  export function createLogger(bridge) {
51
81
  return {
52
- /**
53
- * INFO 레벨 로그.
54
- * @param {...any} args - 로그 메시지 (util.format 지원)
55
- */
56
82
  info(...args) {
57
83
  bridge.logInfo('app', format(...args));
58
84
  },
59
85
 
60
- /**
61
- * WARN 레벨 로그 (호출 위치 자동 추출).
62
- * @param {...any} args - 로그 메시지
63
- */
64
86
  warn(...args) {
65
- const location = getCallSite(2); // Error → warn → 호출자
87
+ const location = resolveLocation(args);
66
88
  bridge.logWarn('app', format(...args), location || undefined);
67
89
  },
68
90
 
69
- /**
70
- * ERROR 레벨 로그 (호출 위치 자동 추출).
71
- * @param {...any} args - 로그 메시지
72
- */
73
91
  error(...args) {
74
- const location = getCallSite(2); // Error → error → 호출자
92
+ const location = resolveLocation(args);
75
93
  bridge.logError('app', format(...args), location || undefined);
76
94
  },
77
95
 
78
- /**
79
- * DEBUG 레벨 로그.
80
- * @param {...any} args - 로그 메시지
81
- */
82
96
  debug(...args) {
83
97
  bridge.logDebug('app', format(...args));
84
98
  },
@@ -90,14 +104,8 @@ export function createLogger(bridge) {
90
104
  *
91
105
  * @param {object} bridge - fuzionx-bridge N-API 모듈
92
106
  * @returns {Function} 원래 console을 복원하는 함수
93
- *
94
- * @example
95
- * const restore = interceptConsole(bridge);
96
- * console.log('hello'); // → tracing::info [console] hello
97
- * restore(); // 원래 console 복원
98
107
  */
99
108
  export function interceptConsole(bridge) {
100
- // 원본 보존
101
109
  const orig = {
102
110
  log: console.log,
103
111
  info: console.info,
@@ -115,12 +123,12 @@ export function interceptConsole(bridge) {
115
123
  };
116
124
 
117
125
  console.warn = (...args) => {
118
- const location = getCallSite(2);
126
+ const location = resolveLocation(args);
119
127
  bridge.logWarn('console', format(...args), location || undefined);
120
128
  };
121
129
 
122
130
  console.error = (...args) => {
123
- const location = getCallSite(2);
131
+ const location = resolveLocation(args);
124
132
  bridge.logError('console', format(...args), location || undefined);
125
133
  };
126
134
 
@@ -128,9 +136,6 @@ export function interceptConsole(bridge) {
128
136
  bridge.logDebug('console', format(...args));
129
137
  };
130
138
 
131
- /**
132
- * 원래 console 함수를 복원한다.
133
- */
134
139
  return function restoreConsole() {
135
140
  console.log = orig.log;
136
141
  console.info = orig.info;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzionx/core",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "type": "module",
5
5
  "description": "Express-style Node.js framework powered by FuzionX native bridge — 167K RPS single process",
6
6
  "main": "index.js",
@@ -18,7 +18,7 @@
18
18
  "url": "https://github.com/saytohenry/fuzionx"
19
19
  },
20
20
  "dependencies": {
21
- "@fuzionx/bridge": "^0.1.28"
21
+ "@fuzionx/bridge": "^0.1.30"
22
22
  },
23
23
  "files": [
24
24
  "index.js",