@qubit-ltd/logging 1.4.4 → 1.4.6

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/README.zh_CN.md CHANGED
@@ -9,6 +9,16 @@
9
9
  [@qubit-ltd/logging] 是一个 JavaScript 库,通过装饰器为类方法和属性提供强大的日志记录功能。
10
10
  该库旨在与[Vue.js 类组件]无缝集成,为处理 JavaScript 项目中的日志记录提供了优雅的解决方案。
11
11
 
12
+ ## 特性
13
+
14
+ - 📝 简单灵活的日志接口,支持不同的日志级别
15
+ - 🔍 支持带占位符的格式化日志消息
16
+ - 🎯 自动方法日志记录和类日志集成的装饰器
17
+ - 🔄 与Vue.js类组件无缝集成
18
+ - 🎛️ 可配置的日志级别和输出器
19
+ - 🌐 全局和单独的日志记录器管理
20
+ - 📋 支持浏览器控制台和自定义输出器
21
+
12
22
  ## 安装
13
23
 
14
24
  使用 npm 或 yarn 安装该库:
@@ -34,6 +44,28 @@ yarn add @qubit-ltd/logging
34
44
  - `level: string`:定义日志记录级别(`TRACE`、`DEBUG`、`INFO`、`WARN`、`ERROR`、`NONE`)。不区分大小写。
35
45
  如果省略,将使用 logger 的现有日志级别,或者为新创建的 logger 分配默认日志级别。
36
46
 
47
+ 示例:
48
+
49
+ ```javascript
50
+ import Logger from '@qubit-ltd/logging';
51
+
52
+ // 创建一个使用默认设置的logger
53
+ const logger1 = Logger.getLogger('MyLogger');
54
+
55
+ // 创建一个自定义日志级别的logger
56
+ const logger2 = Logger.getLogger('DebugLogger', { level: 'DEBUG' });
57
+
58
+ // 创建一个带自定义输出器的logger
59
+ const customAppender = {
60
+ trace: (message, ...args) => { /* 自定义trace实现 */ },
61
+ debug: (message, ...args) => { /* 自定义debug实现 */ },
62
+ info: (message, ...args) => { /* 自定义info实现 */ },
63
+ warn: (message, ...args) => { /* 自定义warn实现 */ },
64
+ error: (message, ...args) => { /* 自定义error实现 */ },
65
+ };
66
+ const logger3 = Logger.getLogger('CustomLogger', { appender: customAppender, level: 'INFO' });
67
+ ```
68
+
37
69
  ### 记录日志消息
38
70
 
39
71
  - `logger.trace(message, ...args)`:记录一个 trace 级别的消息。
@@ -70,7 +102,33 @@ logger.log(level, 'This is an %s message with argument %s and argument %o', leve
70
102
 
71
103
  使用 `logger.setLevel(level)` 调整 logger 的日志级别。
72
104
 
73
- 可用的日志级别有:`TRACE`、`DEBUG`、`INFO`、`WARN`、`ERROR`、`NONE`(不区分大小写)。
105
+ 可用的日志级别(从最详细到最简略):
106
+ - `TRACE`:用于调试目的的最详细信息
107
+ - `DEBUG`:一般调试信息
108
+ - `INFO`:关于应用程序进度的一般信息
109
+ - `WARN`:可能需要注意的警告情况
110
+ - `ERROR`:需要处理的错误条件
111
+ - `NONE`:完全禁用日志记录
112
+
113
+ 所有级别名称不区分大小写。
114
+
115
+ 示例:
116
+
117
+ ```javascript
118
+ const logger = Logger.getLogger('MyClass');
119
+
120
+ // 将级别更改为只显示警告和错误
121
+ logger.setLevel('WARN');
122
+
123
+ // 这些不会显示,因为它们低于WARN级别
124
+ logger.trace('这条跟踪消息不会显示');
125
+ logger.debug('这条调试消息不会显示');
126
+ logger.info('这条信息消息不会显示');
127
+
128
+ // 这些会显示
129
+ logger.warn('这条警告消息会显示');
130
+ logger.error('这条错误消息会显示');
131
+ ```
74
132
 
75
133
  ### 设置日志 Appender
76
134
 
@@ -85,7 +143,17 @@ logger.log(level, 'This is an %s message with argument %s and argument %o', leve
85
143
 
86
144
  ```javascript
87
145
  const logger = Logger.getLogger('MyClass');
88
- logger.setAppender(console); // Outputs log messages to the console.
146
+ logger.setAppender(console); // 将日志消息输出到控制台
147
+
148
+ // 或者创建一个为所有日志添加时间戳的自定义输出器
149
+ const timestampAppender = {
150
+ trace: (message, ...args) => console.trace(`[${new Date().toISOString()}] ${message}`, ...args),
151
+ debug: (message, ...args) => console.debug(`[${new Date().toISOString()}] ${message}`, ...args),
152
+ info: (message, ...args) => console.info(`[${new Date().toISOString()}] ${message}`, ...args),
153
+ warn: (message, ...args) => console.warn(`[${new Date().toISOString()}] ${message}`, ...args),
154
+ error: (message, ...args) => console.error(`[${new Date().toISOString()}] ${message}`, ...args),
155
+ };
156
+ logger.setAppender(timestampAppender);
89
157
  ```
90
158
 
91
159
  ### 启用或禁用日志记录
@@ -94,12 +162,50 @@ logger.setAppender(console); // Outputs log messages to the console.
94
162
  - `logger.disable()`:禁用日志记录。
95
163
  - `logger.setEnabled(enabled)`:动态控制日志记录的启用与禁用。
96
164
 
165
+ 示例:
166
+
167
+ ```javascript
168
+ const logger = Logger.getLogger('MyClass');
169
+
170
+ // 暂时禁用所有日志
171
+ logger.disable();
172
+ logger.info('此消息不会被记录');
173
+
174
+ // 重新启用日志
175
+ logger.enable();
176
+ logger.info('此消息会被记录');
177
+
178
+ // 使用条件控制日志记录
179
+ const debugMode = process.env.NODE_ENV === 'development';
180
+ logger.setEnabled(debugMode);
181
+ ```
182
+
97
183
  ### 管理日志记录器
98
184
 
99
185
  - `Logger.clearAllLoggers()`:清除所有已注册的日志记录器。
100
186
  - `Logger.getLevel(name)`:获取特定日志记录器的日志级别。
101
187
  - `Logger.setLevel(name, level)`:设置特定日志记录器的日志级别。
102
188
 
189
+ 示例:
190
+
191
+ ```javascript
192
+ // 创建多个日志记录器
193
+ const apiLogger = Logger.getLogger('API');
194
+ const uiLogger = Logger.getLogger('UI');
195
+ const dbLogger = Logger.getLogger('Database');
196
+
197
+ // 在不访问实例的情况下更改特定日志记录器的级别
198
+ Logger.setLevel('API', 'DEBUG');
199
+ Logger.setLevel('Database', 'ERROR');
200
+
201
+ // 获取日志记录器的当前级别
202
+ const uiLevel = Logger.getLevel('UI');
203
+ console.log(`UI Logger级别: ${uiLevel}`);
204
+
205
+ // 关闭应用程序时清除所有日志记录器
206
+ Logger.clearAllLoggers();
207
+ ```
208
+
103
209
  ### 默认级别和 Appender
104
210
 
105
211
  当创建一个新日志记录器时,如果没有指定级别或 appender,将使用默认的日志级别和 appender。
@@ -111,6 +217,23 @@ logger.setAppender(console); // Outputs log messages to the console.
111
217
  - `Logger.setDefaultAppender(appender)`:设置默认日志 appender。
112
218
  - `Logger.resetDefaultAppender()`:将默认日志 appender 重置为出厂值。
113
219
 
220
+ 示例:
221
+
222
+ ```javascript
223
+ // 获取当前默认级别
224
+ const defaultLevel = Logger.getDefaultLevel();
225
+ console.log(`默认日志级别: ${defaultLevel}`);
226
+
227
+ // 为所有新的日志记录器更改默认级别
228
+ Logger.setDefaultLevel('DEBUG');
229
+
230
+ // 所有新的日志记录器现在默认将具有DEBUG级别
231
+ const logger = Logger.getLogger('NewLogger'); // 将具有DEBUG级别
232
+
233
+ // 重置为原始的工厂默认级别
234
+ Logger.resetDefaultLevel();
235
+ ```
236
+
114
237
  ### 全局日志管理
115
238
 
116
239
  - `Logger.setAllLevels(level)`:将指定日志级别应用于所有现有日志记录器。
@@ -118,10 +241,42 @@ logger.setAppender(console); // Outputs log messages to the console.
118
241
  - `Logger.setAllAppenders(appender)`:将指定日志 appender 应用于所有现有日志记录器。
119
242
  - `Logger.resetAllAppenders()`:将所有现有日志记录器的日志 appender 重置为默认 appender。
120
243
 
244
+ 示例:
245
+
246
+ ```javascript
247
+ // 创建几个具有不同级别的日志记录器
248
+ const logger1 = Logger.getLogger('Logger1', { level: 'TRACE' });
249
+ const logger2 = Logger.getLogger('Logger2', { level: 'INFO' });
250
+ const logger3 = Logger.getLogger('Logger3', { level: 'ERROR' });
251
+
252
+ // 一次将所有日志记录器更改为WARN级别
253
+ Logger.setAllLevels('WARN');
254
+
255
+ // 现在所有日志记录器将只显示WARN和ERROR消息
256
+ logger1.info('这不会显示');
257
+ logger2.warn('这会显示');
258
+ logger3.error('这会显示');
259
+
260
+ // 将所有日志记录器重置为使用默认级别
261
+ Logger.resetAllLevels();
262
+
263
+ // 将自定义输出器应用于所有现有的日志记录器
264
+ const fileAppender = { /* ... 记录到文件的实现 ... */ };
265
+ Logger.setAllAppenders(fileAppender);
266
+ ```
267
+
121
268
  ### 重置日志记录器
122
269
 
123
270
  - `Logger.reset()`:将日志记录器重置为出厂状态。这将清除所有已注册的日志记录器、重置默认日志级别和默认日志 appender。
124
271
 
272
+ 示例:
273
+
274
+ ```javascript
275
+ // 在对日志记录器和默认设置进行多次修改后
276
+ // 这一个调用将一切重置为工厂设置
277
+ Logger.reset();
278
+ ```
279
+
125
280
  ## `@Log` 装饰器
126
281
 
127
282
  `@Log` 装饰器会自动记录方法签名,包括类名、方法名和参数。
@@ -134,13 +289,25 @@ import { Log } from '@qubit-ltd/logging';
134
289
  class Person {
135
290
  @Log
136
291
  eat(meal) {
137
- // method implementation
292
+ // 方法实现
293
+ return `正在吃${meal.name}`;
294
+ }
295
+
296
+ // Log装饰器的自定义选项
297
+ @Log({ level: 'INFO', withResult: true })
298
+ calculateCalories(food, amount) {
299
+ const calories = food.caloriesPerUnit * amount;
300
+ return calories;
138
301
  }
139
302
  }
140
303
 
141
304
  const person = new Person();
142
- const meal = new Meal();
143
- person.eat(meal); // The log will print the method calling signature
305
+ const meal = { name: '早餐', type: '健康' };
306
+ person.eat(meal);
307
+ // 记录: "Person.eat({"name":"早餐","type":"健康"})"
308
+
309
+ const calories = person.calculateCalories({ caloriesPerUnit: 50 }, 4);
310
+ // 记录: "Person.calculateCalories({"caloriesPerUnit":50}, 4) => 200"
144
311
  ```
145
312
 
146
313
  ## `@HasLogger` 装饰器
@@ -155,9 +322,22 @@ import { HasLogger } from '@qubit-ltd/logging';
155
322
  @HasLogger
156
323
  class MyClass {
157
324
  foo() {
158
- this.logger.debug('This is MyClass.foo()');
325
+ this.logger.debug('这是MyClass.foo()');
326
+ }
327
+
328
+ bar(param) {
329
+ this.logger.info('使用参数处理: %o', param);
330
+ // 使用param做一些事情
331
+ if (param.value < 0) {
332
+ this.logger.warn('检测到负值: %d', param.value);
333
+ }
334
+ return param.value * 2;
159
335
  }
160
336
  }
337
+
338
+ const instance = new MyClass();
339
+ instance.foo();
340
+ instance.bar({ value: -5 });
161
341
  ```
162
342
 
163
343
  ## 与 Vue.js 类组件一起使用
@@ -178,7 +358,22 @@ class MyComponent {
178
358
 
179
359
  @Log
180
360
  foo() {
181
- this.logger.debug('This is MyComponent.foo()');
361
+ this.logger.debug('这是MyComponent.foo()');
362
+ this.message = '点击于 ' + new Date().toLocaleTimeString();
363
+ }
364
+
365
+ @Log({ level: 'INFO' })
366
+ async fetchData() {
367
+ try {
368
+ this.logger.info('从API获取数据...');
369
+ const response = await fetch('/api/data');
370
+ const data = await response.json();
371
+ this.logger.info('接收到数据: %o', data);
372
+ return data;
373
+ } catch (error) {
374
+ this.logger.error('获取数据失败: %o', error);
375
+ throw error;
376
+ }
182
377
  }
183
378
  }
184
379
 
@@ -187,10 +382,76 @@ export default toVue(MyComponent);
187
382
 
188
383
  **注意**:`@HasLogger` 装饰器必须放在 `@Component` 装饰器的**后面**。
189
384
 
385
+ ## 高级用法
386
+
387
+ ### 创建自定义输出器
388
+
389
+ 你可以创建自定义输出器将日志定向到不同的目的地:
390
+
391
+ ```javascript
392
+ // 文件日志输出器(Node.js示例)
393
+ import fs from 'fs';
394
+
395
+ const fileAppender = {
396
+ _writeToFile(level, message, ...args) {
397
+ const formattedArgs = args.map(arg =>
398
+ typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
399
+ );
400
+ const logEntry = `[${new Date().toISOString()}] [${level}] ${message} ${formattedArgs.join(' ')}\n`;
401
+ fs.appendFileSync('application.log', logEntry);
402
+ },
403
+ trace: function(message, ...args) { this._writeToFile('TRACE', message, ...args); },
404
+ debug: function(message, ...args) { this._writeToFile('DEBUG', message, ...args); },
405
+ info: function(message, ...args) { this._writeToFile('INFO', message, ...args); },
406
+ warn: function(message, ...args) { this._writeToFile('WARN', message, ...args); },
407
+ error: function(message, ...args) { this._writeToFile('ERROR', message, ...args); }
408
+ };
409
+
410
+ // 使用自定义输出器
411
+ const logger = Logger.getLogger('AppLogger', { appender: fileAppender });
412
+ ```
413
+
414
+ ### 条件日志记录
415
+
416
+ ```javascript
417
+ import Logger from '@qubit-ltd/logging';
418
+
419
+ function processData(data, options = {}) {
420
+ const logger = Logger.getLogger('DataProcessor');
421
+
422
+ // 仅在明确请求时启用调试日志
423
+ if (options.debug) {
424
+ logger.setLevel('DEBUG');
425
+ } else {
426
+ logger.setLevel('INFO');
427
+ }
428
+
429
+ logger.debug('使用选项处理数据: %o', options);
430
+ // 函数的其余部分
431
+ }
432
+ ```
433
+
190
434
  ## <span id="contributing">贡献</span>
191
435
 
192
436
  如果您发现任何问题或有改进建议,请随时在[GitHub 仓库]上提交 issue 或 pull request。
193
437
 
438
+ ### 开发设置
439
+
440
+ ```bash
441
+ # 克隆仓库
442
+ git clone https://github.com/Haixing-Hu/js-logging.git
443
+ cd js-logging
444
+
445
+ # 安装依赖
446
+ yarn install
447
+
448
+ # 运行测试
449
+ yarn test
450
+
451
+ # 构建库
452
+ yarn build
453
+ ```
454
+
194
455
  ## <span id="license">许可证</span>
195
456
 
196
457
  [@qubit-ltd/logging] 根据 Apache 2.0 许可证分发。详情请参阅 [LICENSE](LICENSE) 文件。
package/dist/logging.cjs CHANGED
@@ -35,12 +35,12 @@ function toPropertyKey(t) {
35
35
  function _defineProperties(e, r) {
36
36
  for (var t = 0; t < r.length; t++) {
37
37
  var o = r[t];
38
- o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, toPropertyKey(o.key), o);
38
+ o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, toPropertyKey(o.key), o);
39
39
  }
40
40
  }
41
41
  function _createClass(e, r, t) {
42
- return _defineProperties(e.prototype, r), _defineProperties(e, t), Object.defineProperty(e, "prototype", {
43
- writable: !1
42
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
43
+ writable: false
44
44
  }), e;
45
45
  }
46
46
 
@@ -465,7 +465,7 @@ function bindLoggingMethods(logger, level, appender) {
465
465
  }
466
466
  }
467
467
 
468
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
468
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: true } : { done: false, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = true, u = false; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = true, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
469
469
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
470
470
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
471
471