kb-server 0.0.6 → 0.0.8

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.
@@ -23,11 +23,11 @@ const packAPI = (apis, options) => {
23
23
  const ctx = {
24
24
  RequestId: requestId,
25
25
  };
26
+ // API 解析 - 将Action定义移到try块外部,以便在catch块中也能访问
27
+ const { Action, ...params } = req.body || {};
26
28
  try {
27
- // API 解析
28
- const { Action, ...params } = req.body || {};
29
29
  if (log) {
30
- logger_1.logger.info(`请求入参:${JSON.stringify(req.body)} - RequestId: ${requestId}`);
30
+ logger_1.logger.info({ requestId, action: Action, params }, "请求入参");
31
31
  }
32
32
  // 接口未定义
33
33
  if (!Action) {
@@ -63,12 +63,11 @@ const packAPI = (apis, options) => {
63
63
  };
64
64
  // 完成响应
65
65
  took = Date.now() - start;
66
- logger_1.logger.info(`响应:${JSON.stringify(response)}`);
67
- logger_1.logger.info(`耗时:${took} ms - RequestId: ${requestId}`);
66
+ logger_1.logger.info({ requestId, action: Action, response, took }, "请求响应");
68
67
  return res.send(response);
69
68
  }
70
69
  catch (rawError) {
71
- logger_1.logger.error(rawError);
70
+ logger_1.logger.error({ requestId, action: Action, error: rawError }, "请求处理异常");
72
71
  // 未知错误
73
72
  let error = new create_errors_1.CommonErrors.InternalError.UnknownError();
74
73
  // 可控错误
@@ -90,8 +89,7 @@ const packAPI = (apis, options) => {
90
89
  };
91
90
  // 完成响应
92
91
  took = Date.now() - start;
93
- logger_1.logger.info(`响应:${JSON.stringify(response)}`);
94
- logger_1.logger.info(`耗时:${took} ms - RequestId: ${requestId}`);
92
+ logger_1.logger.info({ requestId, action: Action, response, took }, "请求响应");
95
93
  return res.send(response);
96
94
  }
97
95
  };
@@ -33,11 +33,11 @@ const packSSE = (sseHandlers, options) => {
33
33
  const ctx = {
34
34
  RequestId: requestId,
35
35
  };
36
+ // API 解析 - 将Action定义移到try块外部,以便在catch块中也能访问
37
+ const { Action, ...params } = req.body || {};
36
38
  try {
37
- // API 解析
38
- const { Action, ...params } = req.body || {};
39
39
  if (log) {
40
- logger_1.logger.info(`请求入参:${JSON.stringify(req.body)} - RequestId: ${requestId}`);
40
+ logger_1.logger.info({ requestId, action: Action, params }, "SSE请求入参");
41
41
  }
42
42
  // 接口未定义
43
43
  if (!Action) {
@@ -73,7 +73,7 @@ const packSSE = (sseHandlers, options) => {
73
73
  abortController.abort();
74
74
  // 完成响应
75
75
  took = Date.now() - start;
76
- logger_1.logger.info(`耗时:${took} ms - ${requestId}`);
76
+ logger_1.logger.info({ requestId, action: Action, took }, "SSE连接关闭");
77
77
  return res.end();
78
78
  });
79
79
  // 写头
@@ -87,14 +87,14 @@ const packSSE = (sseHandlers, options) => {
87
87
  if (timeoutId)
88
88
  clearTimeout(timeoutId);
89
89
  timeoutId = setTimeout(() => {
90
- logger_1.logger.info(`超时自动关闭:${requestId}`);
90
+ logger_1.logger.info({ requestId, action: Action }, "SSE超时自动关闭");
91
91
  close();
92
92
  }, timeout);
93
93
  };
94
94
  // 推送消息
95
95
  const push = (data) => {
96
96
  if (!isConnected) {
97
- logger_1.logger.warning(`连接已关闭: ${requestId}`);
97
+ logger_1.logger.warn({ requestId, action: Action }, "SSE连接已关闭");
98
98
  return;
99
99
  }
100
100
  resetTimeout();
@@ -102,11 +102,11 @@ const packSSE = (sseHandlers, options) => {
102
102
  const response = (0, exports.createSSEMsg)("message", msg);
103
103
  try {
104
104
  res.write(response);
105
- logger_1.logger.info(`推送数据: ${response}`);
105
+ logger_1.logger.info({ requestId, action: Action, data, chunk: response }, "SSE推送数据");
106
106
  }
107
107
  catch (error) {
108
108
  if (error.code === "EPIPE" || error.code === "ECONNRESET") {
109
- logger_1.logger.warning(`连接已关闭: ${requestId}`);
109
+ logger_1.logger.warn({ requestId, action: Action, error }, "SSE连接已关闭");
110
110
  isConnected = false;
111
111
  }
112
112
  }
@@ -115,7 +115,7 @@ const packSSE = (sseHandlers, options) => {
115
115
  const close = () => {
116
116
  if (!isConnected)
117
117
  return;
118
- logger_1.logger.info(`主动关闭连接: ${requestId}`);
118
+ logger_1.logger.info({ requestId, action: Action }, "SSE主动关闭连接");
119
119
  const response = (0, exports.createSSEMsg)("done", "[DONE]");
120
120
  res.write(response, () => res.end());
121
121
  };
@@ -130,7 +130,7 @@ const packSSE = (sseHandlers, options) => {
130
130
  }
131
131
  }
132
132
  catch (rawError) {
133
- logger_1.logger.error(rawError);
133
+ logger_1.logger.error({ requestId, action: Action, error: rawError }, "SSE请求处理异常");
134
134
  if (!res.headersSent) {
135
135
  // 写头
136
136
  res.writeHead(200, {
@@ -156,7 +156,7 @@ const packSSE = (sseHandlers, options) => {
156
156
  },
157
157
  };
158
158
  const response = (0, exports.createSSEMsg)("error", JSON.stringify(errResponse));
159
- logger_1.logger.info(`发送消息:\n${response}`);
159
+ logger_1.logger.info({ requestId, action: Action, response: errResponse }, "SSE错误响应");
160
160
  res.write(response, () => res.end());
161
161
  }
162
162
  };
@@ -1,5 +1,2 @@
1
- export declare const logger: {
2
- info: (message: unknown) => void;
3
- error: (message: unknown) => void;
4
- warning: (message: unknown) => void;
5
- };
1
+ import pino from "pino";
2
+ export declare const logger: pino.Logger<never, boolean>;
@@ -4,17 +4,35 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.logger = void 0;
7
+ const pino_1 = __importDefault(require("pino"));
7
8
  const dayjs_1 = __importDefault(require("dayjs"));
8
- const log = (level, message) => {
9
- const logTime = (0, dayjs_1.default)().format(`YYYY-MM-DD HH:mm:ss`);
10
- if (typeof message === "string") {
11
- console.log(`[${level}] - [${logTime}] - ${message}`);
12
- }
13
- else {
14
- console.log(`[${level}] - [${logTime}] - `, message);
15
- }
16
- };
17
- const info = (message) => log("info", message);
18
- const error = (message) => log("error", message);
19
- const warning = (message) => log("warning", message);
20
- exports.logger = { info, error, warning };
9
+ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
10
+ const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
11
+ // 扩展dayjs插件
12
+ dayjs_1.default.extend(utc_1.default);
13
+ dayjs_1.default.extend(timezone_1.default);
14
+ // 创建基础logger
15
+ exports.logger = (0, pino_1.default)({
16
+ level: process.env.LOG_LEVEL || "info",
17
+ // 使用dayjs获取东八区时间(北京时间)
18
+ timestamp: () => `,"time":"${(0, dayjs_1.default)()
19
+ .tz("Asia/Shanghai")
20
+ .toISOString()}","timezone":"Asia/Shanghai","formatTime":"${(0, dayjs_1.default)()
21
+ .tz("Asia/Shanghai")
22
+ .format("YYYY-MM-DD HH:mm:ss")}"`,
23
+ transport: process.env.NODE_ENV !== "production"
24
+ ? {
25
+ target: "pino-pretty",
26
+ options: {
27
+ colorize: true,
28
+ // 保持原始的ISO时间戳格式,不转换
29
+ translateTime: false,
30
+ // 简单的消息格式
31
+ messageFormat: "{msg}",
32
+ ignore: "pid,hostname",
33
+ // 添加同步选项确保顺序
34
+ sync: true,
35
+ },
36
+ }
37
+ : undefined,
38
+ });
package/dist/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export { createErrors } from "./common/create-errors";
3
3
  export { implementAPI, ServerContext } from "./common/create-api";
4
4
  export { implementSseAPI } from "./common/create-sse";
5
5
  export { callService } from "./common/call-service";
6
+ export { logger } from "./helper/logger";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.callService = exports.implementSseAPI = exports.implementAPI = exports.createErrors = exports.createServer = void 0;
3
+ exports.logger = exports.callService = exports.implementSseAPI = exports.implementAPI = exports.createErrors = exports.createServer = void 0;
4
4
  var create_server_1 = require("./common/create-server");
5
5
  Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return create_server_1.createServer; } });
6
6
  var create_errors_1 = require("./common/create-errors");
@@ -11,3 +11,5 @@ var create_sse_1 = require("./common/create-sse");
11
11
  Object.defineProperty(exports, "implementSseAPI", { enumerable: true, get: function () { return create_sse_1.implementSseAPI; } });
12
12
  var call_service_1 = require("./common/call-service");
13
13
  Object.defineProperty(exports, "callService", { enumerable: true, get: function () { return call_service_1.callService; } });
14
+ var logger_1 = require("./helper/logger");
15
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * 基础日志功能测试
5
+ * 运行方式: npx tsx src/tests/logger/basic.test.ts
6
+ */
7
+ const logger_1 = require("../../helper/logger");
8
+ console.log('=== 基础日志功能测试 ===\n');
9
+ // 测试不同级别的日志
10
+ logger_1.logger.info('这是一条信息日志');
11
+ logger_1.logger.warn('这是一条警告日志');
12
+ logger_1.logger.error('这是一条错误日志');
13
+ logger_1.logger.debug('这是一条调试日志(默认级别下不会显示)');
14
+ logger_1.logger.trace('这是一条跟踪日志(默认级别下不会显示)');
15
+ // 测试直接调用方法
16
+ logger_1.logger.fatal('这是一条致命错误日志');
17
+ console.log('\n基础日志测试完成');
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 运行所有日志测试
3
+ * 运行方式: npx tsx src/tests/logger/run-all.ts
4
+ */
5
+ export {};
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * 运行所有日志测试
4
+ * 运行方式: npx tsx src/tests/logger/run-all.ts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const child_process_1 = require("child_process");
8
+ const fs_1 = require("fs");
9
+ console.log('=== 运行所有日志测试 ===\n');
10
+ const testFiles = [
11
+ 'src/tests/logger/basic.test.ts',
12
+ 'src/tests/logger/structured.test.ts',
13
+ 'src/tests/logger/timezone.test.ts'
14
+ ];
15
+ let failedTests = 0;
16
+ for (const testFile of testFiles) {
17
+ if (!(0, fs_1.existsSync)(testFile)) {
18
+ console.log(`❌ 跳过不存在的测试文件: ${testFile}`);
19
+ failedTests++;
20
+ continue;
21
+ }
22
+ try {
23
+ console.log(`\n🔄 运行测试: ${testFile}`);
24
+ console.log('---');
25
+ (0, child_process_1.execSync)(`npx tsx ${testFile}`, { stdio: 'inherit' });
26
+ console.log('✅ 测试通过');
27
+ }
28
+ catch (error) {
29
+ console.log('❌ 测试失败');
30
+ failedTests++;
31
+ }
32
+ }
33
+ console.log('\n=== 测试总结 ===');
34
+ if (failedTests === 0) {
35
+ console.log('🎉 所有测试都已通过!');
36
+ }
37
+ else {
38
+ console.log(`⚠️ 有 ${failedTests} 个测试失败`);
39
+ }
40
+ // 测试不同环境变量配置
41
+ console.log('\n=== 测试不同环境变量配置 ===');
42
+ console.log('\n📝 测试美化输出 (USE_PRETTY_LOGS=true):');
43
+ try {
44
+ console.log('---');
45
+ (0, child_process_1.execSync)('USE_PRETTY_LOGS=true npx tsx src/tests/logger/basic.test.ts', { stdio: 'inherit' });
46
+ console.log('✅ 美化输出测试通过');
47
+ }
48
+ catch (error) {
49
+ console.log('❌ 美化输出测试失败');
50
+ }
51
+ console.log('\n📝 测试调试级别 (LOG_LEVEL=debug):');
52
+ try {
53
+ console.log('---');
54
+ (0, child_process_1.execSync)('LOG_LEVEL=debug npx tsx src/tests/logger/basic.test.ts', { stdio: 'inherit' });
55
+ console.log('✅ 调试级别测试通过');
56
+ }
57
+ catch (error) {
58
+ console.log('❌ 调试级别测试失败');
59
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ /**
7
+ * 结构化日志测试
8
+ * 运行方式: npx tsx src/tests/logger/structured.test.ts
9
+ */
10
+ const logger_1 = require("../../helper/logger");
11
+ const dayjs_1 = __importDefault(require("dayjs"));
12
+ console.log("=== 结构化日志测试 ===\n");
13
+ // 测试对象日志
14
+ logger_1.logger.info({
15
+ user: "张三",
16
+ action: "登录",
17
+ ip: "192.168.1.1",
18
+ timestamp: (0, dayjs_1.default)().format("YYYY-MM-DD HH:mm:ss"),
19
+ });
20
+ // 测试错误对象日志
21
+ logger_1.logger.error({
22
+ error: "数据库连接失败",
23
+ code: "DB_ERROR",
24
+ retryCount: 3,
25
+ lastError: "Connection timeout after 5000ms",
26
+ stack: "Error: Connection timeout\n at Object.connect (db.js:42:15)",
27
+ });
28
+ // 测试复杂对象日志
29
+ logger_1.logger.info({
30
+ event: "API请求",
31
+ request: {
32
+ id: "req-123456",
33
+ method: "POST",
34
+ url: "/api/users",
35
+ headers: {
36
+ "content-type": "application/json",
37
+ authorization: "Bearer ***",
38
+ },
39
+ body: {
40
+ name: "李四",
41
+ email: "lisi@example.com",
42
+ },
43
+ },
44
+ response: {
45
+ status: 201,
46
+ time: 125,
47
+ data: {
48
+ id: "user-789",
49
+ name: "李四",
50
+ email: "lisi@example.com",
51
+ createdAt: (0, dayjs_1.default)().toISOString(),
52
+ },
53
+ },
54
+ });
55
+ console.log("\n结构化日志测试完成");
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ /**
7
+ * 时区测试
8
+ * 运行方式: npx tsx src/tests/logger/timezone.test.ts
9
+ */
10
+ const logger_1 = require("../../helper/logger");
11
+ const dayjs_1 = __importDefault(require("dayjs"));
12
+ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
13
+ const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
14
+ // 扩展dayjs插件
15
+ dayjs_1.default.extend(utc_1.default);
16
+ dayjs_1.default.extend(timezone_1.default);
17
+ console.log('=== 时区测试 ===\n');
18
+ // 显示当前时间对比
19
+ console.log('UTC时间:', (0, dayjs_1.default)().utc().format());
20
+ console.log('东八区时间:', (0, dayjs_1.default)().tz('Asia/Shanghai').format());
21
+ console.log('本地时间:', (0, dayjs_1.default)().format());
22
+ console.log();
23
+ // 测试日志时间戳
24
+ logger_1.logger.info('这条日志应该包含东八区时间戳');
25
+ // 测试业务日志中的时间
26
+ logger_1.logger.info({
27
+ event: '用户操作',
28
+ user: '张三',
29
+ action: '下单',
30
+ // 使用dayjs记录东八区时间
31
+ beijingTime: (0, dayjs_1.default)().tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss'),
32
+ utcTime: (0, dayjs_1.default)().utc().format(),
33
+ orderInfo: {
34
+ id: 'ORDER-123456',
35
+ amount: 299.00,
36
+ items: ['商品A', '商品B']
37
+ }
38
+ });
39
+ // 测试跨时区场景
40
+ logger_1.logger.warn({
41
+ msg: '服务器时区警告',
42
+ serverTimezone: dayjs_1.default.tz.guess(),
43
+ serverTime: (0, dayjs_1.default)().format('YYYY-MM-DD HH:mm:ss Z'),
44
+ beijingTime: (0, dayjs_1.default)().tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss Z'),
45
+ utcTime: (0, dayjs_1.default)().utc().format()
46
+ });
47
+ console.log('\n时区测试完成');
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "kb-server",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "A fast server for Node.JS,made by express.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "build": "rm -rf ./dist && tsc",
8
- "release": "npm run build && npm publish"
8
+ "release": "npm run build && npm version patch && npm publish"
9
9
  },
10
10
  "keywords": [
11
11
  "2kb",
@@ -29,9 +29,18 @@
29
29
  "express": "^4.21.1",
30
30
  "is-plain-object": "^5.0.0",
31
31
  "nanoid": "^3.3.9",
32
+ "pino": "^10.1.0",
32
33
  "utility-types": "^3.11.0",
33
34
  "uuid": "^11.0.3"
34
35
  },
36
+ "peerDependencies": {
37
+ "pino-pretty": "^13.1.3"
38
+ },
39
+ "peerDependenciesMeta": {
40
+ "pino-pretty": {
41
+ "optional": true
42
+ }
43
+ },
35
44
  "devDependencies": {
36
45
  "@types/express": "^4.17.21"
37
46
  }