vafast 0.4.6 → 0.4.19

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 (163) hide show
  1. package/README.md +70 -8
  2. package/dist/base-server-B7MYJNsl.mjs +112 -0
  3. package/dist/{base-server-DMhpmq5v.mjs.map → base-server-B7MYJNsl.mjs.map} +1 -1
  4. package/dist/{base-server-CtA1bZSg.d.mts → base-server-DLxtulAO.d.mts} +2 -2
  5. package/dist/{base64url-DUtluDF0.mjs → base64url-C2zopQdH.mjs} +1 -1
  6. package/dist/{base64url-DUtluDF0.mjs.map → base64url-C2zopQdH.mjs.map} +1 -1
  7. package/dist/{base64url-0N9uQPjZ.d.mts → base64url-Dwi2Afhc.d.mts} +1 -1
  8. package/dist/{component-route-DF5feXJI.d.mts → component-route-nrrO0iSI.d.mts} +2 -2
  9. package/dist/{component-router-uSylkByf.mjs → component-router-RwPL20vN.mjs} +10 -11
  10. package/dist/{component-router-uSylkByf.mjs.map → component-router-RwPL20vN.mjs.map} +1 -1
  11. package/dist/component-server-DomPJ_7S.mjs +119 -0
  12. package/dist/{component-server-DIgykV0F.mjs.map → component-server-DomPJ_7S.mjs.map} +1 -1
  13. package/dist/{component-server-DvcPVnL4.d.mts → component-server-JqpDC7wy.d.mts} +4 -4
  14. package/dist/{create-handler-DRcJRkx9.d.mts → create-handler-DKw-sQOV.d.mts} +2 -2
  15. package/dist/{create-handler-IzOE24L5.mjs → create-handler-RconAcAB.mjs} +5 -6
  16. package/dist/{create-handler-IzOE24L5.mjs.map → create-handler-RconAcAB.mjs.map} +1 -1
  17. package/dist/defineRoute.d.mts +3 -3
  18. package/dist/{dependency-manager-C_qZvkaw.d.mts → dependency-manager-C3_7ic4h.d.mts} +1 -1
  19. package/dist/dependency-manager-DCmh7xFc.mjs +60 -0
  20. package/dist/{dependency-manager-BpN2YufZ.mjs.map → dependency-manager-DCmh7xFc.mjs.map} +1 -1
  21. package/dist/{formats-CYLwo9GJ.d.mts → formats-Dk-DSBY4.d.mts} +1 -1
  22. package/dist/{go-await-2Pzj4snS.mjs → go-await-C4ZdEUwY.mjs} +1 -1
  23. package/dist/{go-await-2Pzj4snS.mjs.map → go-await-C4ZdEUwY.mjs.map} +1 -1
  24. package/dist/{go-await-DRItVwwh.d.mts → go-await-DL1A_-4X.d.mts} +1 -1
  25. package/dist/{handle-D0TFoOiX.d.mts → handle-BhR3oyky.d.mts} +1 -1
  26. package/dist/{handle-s4V-E2RE.mjs → handle-BxJwSvV0.mjs} +2 -2
  27. package/dist/{handle-s4V-E2RE.mjs.map → handle-BxJwSvV0.mjs.map} +1 -1
  28. package/dist/{html-renderer-CMGKJoIy.d.mts → html-renderer-CfKK2BrP.d.mts} +1 -1
  29. package/dist/{html-renderer-CuakkPIt.mjs → html-renderer-DTtJ_Yic.mjs} +26 -27
  30. package/dist/{html-renderer-CuakkPIt.mjs.map → html-renderer-DTtJ_Yic.mjs.map} +1 -1
  31. package/dist/{index-CdOYxwDQ.d.mts → index-CEfOqqvd.d.mts} +5 -5
  32. package/dist/index.d.mts +24 -24
  33. package/dist/index.mjs +20 -23
  34. package/dist/index.mjs.map +1 -1
  35. package/dist/middleware/component-router.d.mts +1 -1
  36. package/dist/middleware/component-router.mjs +1 -2
  37. package/dist/{middleware-CV5o-4wk.mjs → middleware-CewKbtb4.mjs} +51 -58
  38. package/dist/{middleware-CV5o-4wk.mjs.map → middleware-CewKbtb4.mjs.map} +1 -1
  39. package/dist/{middleware-5PjaxPMA.d.mts → middleware-KXEoefLX.d.mts} +2 -2
  40. package/dist/middleware.d.mts +3 -3
  41. package/dist/middleware.mjs +1 -2
  42. package/dist/monitoring/index.d.mts +8 -33
  43. package/dist/monitoring/index.mjs +1 -27
  44. package/dist/monitoring/native-monitor.d.mts +148 -27
  45. package/dist/monitoring/native-monitor.mjs +320 -116
  46. package/dist/monitoring/native-monitor.mjs.map +1 -1
  47. package/dist/node-server/index.d.mts +1 -1
  48. package/dist/node-server/index.mjs +3 -3
  49. package/dist/node-server/request.mjs +1 -1
  50. package/dist/node-server/response.mjs +1 -1
  51. package/dist/node-server/serve.d.mts +1 -1
  52. package/dist/node-server/serve.mjs +2 -2
  53. package/dist/{parsers-7lvt3Oss.d.mts → parsers-BerGr2_q.d.mts} +1 -1
  54. package/dist/{parsers-BQ63b0YE.mjs → parsers-DpH_mD0H.mjs} +1 -1
  55. package/dist/{parsers-BQ63b0YE.mjs.map → parsers-DpH_mD0H.mjs.map} +1 -1
  56. package/dist/path-matcher-CGczAIl_.mjs +61 -0
  57. package/dist/{path-matcher-BNaaJgI3.mjs.map → path-matcher-CGczAIl_.mjs.map} +1 -1
  58. package/dist/radix-tree-qqSjnVXF.mjs +163 -0
  59. package/dist/{radix-tree-Qxr-QpCx.mjs.map → radix-tree-qqSjnVXF.mjs.map} +1 -1
  60. package/dist/{request-B886yCvG.mjs → request-B-Nct5f7.mjs} +1 -1
  61. package/dist/{request-B886yCvG.mjs.map → request-B-Nct5f7.mjs.map} +1 -1
  62. package/dist/{request-validator-DLFtm4uV.mjs → request-validator-Bz9X48FX.mjs} +3 -3
  63. package/dist/{request-validator-DLFtm4uV.mjs.map → request-validator-Bz9X48FX.mjs.map} +1 -1
  64. package/dist/{request-validator-42lY21gn.d.mts → request-validator-Coo8dI-p.d.mts} +2 -2
  65. package/dist/{response-CxYf6Ep3.d.mts → response-BMfdEcTm.d.mts} +2 -2
  66. package/dist/{response-30WnzABq.mjs → response-BnkYA4pj.mjs} +1 -1
  67. package/dist/{response-30WnzABq.mjs.map → response-BnkYA4pj.mjs.map} +1 -1
  68. package/dist/{route-CUbNpSwz.d.mts → route-6A7umH7b.d.mts} +2 -2
  69. package/dist/{route-B3ONOzxQ.mjs → route-Ds53PR4M.mjs} +1 -1
  70. package/dist/{route-B3ONOzxQ.mjs.map → route-Ds53PR4M.mjs.map} +1 -1
  71. package/dist/{route-registry-CYD7m6QP.d.mts → route-registry-CmABJA2V.d.mts} +2 -2
  72. package/dist/route-registry-emTmRrWQ.mjs +226 -0
  73. package/dist/{route-registry-BVvbghgH.mjs.map → route-registry-emTmRrWQ.mjs.map} +1 -1
  74. package/dist/router/index.d.mts +2 -2
  75. package/dist/router/index.mjs +3 -9
  76. package/dist/router/radix-tree.d.mts +3 -3
  77. package/dist/router/radix-tree.mjs +1 -2
  78. package/dist/{router-B9HUUCkR.mjs → router-xWzwz_1a.mjs} +2 -5
  79. package/dist/{router-B9HUUCkR.mjs.map → router-xWzwz_1a.mjs.map} +1 -1
  80. package/dist/router.d.mts +3 -3
  81. package/dist/router.mjs +1 -2
  82. package/dist/{schema-DOKg31ZX.d.mts → schema-B6DFN5c2.d.mts} +1 -1
  83. package/dist/{serve-DgWBnexE.mjs → serve-48LEIkPa.mjs} +3 -3
  84. package/dist/{serve-DgWBnexE.mjs.map → serve-48LEIkPa.mjs.map} +1 -1
  85. package/dist/{serve-B5WmhK6m.d.mts → serve-AG80VaIr.d.mts} +1 -1
  86. package/dist/serve.d.mts +1 -1
  87. package/dist/serve.mjs +2 -2
  88. package/dist/server/base-server.d.mts +3 -3
  89. package/dist/server/base-server.mjs +1 -2
  90. package/dist/server/component-server.d.mts +4 -4
  91. package/dist/server/component-server.mjs +2 -3
  92. package/dist/server/index.d.mts +6 -6
  93. package/dist/server/index.mjs +6 -7
  94. package/dist/server/server-factory.d.mts +6 -6
  95. package/dist/server/server-factory.mjs +5 -6
  96. package/dist/server/server.d.mts +4 -4
  97. package/dist/server/server.mjs +2 -3
  98. package/dist/server-C75o1b-a.mjs +70 -0
  99. package/dist/server-C75o1b-a.mjs.map +1 -0
  100. package/dist/{server-CWIZP6nb.d.mts → server-DGA3dd5s.d.mts} +3 -3
  101. package/dist/server-L_FNwdap.mjs +137 -0
  102. package/dist/{server-C3yoZXNs.mjs.map → server-L_FNwdap.mjs.map} +1 -1
  103. package/dist/{sse-BDIptC85.d.mts → sse-BgLhEo43.d.mts} +2 -2
  104. package/dist/{sse-CCVfFW6s.mjs → sse-CBl-szg1.mjs} +3 -3
  105. package/dist/{sse-CCVfFW6s.mjs.map → sse-CBl-szg1.mjs.map} +1 -1
  106. package/dist/types/component-route.d.mts +1 -1
  107. package/dist/types/index.d.mts +5 -5
  108. package/dist/types/index.mjs +1 -1
  109. package/dist/types/route.d.mts +1 -1
  110. package/dist/types/route.mjs +1 -1
  111. package/dist/types/schema.d.mts +1 -1
  112. package/dist/types/types.d.mts +1 -1
  113. package/dist/{types-mpeSaHdI.d.mts → types-D1PUFkda.d.mts} +1 -1
  114. package/dist/utils/base64url.d.mts +1 -1
  115. package/dist/utils/base64url.mjs +1 -1
  116. package/dist/utils/create-handler.d.mts +2 -2
  117. package/dist/utils/create-handler.mjs +4 -4
  118. package/dist/utils/dependency-manager.d.mts +1 -1
  119. package/dist/utils/dependency-manager.mjs +1 -2
  120. package/dist/utils/formats.d.mts +1 -1
  121. package/dist/utils/go-await.d.mts +1 -1
  122. package/dist/utils/go-await.mjs +1 -1
  123. package/dist/utils/handle.d.mts +1 -1
  124. package/dist/utils/handle.mjs +2 -2
  125. package/dist/utils/html-renderer.d.mts +1 -1
  126. package/dist/utils/html-renderer.mjs +1 -2
  127. package/dist/utils/index.d.mts +16 -16
  128. package/dist/utils/index.mjs +13 -21
  129. package/dist/utils/parsers.d.mts +1 -1
  130. package/dist/utils/parsers.mjs +1 -1
  131. package/dist/utils/path-matcher.mjs +1 -2
  132. package/dist/utils/request-validator.d.mts +2 -2
  133. package/dist/utils/request-validator.mjs +3 -3
  134. package/dist/utils/response.d.mts +4 -4
  135. package/dist/utils/response.mjs +1 -2
  136. package/dist/utils/route-registry.d.mts +3 -3
  137. package/dist/utils/route-registry.mjs +1 -2
  138. package/dist/utils/sse.d.mts +2 -2
  139. package/dist/utils/sse.mjs +3 -3
  140. package/dist/utils/validators/validators.d.mts +1 -1
  141. package/dist/utils/validators/validators.mjs +1 -1
  142. package/dist/{validators-CPmnj_y9.d.mts → validators-Ch71zkT8.d.mts} +1 -1
  143. package/dist/{validators-WXQ49LcR.mjs → validators-DBkyw6BG.mjs} +1 -1
  144. package/dist/{validators-WXQ49LcR.mjs.map → validators-DBkyw6BG.mjs.map} +1 -1
  145. package/package.json +7 -2
  146. package/dist/base-server-DMhpmq5v.mjs +0 -113
  147. package/dist/chunk-DW4-Jl94.mjs +0 -37
  148. package/dist/component-server-DIgykV0F.mjs +0 -124
  149. package/dist/dependency-manager-BpN2YufZ.mjs +0 -61
  150. package/dist/monitoring/index.mjs.map +0 -1
  151. package/dist/monitoring/types.d.mts +0 -150
  152. package/dist/path-matcher-BNaaJgI3.mjs +0 -62
  153. package/dist/radix-tree-Qxr-QpCx.mjs +0 -157
  154. package/dist/route-registry-BVvbghgH.mjs +0 -225
  155. package/dist/router/index.mjs.map +0 -1
  156. package/dist/schema-CflsMJuG.mjs +0 -1
  157. package/dist/server-BttM6Ssc.mjs +0 -88
  158. package/dist/server-BttM6Ssc.mjs.map +0 -1
  159. package/dist/server-C3yoZXNs.mjs +0 -136
  160. package/dist/utils/index.mjs.map +0 -1
  161. /package/dist/{component-route-BKUFoJ5P.mjs → component-route-DNgAj6VC.mjs} +0 -0
  162. /package/dist/{index-CTHojwxd.d.mts → index-CREkvfw9.d.mts} +0 -0
  163. /package/dist/{monitoring/types.mjs → schema-1fwiv7cm.mjs} +0 -0
@@ -1,154 +1,358 @@
1
- import { r as __toCommonJS } from "../chunk-DW4-Jl94.mjs";
2
- import "../middleware-CV5o-4wk.mjs";
3
- import "../server-C3yoZXNs.mjs";
4
- import "../dependency-manager-BpN2YufZ.mjs";
5
- import "../component-server-DIgykV0F.mjs";
6
- import { n as server_exports, t as init_server } from "../server-BttM6Ssc.mjs";
7
-
8
1
  //#region src/monitoring/native-monitor.ts
9
- var NativeMonitor = class {
10
- config;
11
- metrics = [];
12
- isEnabled = false;
13
- constructor(config = {}) {
14
- this.config = {
15
- enabled: true,
16
- console: true,
17
- slowThreshold: 1e3,
18
- errorThreshold: .05,
19
- tags: { framework: "vafast" },
20
- ...config
21
- };
22
- this.isEnabled = this.config.enabled ?? true;
23
- if (this.isEnabled && this.config.console) {
24
- console.log("✅ 原生监控已启用");
25
- console.log(`📊 监控配置:`, {
26
- 慢请求阈值: `${this.config.slowThreshold}ms`,
27
- 错误率阈值: `${(this.config.errorThreshold * 100).toFixed(1)}%`,
28
- 标签: this.config.tags
29
- });
2
+ const ONE_MINUTE = 60 * 1e3;
3
+ const FIVE_MINUTES = 300 * 1e3;
4
+ const ONE_HOUR = 3600 * 1e3;
5
+ function createRingBuffer(capacity) {
6
+ const buffer = new Array(capacity);
7
+ let head = 0;
8
+ let size = 0;
9
+ return {
10
+ push(item) {
11
+ buffer[head % capacity] = item;
12
+ head++;
13
+ if (size < capacity) size++;
14
+ },
15
+ toArray() {
16
+ if (size === 0) return [];
17
+ if (size < capacity) return buffer.slice(0, size);
18
+ const start = head % capacity;
19
+ return [...buffer.slice(start), ...buffer.slice(0, start)];
20
+ },
21
+ getSize: () => size,
22
+ clear() {
23
+ head = 0;
24
+ size = 0;
25
+ },
26
+ recent(n) {
27
+ return this.toArray().slice(-n);
30
28
  }
29
+ };
30
+ }
31
+ function generateRequestId() {
32
+ return `req_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
33
+ }
34
+ function getMemoryInfo() {
35
+ if (typeof process !== "undefined" && process.memoryUsage) {
36
+ const mem = process.memoryUsage();
37
+ return {
38
+ heapUsed: mem.heapUsed,
39
+ heapTotal: mem.heapTotal
40
+ };
31
41
  }
32
- recordMetrics(metrics) {
33
- if (!this.isEnabled) return;
34
- this.metrics.push(metrics);
35
- if (this.metrics.length > 1e3) this.metrics = this.metrics.slice(-1e3);
36
- if (this.config.console) {
37
- const status = metrics.statusCode < 400 ? "✅" : "❌";
38
- const timeColor = metrics.totalTime > this.config.slowThreshold ? "🐌" : "⚡";
39
- console.log(`${status} ${metrics.method} ${metrics.path} - ${metrics.statusCode} (${timeColor} ${metrics.totalTime.toFixed(2)}ms)`);
40
- if (metrics.totalTime > this.config.slowThreshold) console.warn(`🐌 慢请求警告: ${metrics.path} 耗时 ${metrics.totalTime.toFixed(2)}ms`);
41
- }
42
+ return {
43
+ heapUsed: 0,
44
+ heapTotal: 0
45
+ };
46
+ }
47
+ function formatMemory(bytes) {
48
+ return (bytes / 1024 / 1024).toFixed(2) + "MB";
49
+ }
50
+ function percentile(sorted, p) {
51
+ if (sorted.length === 0) return 0;
52
+ const index = Math.ceil(p / 100 * sorted.length) - 1;
53
+ return sorted[Math.max(0, index)];
54
+ }
55
+ function shouldExclude(path, excludePaths) {
56
+ return excludePaths.some((p) => path === p || path.startsWith(p + "/") || p.endsWith("*") && path.startsWith(p.slice(0, -1)));
57
+ }
58
+ function getStatusCodeCategory(code) {
59
+ if (code >= 200 && code < 300) return "2xx";
60
+ if (code >= 300 && code < 400) return "3xx";
61
+ if (code >= 400 && code < 500) return "4xx";
62
+ return "5xx";
63
+ }
64
+ function createMonitorState(config) {
65
+ const buffer = createRingBuffer(config.maxRecords);
66
+ const pathStats = /* @__PURE__ */ new Map();
67
+ const startTime = Date.now();
68
+ /** 获取时间窗口内的指标 */
69
+ function getMetricsInWindow(windowMs) {
70
+ const cutoff = Date.now() - windowMs;
71
+ return buffer.toArray().filter((m) => m.timestamp >= cutoff);
42
72
  }
43
- getStatus() {
44
- if (!this.isEnabled) return {
45
- enabled: false,
46
- message: "监控未启用"
73
+ /** 计算时间窗口统计 */
74
+ function calcTimeWindowStats(windowMs) {
75
+ const metrics = getMetricsInWindow(windowMs);
76
+ const count = metrics.length;
77
+ if (count === 0) return {
78
+ requests: 0,
79
+ successful: 0,
80
+ failed: 0,
81
+ errorRate: 0,
82
+ avgTime: 0,
83
+ rps: 0
47
84
  };
48
- const totalRequests = this.metrics.length;
49
- const successfulRequests = this.metrics.filter((m) => m.statusCode < 400).length;
50
- const failedRequests = totalRequests - successfulRequests;
51
- const avgResponseTime = totalRequests > 0 ? this.metrics.reduce((sum, m) => sum + m.totalTime, 0) / totalRequests : 0;
85
+ const successful = metrics.filter((m) => m.statusCode < 400).length;
86
+ const failed = count - successful;
87
+ const avgTime = metrics.reduce((sum, m) => sum + m.totalTime, 0) / count;
88
+ const timestamps = metrics.map((m) => m.timestamp);
89
+ const actualWindow = Math.max(...timestamps) - Math.min(...timestamps);
90
+ const rps = count / Math.max(actualWindow, 1e3) * 1e3;
52
91
  return {
53
- enabled: true,
54
- totalRequests,
55
- successfulRequests,
56
- failedRequests,
57
- errorRate: totalRequests > 0 ? failedRequests / totalRequests : 0,
58
- avgResponseTime: avgResponseTime.toFixed(2) + "ms",
59
- memoryUsage: this.getMemoryUsage(),
60
- recentRequests: this.metrics.slice(-5)
92
+ requests: count,
93
+ successful,
94
+ failed,
95
+ errorRate: failed / count,
96
+ avgTime: Number(avgTime.toFixed(2)),
97
+ rps: Number(rps.toFixed(2))
61
98
  };
62
99
  }
63
- getMetrics() {
64
- return this.metrics;
100
+ /** 计算状态码分布 */
101
+ function calcStatusCodeDistribution() {
102
+ const metrics = buffer.toArray();
103
+ const dist = {
104
+ "2xx": 0,
105
+ "3xx": 0,
106
+ "4xx": 0,
107
+ "5xx": 0,
108
+ detail: {}
109
+ };
110
+ for (const m of metrics) {
111
+ const category = getStatusCodeCategory(m.statusCode);
112
+ dist[category]++;
113
+ dist.detail[m.statusCode] = (dist.detail[m.statusCode] || 0) + 1;
114
+ }
115
+ return dist;
65
116
  }
66
- reset() {
67
- this.metrics = [];
68
- console.log("🔄 监控数据已重置");
117
+ /** 计算当前 RPS(基于最近 10 秒) */
118
+ function calcCurrentRPS() {
119
+ const metrics = getMetricsInWindow(1e4);
120
+ if (metrics.length === 0) return 0;
121
+ return Number((metrics.length / 10).toFixed(2));
69
122
  }
70
- getMemoryUsage() {
71
- if (typeof process !== "undefined" && process.memoryUsage) {
72
- const mem = process.memoryUsage();
123
+ return {
124
+ addMetrics(m) {
125
+ buffer.push(m);
126
+ const stats = pathStats.get(m.path) || {
127
+ count: 0,
128
+ totalTime: 0,
129
+ avgTime: 0,
130
+ minTime: Infinity,
131
+ maxTime: 0,
132
+ errorCount: 0
133
+ };
134
+ stats.count++;
135
+ stats.totalTime += m.totalTime;
136
+ stats.avgTime = stats.totalTime / stats.count;
137
+ stats.minTime = Math.min(stats.minTime, m.totalTime);
138
+ stats.maxTime = Math.max(stats.maxTime, m.totalTime);
139
+ if (m.statusCode >= 400) stats.errorCount++;
140
+ pathStats.set(m.path, stats);
141
+ },
142
+ getMetrics: () => buffer.toArray(),
143
+ getPathStats: (path) => pathStats.get(path),
144
+ getTimeWindowStats: calcTimeWindowStats,
145
+ getRPS: calcCurrentRPS,
146
+ getStatusCodeDistribution: calcStatusCodeDistribution,
147
+ reset() {
148
+ buffer.clear();
149
+ pathStats.clear();
150
+ },
151
+ getStatus() {
152
+ const metrics = buffer.toArray();
153
+ const total = metrics.length;
154
+ if (total === 0) return {
155
+ enabled: config.enabled,
156
+ uptime: Date.now() - startTime,
157
+ totalRequests: 0,
158
+ successfulRequests: 0,
159
+ failedRequests: 0,
160
+ errorRate: 0,
161
+ avgResponseTime: 0,
162
+ p50: 0,
163
+ p95: 0,
164
+ p99: 0,
165
+ minTime: 0,
166
+ maxTime: 0,
167
+ rps: 0,
168
+ statusCodes: {
169
+ "2xx": 0,
170
+ "3xx": 0,
171
+ "4xx": 0,
172
+ "5xx": 0,
173
+ detail: {}
174
+ },
175
+ timeWindows: {
176
+ last1min: {
177
+ requests: 0,
178
+ successful: 0,
179
+ failed: 0,
180
+ errorRate: 0,
181
+ avgTime: 0,
182
+ rps: 0
183
+ },
184
+ last5min: {
185
+ requests: 0,
186
+ successful: 0,
187
+ failed: 0,
188
+ errorRate: 0,
189
+ avgTime: 0,
190
+ rps: 0
191
+ },
192
+ last1hour: {
193
+ requests: 0,
194
+ successful: 0,
195
+ failed: 0,
196
+ errorRate: 0,
197
+ avgTime: 0,
198
+ rps: 0
199
+ }
200
+ },
201
+ byPath: {},
202
+ memoryUsage: {
203
+ heapUsed: formatMemory(0),
204
+ heapTotal: formatMemory(0)
205
+ },
206
+ recentRequests: []
207
+ };
208
+ const successful = metrics.filter((m) => m.statusCode < 400).length;
209
+ const failed = total - successful;
210
+ const times = metrics.map((m) => m.totalTime);
211
+ const sortedTimes = [...times].sort((a, b) => a - b);
212
+ const avgTime = times.reduce((a, b) => a + b, 0) / total;
213
+ const mem = getMemoryInfo();
214
+ const byPath = {};
215
+ pathStats.forEach((stats, path) => {
216
+ byPath[path] = {
217
+ ...stats,
218
+ minTime: stats.minTime === Infinity ? 0 : stats.minTime
219
+ };
220
+ });
73
221
  return {
74
- heapUsed: (mem.heapUsed / 1024 / 1024).toFixed(2) + "MB",
75
- heapTotal: (mem.heapTotal / 1024 / 1024).toFixed(2) + "MB",
76
- external: (mem.external / 1024 / 1024).toFixed(2) + "MB"
222
+ enabled: config.enabled,
223
+ uptime: Date.now() - startTime,
224
+ totalRequests: total,
225
+ successfulRequests: successful,
226
+ failedRequests: failed,
227
+ errorRate: Number((failed / total).toFixed(4)),
228
+ avgResponseTime: Number(avgTime.toFixed(2)),
229
+ p50: Number(percentile(sortedTimes, 50).toFixed(2)),
230
+ p95: Number(percentile(sortedTimes, 95).toFixed(2)),
231
+ p99: Number(percentile(sortedTimes, 99).toFixed(2)),
232
+ minTime: Number(sortedTimes[0].toFixed(2)),
233
+ maxTime: Number(sortedTimes[sortedTimes.length - 1].toFixed(2)),
234
+ rps: calcCurrentRPS(),
235
+ statusCodes: calcStatusCodeDistribution(),
236
+ timeWindows: {
237
+ last1min: calcTimeWindowStats(ONE_MINUTE),
238
+ last5min: calcTimeWindowStats(FIVE_MINUTES),
239
+ last1hour: calcTimeWindowStats(ONE_HOUR)
240
+ },
241
+ byPath,
242
+ memoryUsage: {
243
+ heapUsed: formatMemory(mem.heapUsed),
244
+ heapTotal: formatMemory(mem.heapTotal)
245
+ },
246
+ recentRequests: buffer.recent(5)
77
247
  };
78
248
  }
79
- return { message: "内存信息不可用" };
80
- }
249
+ };
250
+ }
251
+ function logRequest(metrics, slowThreshold, enabled) {
252
+ if (!enabled) return;
253
+ const status = metrics.statusCode < 400 ? "✅" : "❌";
254
+ const speed = metrics.totalTime > slowThreshold ? "🐌" : "⚡";
255
+ console.log(`${status} ${metrics.method} ${metrics.path} - ${metrics.statusCode} (${speed} ${metrics.totalTime.toFixed(2)}ms)`);
256
+ }
257
+ const defaultConfig = {
258
+ enabled: true,
259
+ console: true,
260
+ slowThreshold: 1e3,
261
+ maxRecords: 1e3,
262
+ samplingRate: 1,
263
+ excludePaths: [],
264
+ tags: { framework: "vafast" },
265
+ onRequest: () => {},
266
+ onSlowRequest: () => {}
81
267
  };
268
+ /**
269
+ * 为 Server 添加监控能力
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * const server = new Server(routes)
274
+ * const monitored = withMonitoring(server, {
275
+ * slowThreshold: 500,
276
+ * excludePaths: ['/health'],
277
+ * onSlowRequest: (m) => console.warn('Slow!', m.path)
278
+ * })
279
+ *
280
+ * // 获取完整状态
281
+ * const status = monitored.getMonitoringStatus()
282
+ * console.log(`P99: ${status.p99}ms`)
283
+ * console.log(`RPS: ${status.rps}`)
284
+ * console.log(`Last 1min errors: ${status.timeWindows.last1min.errorRate}`)
285
+ *
286
+ * // 单独获取 RPS
287
+ * console.log(`Current RPS: ${monitored.getRPS()}`)
288
+ *
289
+ * // 自定义时间窗口
290
+ * const last30sec = monitored.getTimeWindowStats(30000)
291
+ * ```
292
+ */
82
293
  function withMonitoring(server, config = {}) {
83
- const monitor = new NativeMonitor(config);
294
+ const finalConfig = {
295
+ ...defaultConfig,
296
+ ...config
297
+ };
298
+ const state = createMonitorState(finalConfig);
84
299
  const originalFetch = server.fetch.bind(server);
300
+ if (finalConfig.enabled && finalConfig.console) {
301
+ console.log("✅ Monitoring enabled");
302
+ console.log(`📊 Config:`, {
303
+ slowThreshold: `${finalConfig.slowThreshold}ms`,
304
+ maxRecords: finalConfig.maxRecords,
305
+ samplingRate: finalConfig.samplingRate,
306
+ excludePaths: finalConfig.excludePaths
307
+ });
308
+ }
85
309
  const monitoredFetch = async (req) => {
86
- const startTime = performance.now();
87
- const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
310
+ if (!finalConfig.enabled) return originalFetch(req);
88
311
  const { pathname } = new URL(req.url);
312
+ if (shouldExclude(pathname, finalConfig.excludePaths)) return originalFetch(req);
313
+ if (finalConfig.samplingRate < 1 && Math.random() > finalConfig.samplingRate) return originalFetch(req);
314
+ const startTime = performance.now();
315
+ const requestId = generateRequestId();
89
316
  const method = req.method;
317
+ let statusCode = 500;
90
318
  try {
91
319
  const response = await originalFetch(req);
92
- const totalTime = performance.now() - startTime;
93
- monitor.recordMetrics({
94
- requestId,
95
- method,
96
- path: pathname,
97
- statusCode: response.status,
98
- totalTime,
99
- timestamp: Date.now(),
100
- memoryUsage: (() => {
101
- if (typeof process !== "undefined" && process.memoryUsage) {
102
- const mem = process.memoryUsage();
103
- return {
104
- heapUsed: mem.heapUsed,
105
- heapTotal: mem.heapTotal
106
- };
107
- }
108
- return {
109
- heapUsed: 0,
110
- heapTotal: 0
111
- };
112
- })()
113
- });
320
+ statusCode = response.status;
114
321
  return response;
115
- } catch (error) {
322
+ } finally {
116
323
  const totalTime = performance.now() - startTime;
117
- monitor.recordMetrics({
324
+ const metrics = {
118
325
  requestId,
119
326
  method,
120
327
  path: pathname,
121
- statusCode: 500,
328
+ statusCode,
122
329
  totalTime,
123
330
  timestamp: Date.now(),
124
- memoryUsage: (() => {
125
- if (typeof process !== "undefined" && process.memoryUsage) {
126
- const mem = process.memoryUsage();
127
- return {
128
- heapUsed: mem.heapUsed,
129
- heapTotal: mem.heapTotal
130
- };
131
- }
132
- return {
133
- heapUsed: 0,
134
- heapTotal: 0
135
- };
136
- })()
137
- });
138
- throw error;
331
+ memoryUsage: getMemoryInfo()
332
+ };
333
+ state.addMetrics(metrics);
334
+ logRequest(metrics, finalConfig.slowThreshold, finalConfig.console);
335
+ finalConfig.onRequest(metrics);
336
+ if (totalTime > finalConfig.slowThreshold) finalConfig.onSlowRequest(metrics);
139
337
  }
140
338
  };
141
339
  return {
142
340
  ...server,
143
341
  fetch: monitoredFetch,
144
- getMonitoringStatus: () => monitor.getStatus(),
145
- getMonitoringMetrics: () => monitor.getMetrics(),
146
- resetMonitoring: () => monitor.reset()
342
+ getMonitoringStatus: state.getStatus,
343
+ getMonitoringMetrics: state.getMetrics,
344
+ getPathStats: state.getPathStats,
345
+ getTimeWindowStats: state.getTimeWindowStats,
346
+ getRPS: state.getRPS,
347
+ getStatusCodeDistribution: state.getStatusCodeDistribution,
348
+ resetMonitoring: state.reset
147
349
  };
148
350
  }
149
- function createMonitoredServer(routes, config) {
150
- const { Server } = (init_server(), __toCommonJS(server_exports));
151
- return withMonitoring(new Server(routes), config);
351
+ /**
352
+ * 创建带监控的 Server(便捷函数)
353
+ */
354
+ function createMonitoredServer(ServerClass, routes, config) {
355
+ return withMonitoring(new ServerClass(routes), config);
152
356
  }
153
357
 
154
358
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"native-monitor.mjs","names":[],"sources":["../../src/monitoring/native-monitor.ts"],"sourcesContent":["/**\n * 原生监控装饰器\n *\n * 通过装饰器模式为 Server 添加监控能力,完全不入侵原类\n *\n * @author Framework Team\n * @version 2.0.0\n * @license MIT\n */\n\nimport type { Server } from \"../server\";\n\n// 监控配置接口\nexport interface NativeMonitoringConfig {\n enabled?: boolean;\n console?: boolean;\n slowThreshold?: number; // 毫秒\n errorThreshold?: number;\n tags?: Record<string, string>;\n}\n\n// 监控指标接口\nexport interface NativeMonitoringMetrics {\n requestId: string;\n method: string;\n path: string;\n statusCode: number;\n totalTime: number;\n timestamp: number;\n memoryUsage: {\n heapUsed: number;\n heapTotal: number;\n };\n}\n\n// 带监控的 Server 接口\nexport interface MonitoredServer extends Server {\n // 监控相关方法\n getMonitoringStatus(): any;\n getMonitoringMetrics(): NativeMonitoringMetrics[];\n resetMonitoring(): void;\n\n // 原始方法保持不变\n fetch: (req: Request) => Promise<Response>;\n use: (mw: any) => void;\n}\n\n// 原生监控器\nclass NativeMonitor {\n private config: NativeMonitoringConfig;\n private metrics: NativeMonitoringMetrics[] = [];\n private isEnabled = false;\n\n constructor(config: NativeMonitoringConfig = {}) {\n this.config = {\n enabled: true,\n console: true,\n slowThreshold: 1000,\n errorThreshold: 0.05,\n tags: { framework: \"vafast\" },\n ...config,\n };\n\n this.isEnabled = this.config.enabled ?? true;\n\n if (this.isEnabled && this.config.console) {\n console.log(\"✅ 原生监控已启用\");\n console.log(`📊 监控配置:`, {\n 慢请求阈值: `${this.config.slowThreshold}ms`,\n 错误率阈值: `${(this.config.errorThreshold! * 100).toFixed(1)}%`,\n 标签: this.config.tags,\n });\n }\n }\n\n // 记录监控指标\n recordMetrics(metrics: NativeMonitoringMetrics): void {\n if (!this.isEnabled) return;\n\n this.metrics.push(metrics);\n\n // 保持最近1000条记录\n if (this.metrics.length > 1000) {\n this.metrics = this.metrics.slice(-1000);\n }\n\n // 控制台输出\n if (this.config.console) {\n const status = metrics.statusCode < 400 ? \"✅\" : \"❌\";\n const timeColor =\n metrics.totalTime > this.config.slowThreshold! ? \"🐌\" : \"⚡\";\n\n console.log(\n `${status} ${metrics.method} ${metrics.path} - ${\n metrics.statusCode\n } (${timeColor} ${metrics.totalTime.toFixed(2)}ms)`,\n );\n\n // 慢请求警告\n if (metrics.totalTime > this.config.slowThreshold!) {\n console.warn(\n `🐌 慢请求警告: ${metrics.path} 耗时 ${metrics.totalTime.toFixed(\n 2,\n )}ms`,\n );\n }\n }\n }\n\n // 获取监控状态\n getStatus() {\n if (!this.isEnabled) {\n return { enabled: false, message: \"监控未启用\" };\n }\n\n const totalRequests = this.metrics.length;\n const successfulRequests = this.metrics.filter(\n (m) => m.statusCode < 400,\n ).length;\n const failedRequests = totalRequests - successfulRequests;\n const avgResponseTime =\n totalRequests > 0\n ? this.metrics.reduce((sum, m) => sum + m.totalTime, 0) / totalRequests\n : 0;\n\n return {\n enabled: true,\n totalRequests,\n successfulRequests,\n failedRequests,\n errorRate: totalRequests > 0 ? failedRequests / totalRequests : 0,\n avgResponseTime: avgResponseTime.toFixed(2) + \"ms\",\n memoryUsage: this.getMemoryUsage(),\n recentRequests: this.metrics.slice(-5),\n };\n }\n\n // 获取监控指标\n getMetrics() {\n return this.metrics;\n }\n\n // 重置监控数据\n reset() {\n this.metrics = [];\n console.log(\"🔄 监控数据已重置\");\n }\n\n // 获取内存使用情况\n private getMemoryUsage() {\n if (typeof process !== \"undefined\" && process.memoryUsage) {\n const mem = process.memoryUsage();\n return {\n heapUsed: (mem.heapUsed / 1024 / 1024).toFixed(2) + \"MB\",\n heapTotal: (mem.heapTotal / 1024 / 1024).toFixed(2) + \"MB\",\n external: (mem.external / 1024 / 1024).toFixed(2) + \"MB\",\n };\n }\n return { message: \"内存信息不可用\" };\n }\n}\n\n// 纯函数:为 Server 添加监控能力\nexport function withMonitoring(\n server: Server,\n config: NativeMonitoringConfig = {},\n): MonitoredServer {\n const monitor = new NativeMonitor(config);\n\n // 保存原始的 fetch 方法\n const originalFetch = server.fetch.bind(server);\n\n // 创建带监控的 fetch 方法\n const monitoredFetch = async (req: Request): Promise<Response> => {\n const startTime = performance.now();\n const requestId = `req_${Date.now()}_${Math.random()\n .toString(36)\n .substr(2, 9)}`;\n const { pathname } = new URL(req.url);\n const method = req.method;\n\n try {\n // 调用原始 fetch\n const response = await originalFetch(req);\n\n // 记录监控指标\n const totalTime = performance.now() - startTime;\n monitor.recordMetrics({\n requestId,\n method,\n path: pathname,\n statusCode: response.status,\n totalTime,\n timestamp: Date.now(),\n memoryUsage: (() => {\n if (typeof process !== \"undefined\" && process.memoryUsage) {\n const mem = process.memoryUsage();\n return {\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n };\n }\n return { heapUsed: 0, heapTotal: 0 };\n })(),\n });\n\n return response;\n } catch (error) {\n // 记录错误监控指标\n const totalTime = performance.now() - startTime;\n monitor.recordMetrics({\n requestId,\n method,\n path: pathname,\n statusCode: 500,\n totalTime,\n timestamp: Date.now(),\n memoryUsage: (() => {\n if (typeof process !== \"undefined\" && process.memoryUsage) {\n const mem = process.memoryUsage();\n return {\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n };\n }\n return { heapUsed: 0, heapTotal: 0 };\n })(),\n });\n\n throw error;\n }\n };\n\n // 创建带监控的 Server 对象\n const monitoredServer = {\n ...server,\n fetch: monitoredFetch,\n\n // 监控方法\n getMonitoringStatus: () => monitor.getStatus(),\n getMonitoringMetrics: () => monitor.getMetrics(),\n resetMonitoring: () => monitor.reset(),\n } as MonitoredServer;\n\n return monitoredServer;\n}\n\n// 便捷函数:创建带监控的 Server\nexport function createMonitoredServer(\n routes: any[],\n config?: NativeMonitoringConfig,\n): MonitoredServer {\n const { Server } = require(\"../server\");\n const server = new Server(routes);\n return withMonitoring(server, config);\n}\n"],"mappings":";;;;;;;;AAgDA,IAAM,gBAAN,MAAoB;CAClB,AAAQ;CACR,AAAQ,UAAqC,EAAE;CAC/C,AAAQ,YAAY;CAEpB,YAAY,SAAiC,EAAE,EAAE;AAC/C,OAAK,SAAS;GACZ,SAAS;GACT,SAAS;GACT,eAAe;GACf,gBAAgB;GAChB,MAAM,EAAE,WAAW,UAAU;GAC7B,GAAG;GACJ;AAED,OAAK,YAAY,KAAK,OAAO,WAAW;AAExC,MAAI,KAAK,aAAa,KAAK,OAAO,SAAS;AACzC,WAAQ,IAAI,YAAY;AACxB,WAAQ,IAAI,YAAY;IACtB,OAAO,GAAG,KAAK,OAAO,cAAc;IACpC,OAAO,IAAI,KAAK,OAAO,iBAAkB,KAAK,QAAQ,EAAE,CAAC;IACzD,IAAI,KAAK,OAAO;IACjB,CAAC;;;CAKN,cAAc,SAAwC;AACpD,MAAI,CAAC,KAAK,UAAW;AAErB,OAAK,QAAQ,KAAK,QAAQ;AAG1B,MAAI,KAAK,QAAQ,SAAS,IACxB,MAAK,UAAU,KAAK,QAAQ,MAAM,KAAM;AAI1C,MAAI,KAAK,OAAO,SAAS;GACvB,MAAM,SAAS,QAAQ,aAAa,MAAM,MAAM;GAChD,MAAM,YACJ,QAAQ,YAAY,KAAK,OAAO,gBAAiB,OAAO;AAE1D,WAAQ,IACN,GAAG,OAAO,GAAG,QAAQ,OAAO,GAAG,QAAQ,KAAK,KAC1C,QAAQ,WACT,IAAI,UAAU,GAAG,QAAQ,UAAU,QAAQ,EAAE,CAAC,KAChD;AAGD,OAAI,QAAQ,YAAY,KAAK,OAAO,cAClC,SAAQ,KACN,aAAa,QAAQ,KAAK,MAAM,QAAQ,UAAU,QAChD,EACD,CAAC,IACH;;;CAMP,YAAY;AACV,MAAI,CAAC,KAAK,UACR,QAAO;GAAE,SAAS;GAAO,SAAS;GAAS;EAG7C,MAAM,gBAAgB,KAAK,QAAQ;EACnC,MAAM,qBAAqB,KAAK,QAAQ,QACrC,MAAM,EAAE,aAAa,IACvB,CAAC;EACF,MAAM,iBAAiB,gBAAgB;EACvC,MAAM,kBACJ,gBAAgB,IACZ,KAAK,QAAQ,QAAQ,KAAK,MAAM,MAAM,EAAE,WAAW,EAAE,GAAG,gBACxD;AAEN,SAAO;GACL,SAAS;GACT;GACA;GACA;GACA,WAAW,gBAAgB,IAAI,iBAAiB,gBAAgB;GAChE,iBAAiB,gBAAgB,QAAQ,EAAE,GAAG;GAC9C,aAAa,KAAK,gBAAgB;GAClC,gBAAgB,KAAK,QAAQ,MAAM,GAAG;GACvC;;CAIH,aAAa;AACX,SAAO,KAAK;;CAId,QAAQ;AACN,OAAK,UAAU,EAAE;AACjB,UAAQ,IAAI,aAAa;;CAI3B,AAAQ,iBAAiB;AACvB,MAAI,OAAO,YAAY,eAAe,QAAQ,aAAa;GACzD,MAAM,MAAM,QAAQ,aAAa;AACjC,UAAO;IACL,WAAW,IAAI,WAAW,OAAO,MAAM,QAAQ,EAAE,GAAG;IACpD,YAAY,IAAI,YAAY,OAAO,MAAM,QAAQ,EAAE,GAAG;IACtD,WAAW,IAAI,WAAW,OAAO,MAAM,QAAQ,EAAE,GAAG;IACrD;;AAEH,SAAO,EAAE,SAAS,WAAW;;;AAKjC,SAAgB,eACd,QACA,SAAiC,EAAE,EAClB;CACjB,MAAM,UAAU,IAAI,cAAc,OAAO;CAGzC,MAAM,gBAAgB,OAAO,MAAM,KAAK,OAAO;CAG/C,MAAM,iBAAiB,OAAO,QAAoC;EAChE,MAAM,YAAY,YAAY,KAAK;EACnC,MAAM,YAAY,OAAO,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CACjD,SAAS,GAAG,CACZ,OAAO,GAAG,EAAE;EACf,MAAM,EAAE,aAAa,IAAI,IAAI,IAAI,IAAI;EACrC,MAAM,SAAS,IAAI;AAEnB,MAAI;GAEF,MAAM,WAAW,MAAM,cAAc,IAAI;GAGzC,MAAM,YAAY,YAAY,KAAK,GAAG;AACtC,WAAQ,cAAc;IACpB;IACA;IACA,MAAM;IACN,YAAY,SAAS;IACrB;IACA,WAAW,KAAK,KAAK;IACrB,oBAAoB;AAClB,SAAI,OAAO,YAAY,eAAe,QAAQ,aAAa;MACzD,MAAM,MAAM,QAAQ,aAAa;AACjC,aAAO;OACL,UAAU,IAAI;OACd,WAAW,IAAI;OAChB;;AAEH,YAAO;MAAE,UAAU;MAAG,WAAW;MAAG;QAClC;IACL,CAAC;AAEF,UAAO;WACA,OAAO;GAEd,MAAM,YAAY,YAAY,KAAK,GAAG;AACtC,WAAQ,cAAc;IACpB;IACA;IACA,MAAM;IACN,YAAY;IACZ;IACA,WAAW,KAAK,KAAK;IACrB,oBAAoB;AAClB,SAAI,OAAO,YAAY,eAAe,QAAQ,aAAa;MACzD,MAAM,MAAM,QAAQ,aAAa;AACjC,aAAO;OACL,UAAU,IAAI;OACd,WAAW,IAAI;OAChB;;AAEH,YAAO;MAAE,UAAU;MAAG,WAAW;MAAG;QAClC;IACL,CAAC;AAEF,SAAM;;;AAeV,QAVwB;EACtB,GAAG;EACH,OAAO;EAGP,2BAA2B,QAAQ,WAAW;EAC9C,4BAA4B,QAAQ,YAAY;EAChD,uBAAuB,QAAQ,OAAO;EACvC;;AAMH,SAAgB,sBACd,QACA,QACiB;CACjB,MAAM,EAAE;AAER,QAAO,eADQ,IAAI,OAAO,OAAO,EACH,OAAO"}
1
+ {"version":3,"file":"native-monitor.mjs","names":[],"sources":["../../src/monitoring/native-monitor.ts"],"sourcesContent":["/**\n * 原生监控模块(零外部依赖)\n *\n * 特性:\n * - P50/P95/P99 百分位数统计\n * - 按路径分组统计\n * - 时间窗口统计(1分钟/5分钟/1小时)\n * - RPS 计算(每秒请求数)\n * - 状态码分布\n * - 环形缓冲区(内存友好)\n * - 采样率控制\n * - 路径排除\n * - 自定义回调\n */\n\nimport type { Server } from \"../server\";\n\n// ========== 类型定义 ==========\n\n/** 监控配置 */\nexport interface MonitoringConfig {\n /** 是否启用监控,默认 true */\n enabled?: boolean;\n /** 是否输出到控制台,默认 true */\n console?: boolean;\n /** 慢请求阈值(毫秒),默认 1000 */\n slowThreshold?: number;\n /** 最大记录数,默认 1000 */\n maxRecords?: number;\n /** 采样率 0-1,默认 1(全部记录) */\n samplingRate?: number;\n /** 排除的路径(不记录) */\n excludePaths?: string[];\n /** 自定义标签 */\n tags?: Record<string, string>;\n /** 请求完成回调 */\n onRequest?: (metrics: MonitoringMetrics) => void;\n /** 慢请求回调 */\n onSlowRequest?: (metrics: MonitoringMetrics) => void;\n}\n\n/** 监控指标 */\nexport interface MonitoringMetrics {\n requestId: string;\n method: string;\n path: string;\n statusCode: number;\n totalTime: number;\n timestamp: number;\n memoryUsage: MemoryInfo;\n}\n\n/** 内存信息 */\nexport interface MemoryInfo {\n heapUsed: number;\n heapTotal: number;\n}\n\n/** 路径统计 */\nexport interface PathStats {\n count: number;\n totalTime: number;\n avgTime: number;\n minTime: number;\n maxTime: number;\n errorCount: number;\n}\n\n/** 时间窗口统计 */\nexport interface TimeWindowStats {\n /** 请求数 */\n requests: number;\n /** 成功数 */\n successful: number;\n /** 失败数 */\n failed: number;\n /** 错误率 */\n errorRate: number;\n /** 平均响应时间 */\n avgTime: number;\n /** RPS(每秒请求数) */\n rps: number;\n}\n\n/** 状态码分布 */\nexport interface StatusCodeDistribution {\n /** 2xx 成功 */\n \"2xx\": number;\n /** 3xx 重定向 */\n \"3xx\": number;\n /** 4xx 客户端错误 */\n \"4xx\": number;\n /** 5xx 服务器错误 */\n \"5xx\": number;\n /** 详细分布 */\n detail: Record<number, number>;\n}\n\n/** 监控状态 */\nexport interface MonitoringStatus {\n enabled: boolean;\n /** 服务运行时间(毫秒) */\n uptime: number;\n totalRequests: number;\n successfulRequests: number;\n failedRequests: number;\n errorRate: number;\n /** 平均响应时间(毫秒) */\n avgResponseTime: number;\n /** P50 响应时间(毫秒) */\n p50: number;\n /** P95 响应时间(毫秒) */\n p95: number;\n /** P99 响应时间(毫秒) */\n p99: number;\n /** 最小响应时间 */\n minTime: number;\n /** 最大响应时间 */\n maxTime: number;\n /** 当前 RPS */\n rps: number;\n /** 状态码分布 */\n statusCodes: StatusCodeDistribution;\n /** 时间窗口统计 */\n timeWindows: {\n /** 最近 1 分钟 */\n last1min: TimeWindowStats;\n /** 最近 5 分钟 */\n last5min: TimeWindowStats;\n /** 最近 1 小时 */\n last1hour: TimeWindowStats;\n };\n /** 按路径统计 */\n byPath: Record<string, PathStats>;\n /** 内存使用 */\n memoryUsage: {\n heapUsed: string;\n heapTotal: string;\n };\n /** 最近请求 */\n recentRequests: MonitoringMetrics[];\n}\n\n/** 带监控的 Server */\nexport interface MonitoredServer extends Server {\n getMonitoringStatus(): MonitoringStatus;\n getMonitoringMetrics(): MonitoringMetrics[];\n getPathStats(path: string): PathStats | undefined;\n getTimeWindowStats(windowMs: number): TimeWindowStats;\n getRPS(): number;\n getStatusCodeDistribution(): StatusCodeDistribution;\n resetMonitoring(): void;\n}\n\n// ========== 常量 ==========\n\nconst ONE_MINUTE = 60 * 1000;\nconst FIVE_MINUTES = 5 * 60 * 1000;\nconst ONE_HOUR = 60 * 60 * 1000;\n\n// ========== 环形缓冲区 ==========\n\nfunction createRingBuffer<T>(capacity: number) {\n const buffer: T[] = new Array(capacity);\n let head = 0;\n let size = 0;\n\n return {\n push(item: T) {\n buffer[head % capacity] = item;\n head++;\n if (size < capacity) size++;\n },\n\n toArray(): T[] {\n if (size === 0) return [];\n if (size < capacity) {\n return buffer.slice(0, size);\n }\n const start = head % capacity;\n return [...buffer.slice(start), ...buffer.slice(0, start)];\n },\n\n getSize: () => size,\n\n clear() {\n head = 0;\n size = 0;\n },\n\n recent(n: number): T[] {\n const arr = this.toArray();\n return arr.slice(-n);\n },\n };\n}\n\n// ========== 工具函数 ==========\n\nfunction generateRequestId(): string {\n return `req_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n\nfunction getMemoryInfo(): MemoryInfo {\n if (typeof process !== \"undefined\" && process.memoryUsage) {\n const mem = process.memoryUsage();\n return { heapUsed: mem.heapUsed, heapTotal: mem.heapTotal };\n }\n return { heapUsed: 0, heapTotal: 0 };\n}\n\nfunction formatMemory(bytes: number): string {\n return (bytes / 1024 / 1024).toFixed(2) + \"MB\";\n}\n\nfunction percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0;\n const index = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, index)];\n}\n\nfunction shouldExclude(path: string, excludePaths: string[]): boolean {\n return excludePaths.some(\n (p) =>\n path === p ||\n path.startsWith(p + \"/\") ||\n (p.endsWith(\"*\") && path.startsWith(p.slice(0, -1)))\n );\n}\n\nfunction getStatusCodeCategory(code: number): \"2xx\" | \"3xx\" | \"4xx\" | \"5xx\" {\n if (code >= 200 && code < 300) return \"2xx\";\n if (code >= 300 && code < 400) return \"3xx\";\n if (code >= 400 && code < 500) return \"4xx\";\n return \"5xx\";\n}\n\n// ========== 监控状态管理 ==========\n\nfunction createMonitorState(config: Required<MonitoringConfig>) {\n const buffer = createRingBuffer<MonitoringMetrics>(config.maxRecords);\n const pathStats = new Map<string, PathStats>();\n const startTime = Date.now();\n\n /** 获取时间窗口内的指标 */\n function getMetricsInWindow(windowMs: number): MonitoringMetrics[] {\n const now = Date.now();\n const cutoff = now - windowMs;\n return buffer.toArray().filter((m) => m.timestamp >= cutoff);\n }\n\n /** 计算时间窗口统计 */\n function calcTimeWindowStats(windowMs: number): TimeWindowStats {\n const metrics = getMetricsInWindow(windowMs);\n const count = metrics.length;\n\n if (count === 0) {\n return {\n requests: 0,\n successful: 0,\n failed: 0,\n errorRate: 0,\n avgTime: 0,\n rps: 0,\n };\n }\n\n const successful = metrics.filter((m) => m.statusCode < 400).length;\n const failed = count - successful;\n const avgTime = metrics.reduce((sum, m) => sum + m.totalTime, 0) / count;\n\n // 计算实际时间跨度(用于 RPS)\n const timestamps = metrics.map((m) => m.timestamp);\n const actualWindow = Math.max(...timestamps) - Math.min(...timestamps);\n const effectiveWindow = Math.max(actualWindow, 1000); // 至少 1 秒\n const rps = (count / effectiveWindow) * 1000;\n\n return {\n requests: count,\n successful,\n failed,\n errorRate: failed / count,\n avgTime: Number(avgTime.toFixed(2)),\n rps: Number(rps.toFixed(2)),\n };\n }\n\n /** 计算状态码分布 */\n function calcStatusCodeDistribution(): StatusCodeDistribution {\n const metrics = buffer.toArray();\n const dist: StatusCodeDistribution = {\n \"2xx\": 0,\n \"3xx\": 0,\n \"4xx\": 0,\n \"5xx\": 0,\n detail: {},\n };\n\n for (const m of metrics) {\n const category = getStatusCodeCategory(m.statusCode);\n dist[category]++;\n dist.detail[m.statusCode] = (dist.detail[m.statusCode] || 0) + 1;\n }\n\n return dist;\n }\n\n /** 计算当前 RPS(基于最近 10 秒) */\n function calcCurrentRPS(): number {\n const metrics = getMetricsInWindow(10000); // 最近 10 秒\n if (metrics.length === 0) return 0;\n return Number((metrics.length / 10).toFixed(2));\n }\n\n return {\n addMetrics(m: MonitoringMetrics) {\n buffer.push(m);\n\n // 更新路径统计\n const stats = pathStats.get(m.path) || {\n count: 0,\n totalTime: 0,\n avgTime: 0,\n minTime: Infinity,\n maxTime: 0,\n errorCount: 0,\n };\n\n stats.count++;\n stats.totalTime += m.totalTime;\n stats.avgTime = stats.totalTime / stats.count;\n stats.minTime = Math.min(stats.minTime, m.totalTime);\n stats.maxTime = Math.max(stats.maxTime, m.totalTime);\n if (m.statusCode >= 400) stats.errorCount++;\n\n pathStats.set(m.path, stats);\n },\n\n getMetrics: () => buffer.toArray(),\n\n getPathStats: (path: string) => pathStats.get(path),\n\n getTimeWindowStats: calcTimeWindowStats,\n\n getRPS: calcCurrentRPS,\n\n getStatusCodeDistribution: calcStatusCodeDistribution,\n\n reset() {\n buffer.clear();\n pathStats.clear();\n },\n\n getStatus(): MonitoringStatus {\n const metrics = buffer.toArray();\n const total = metrics.length;\n\n if (total === 0) {\n return {\n enabled: config.enabled,\n uptime: Date.now() - startTime,\n totalRequests: 0,\n successfulRequests: 0,\n failedRequests: 0,\n errorRate: 0,\n avgResponseTime: 0,\n p50: 0,\n p95: 0,\n p99: 0,\n minTime: 0,\n maxTime: 0,\n rps: 0,\n statusCodes: { \"2xx\": 0, \"3xx\": 0, \"4xx\": 0, \"5xx\": 0, detail: {} },\n timeWindows: {\n last1min: { requests: 0, successful: 0, failed: 0, errorRate: 0, avgTime: 0, rps: 0 },\n last5min: { requests: 0, successful: 0, failed: 0, errorRate: 0, avgTime: 0, rps: 0 },\n last1hour: { requests: 0, successful: 0, failed: 0, errorRate: 0, avgTime: 0, rps: 0 },\n },\n byPath: {},\n memoryUsage: { heapUsed: formatMemory(0), heapTotal: formatMemory(0) },\n recentRequests: [],\n };\n }\n\n const successful = metrics.filter((m) => m.statusCode < 400).length;\n const failed = total - successful;\n\n const times = metrics.map((m) => m.totalTime);\n const sortedTimes = [...times].sort((a, b) => a - b);\n const avgTime = times.reduce((a, b) => a + b, 0) / total;\n\n const mem = getMemoryInfo();\n\n const byPath: Record<string, PathStats> = {};\n pathStats.forEach((stats, path) => {\n byPath[path] = { ...stats, minTime: stats.minTime === Infinity ? 0 : stats.minTime };\n });\n\n return {\n enabled: config.enabled,\n uptime: Date.now() - startTime,\n totalRequests: total,\n successfulRequests: successful,\n failedRequests: failed,\n errorRate: Number((failed / total).toFixed(4)),\n avgResponseTime: Number(avgTime.toFixed(2)),\n p50: Number(percentile(sortedTimes, 50).toFixed(2)),\n p95: Number(percentile(sortedTimes, 95).toFixed(2)),\n p99: Number(percentile(sortedTimes, 99).toFixed(2)),\n minTime: Number(sortedTimes[0].toFixed(2)),\n maxTime: Number(sortedTimes[sortedTimes.length - 1].toFixed(2)),\n rps: calcCurrentRPS(),\n statusCodes: calcStatusCodeDistribution(),\n timeWindows: {\n last1min: calcTimeWindowStats(ONE_MINUTE),\n last5min: calcTimeWindowStats(FIVE_MINUTES),\n last1hour: calcTimeWindowStats(ONE_HOUR),\n },\n byPath,\n memoryUsage: {\n heapUsed: formatMemory(mem.heapUsed),\n heapTotal: formatMemory(mem.heapTotal),\n },\n recentRequests: buffer.recent(5),\n };\n },\n };\n}\n\n// ========== 日志输出 ==========\n\nfunction logRequest(\n metrics: MonitoringMetrics,\n slowThreshold: number,\n enabled: boolean\n) {\n if (!enabled) return;\n\n const status = metrics.statusCode < 400 ? \"✅\" : \"❌\";\n const speed = metrics.totalTime > slowThreshold ? \"🐌\" : \"⚡\";\n\n console.log(\n `${status} ${metrics.method} ${metrics.path} - ${metrics.statusCode} (${speed} ${metrics.totalTime.toFixed(2)}ms)`\n );\n}\n\n// ========== 主函数 ==========\n\nconst defaultConfig: Required<MonitoringConfig> = {\n enabled: true,\n console: true,\n slowThreshold: 1000,\n maxRecords: 1000,\n samplingRate: 1,\n excludePaths: [],\n tags: { framework: \"vafast\" },\n onRequest: () => {},\n onSlowRequest: () => {},\n};\n\n/**\n * 为 Server 添加监控能力\n *\n * @example\n * ```ts\n * const server = new Server(routes)\n * const monitored = withMonitoring(server, {\n * slowThreshold: 500,\n * excludePaths: ['/health'],\n * onSlowRequest: (m) => console.warn('Slow!', m.path)\n * })\n *\n * // 获取完整状态\n * const status = monitored.getMonitoringStatus()\n * console.log(`P99: ${status.p99}ms`)\n * console.log(`RPS: ${status.rps}`)\n * console.log(`Last 1min errors: ${status.timeWindows.last1min.errorRate}`)\n *\n * // 单独获取 RPS\n * console.log(`Current RPS: ${monitored.getRPS()}`)\n *\n * // 自定义时间窗口\n * const last30sec = monitored.getTimeWindowStats(30000)\n * ```\n */\nexport function withMonitoring(\n server: Server,\n config: MonitoringConfig = {}\n): MonitoredServer {\n const finalConfig = { ...defaultConfig, ...config };\n const state = createMonitorState(finalConfig);\n const originalFetch = server.fetch.bind(server);\n\n if (finalConfig.enabled && finalConfig.console) {\n console.log(\"✅ Monitoring enabled\");\n console.log(`📊 Config:`, {\n slowThreshold: `${finalConfig.slowThreshold}ms`,\n maxRecords: finalConfig.maxRecords,\n samplingRate: finalConfig.samplingRate,\n excludePaths: finalConfig.excludePaths,\n });\n }\n\n const monitoredFetch = async (req: Request): Promise<Response> => {\n if (!finalConfig.enabled) {\n return originalFetch(req);\n }\n\n const { pathname } = new URL(req.url);\n\n if (shouldExclude(pathname, finalConfig.excludePaths)) {\n return originalFetch(req);\n }\n\n if (finalConfig.samplingRate < 1 && Math.random() > finalConfig.samplingRate) {\n return originalFetch(req);\n }\n\n const startTime = performance.now();\n const requestId = generateRequestId();\n const method = req.method;\n\n let statusCode = 500;\n try {\n const response = await originalFetch(req);\n statusCode = response.status;\n return response;\n } finally {\n const totalTime = performance.now() - startTime;\n const metrics: MonitoringMetrics = {\n requestId,\n method,\n path: pathname,\n statusCode,\n totalTime,\n timestamp: Date.now(),\n memoryUsage: getMemoryInfo(),\n };\n\n state.addMetrics(metrics);\n logRequest(metrics, finalConfig.slowThreshold, finalConfig.console);\n\n finalConfig.onRequest(metrics);\n if (totalTime > finalConfig.slowThreshold) {\n finalConfig.onSlowRequest(metrics);\n }\n }\n };\n\n return {\n ...server,\n fetch: monitoredFetch,\n getMonitoringStatus: state.getStatus,\n getMonitoringMetrics: state.getMetrics,\n getPathStats: state.getPathStats,\n getTimeWindowStats: state.getTimeWindowStats,\n getRPS: state.getRPS,\n getStatusCodeDistribution: state.getStatusCodeDistribution,\n resetMonitoring: state.reset,\n } as MonitoredServer;\n}\n\n/**\n * 创建带监控的 Server(便捷函数)\n */\nexport function createMonitoredServer(\n ServerClass: typeof Server,\n routes: ConstructorParameters<typeof Server>[0],\n config?: MonitoringConfig\n): MonitoredServer {\n const server = new ServerClass(routes);\n return withMonitoring(server, config);\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a as createAdaptorServer, i as ServeResult, o as serve, r as ServeOptions, t as FetchHandler } from "../serve-B5WmhK6m.mjs";
1
+ import { a as createAdaptorServer, i as ServeResult, o as serve, r as ServeOptions, t as FetchHandler } from "../serve-AG80VaIr.mjs";
2
2
  import { createProxyRequest } from "./request.mjs";
3
3
  import { writeResponse, writeResponseSimple } from "./response.mjs";
4
4
  export { type FetchHandler, type ServeOptions, type ServeResult, createAdaptorServer, createProxyRequest, serve, writeResponse, writeResponseSimple };
@@ -1,5 +1,5 @@
1
- import { t as createProxyRequest } from "../request-B886yCvG.mjs";
2
- import { n as writeResponseSimple, t as writeResponse } from "../response-30WnzABq.mjs";
3
- import { n as serve, t as createAdaptorServer } from "../serve-DgWBnexE.mjs";
1
+ import { t as createProxyRequest } from "../request-B-Nct5f7.mjs";
2
+ import { n as writeResponseSimple, t as writeResponse } from "../response-BnkYA4pj.mjs";
3
+ import { n as serve, t as createAdaptorServer } from "../serve-48LEIkPa.mjs";
4
4
 
5
5
  export { createAdaptorServer, createProxyRequest, serve, writeResponse, writeResponseSimple };
@@ -1,3 +1,3 @@
1
- import { t as createProxyRequest } from "../request-B886yCvG.mjs";
1
+ import { t as createProxyRequest } from "../request-B-Nct5f7.mjs";
2
2
 
3
3
  export { createProxyRequest };
@@ -1,3 +1,3 @@
1
- import { n as writeResponseSimple, t as writeResponse } from "../response-30WnzABq.mjs";
1
+ import { n as writeResponseSimple, t as writeResponse } from "../response-BnkYA4pj.mjs";
2
2
 
3
3
  export { writeResponse, writeResponseSimple };
@@ -1,2 +1,2 @@
1
- import { a as createAdaptorServer, i as ServeResult, n as GracefulShutdownOptions, o as serve, r as ServeOptions, t as FetchHandler } from "../serve-B5WmhK6m.mjs";
1
+ import { a as createAdaptorServer, i as ServeResult, n as GracefulShutdownOptions, o as serve, r as ServeOptions, t as FetchHandler } from "../serve-AG80VaIr.mjs";
2
2
  export { FetchHandler, GracefulShutdownOptions, ServeOptions, ServeResult, createAdaptorServer, serve };
@@ -1,4 +1,4 @@
1
- import "../request-B886yCvG.mjs";
2
- import { n as serve, t as createAdaptorServer } from "../serve-DgWBnexE.mjs";
1
+ import "../request-B-Nct5f7.mjs";
2
+ import { n as serve, t as createAdaptorServer } from "../serve-48LEIkPa.mjs";
3
3
 
4
4
  export { createAdaptorServer, serve };
@@ -55,4 +55,4 @@ declare function parseCookiesFast(req: Request): Record<string, string>;
55
55
  declare function getCookie(req: Request, name: string): string | null;
56
56
  //#endregion
57
57
  export { parseBody as a, parseCookiesFast as c, parseHeaders as d, parseQuery as f, getHeader as i, parseFile as l, FormData as n, parseBodyAs as o, parseQueryFast as p, getCookie as r, parseCookies as s, FileInfo as t, parseFormData as u };
58
- //# sourceMappingURL=parsers-7lvt3Oss.d.mts.map
58
+ //# sourceMappingURL=parsers-BerGr2_q.d.mts.map
@@ -165,4 +165,4 @@ function getCookie(req, name) {
165
165
 
166
166
  //#endregion
167
167
  export { parseCookies as a, parseFormData as c, parseQueryFast as d, parseBodyAs as i, parseHeaders as l, getHeader as n, parseCookiesFast as o, parseBody as r, parseFile as s, getCookie as t, parseQuery as u };
168
- //# sourceMappingURL=parsers-BQ63b0YE.mjs.map
168
+ //# sourceMappingURL=parsers-DpH_mD0H.mjs.map