@push.rocks/smartproxy 19.5.26 → 19.6.1
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/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts/proxies/http-proxy/function-cache.d.ts +5 -0
- package/dist_ts/proxies/http-proxy/function-cache.js +19 -2
- package/dist_ts/proxies/http-proxy/http-proxy.js +5 -1
- package/dist_ts/proxies/http-proxy/request-handler.d.ts +5 -0
- package/dist_ts/proxies/http-proxy/request-handler.js +27 -2
- package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +80 -0
- package/dist_ts/proxies/smart-proxy/metrics-collector.js +239 -0
- package/dist_ts/proxies/smart-proxy/models/index.d.ts +1 -0
- package/dist_ts/proxies/smart-proxy/models/index.js +2 -1
- package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +55 -0
- package/dist_ts/proxies/smart-proxy/models/metrics-types.js +2 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +2 -2
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +14 -6
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +12 -2
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +17 -1
- package/package.json +18 -8
- package/readme.md +118 -0
- package/readme.memory-leaks-fixed.md +45 -0
- package/readme.metrics.md +591 -0
- package/ts/plugins.ts +2 -0
- package/ts/proxies/http-proxy/function-cache.ts +21 -1
- package/ts/proxies/http-proxy/http-proxy.ts +5 -0
- package/ts/proxies/http-proxy/request-handler.ts +32 -1
- package/ts/proxies/smart-proxy/metrics-collector.ts +289 -0
- package/ts/proxies/smart-proxy/models/index.ts +1 -0
- package/ts/proxies/smart-proxy/models/metrics-types.ts +54 -0
- package/ts/proxies/smart-proxy/route-connection-handler.ts +18 -5
- package/ts/proxies/smart-proxy/smart-proxy.ts +27 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartproxy",
|
|
3
|
-
"version": "19.
|
|
3
|
+
"version": "19.6.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
"type": "module",
|
|
9
9
|
"author": "Lossless GmbH",
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "(tstest test/**/test*.ts --verbose --timeout 60 --logfile)",
|
|
13
|
+
"build": "(tsbuild tsfolders --allowimplicitany)",
|
|
14
|
+
"format": "(gitzone format)",
|
|
15
|
+
"buildDocs": "tsdoc"
|
|
16
|
+
},
|
|
11
17
|
"devDependencies": {
|
|
12
18
|
"@git.zone/tsbuild": "^2.6.4",
|
|
13
19
|
"@git.zone/tsrun": "^1.2.44",
|
|
@@ -25,6 +31,7 @@
|
|
|
25
31
|
"@push.rocks/smartnetwork": "^4.0.2",
|
|
26
32
|
"@push.rocks/smartpromise": "^4.2.3",
|
|
27
33
|
"@push.rocks/smartrequest": "^2.1.0",
|
|
34
|
+
"@push.rocks/smartrx": "^3.0.10",
|
|
28
35
|
"@push.rocks/smartstring": "^4.0.15",
|
|
29
36
|
"@push.rocks/taskbuffer": "^3.1.7",
|
|
30
37
|
"@tsclass/tsclass": "^9.2.0",
|
|
@@ -74,10 +81,13 @@
|
|
|
74
81
|
"bugs": {
|
|
75
82
|
"url": "https://code.foss.global/push.rocks/smartproxy/issues"
|
|
76
83
|
},
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
"pnpm": {
|
|
85
|
+
"overrides": {},
|
|
86
|
+
"onlyBuiltDependencies": [
|
|
87
|
+
"esbuild",
|
|
88
|
+
"mongodb-memory-server",
|
|
89
|
+
"puppeteer"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
|
|
93
|
+
}
|
package/readme.md
CHANGED
|
@@ -919,6 +919,124 @@ Available helper functions:
|
|
|
919
919
|
})
|
|
920
920
|
```
|
|
921
921
|
|
|
922
|
+
## Metrics and Monitoring
|
|
923
|
+
|
|
924
|
+
SmartProxy includes a comprehensive metrics collection system that provides real-time insights into proxy performance, connection statistics, and throughput data.
|
|
925
|
+
|
|
926
|
+
### Getting Metrics
|
|
927
|
+
|
|
928
|
+
```typescript
|
|
929
|
+
const proxy = new SmartProxy({ /* config */ });
|
|
930
|
+
await proxy.start();
|
|
931
|
+
|
|
932
|
+
// Access metrics through the getStats() method
|
|
933
|
+
const stats = proxy.getStats();
|
|
934
|
+
|
|
935
|
+
// Get current active connections
|
|
936
|
+
console.log(`Active connections: ${stats.getActiveConnections()}`);
|
|
937
|
+
|
|
938
|
+
// Get total connections since start
|
|
939
|
+
console.log(`Total connections: ${stats.getTotalConnections()}`);
|
|
940
|
+
|
|
941
|
+
// Get requests per second (RPS)
|
|
942
|
+
console.log(`Current RPS: ${stats.getRequestsPerSecond()}`);
|
|
943
|
+
|
|
944
|
+
// Get throughput data
|
|
945
|
+
const throughput = stats.getThroughput();
|
|
946
|
+
console.log(`Bytes received: ${throughput.bytesIn}`);
|
|
947
|
+
console.log(`Bytes sent: ${throughput.bytesOut}`);
|
|
948
|
+
|
|
949
|
+
// Get connections by route
|
|
950
|
+
const routeConnections = stats.getConnectionsByRoute();
|
|
951
|
+
for (const [route, count] of routeConnections) {
|
|
952
|
+
console.log(`Route ${route}: ${count} connections`);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// Get connections by IP address
|
|
956
|
+
const ipConnections = stats.getConnectionsByIP();
|
|
957
|
+
for (const [ip, count] of ipConnections) {
|
|
958
|
+
console.log(`IP ${ip}: ${count} connections`);
|
|
959
|
+
}
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
### Available Metrics
|
|
963
|
+
|
|
964
|
+
The `IProxyStats` interface provides the following methods:
|
|
965
|
+
|
|
966
|
+
- `getActiveConnections()`: Current number of active connections
|
|
967
|
+
- `getTotalConnections()`: Total connections handled since proxy start
|
|
968
|
+
- `getRequestsPerSecond()`: Current requests per second (1-minute average)
|
|
969
|
+
- `getThroughput()`: Total bytes transferred (in/out)
|
|
970
|
+
- `getConnectionsByRoute()`: Connection count per route
|
|
971
|
+
- `getConnectionsByIP()`: Connection count per client IP
|
|
972
|
+
|
|
973
|
+
### Monitoring Example
|
|
974
|
+
|
|
975
|
+
```typescript
|
|
976
|
+
// Create a monitoring loop
|
|
977
|
+
setInterval(() => {
|
|
978
|
+
const stats = proxy.getStats();
|
|
979
|
+
|
|
980
|
+
// Log key metrics
|
|
981
|
+
console.log({
|
|
982
|
+
timestamp: new Date().toISOString(),
|
|
983
|
+
activeConnections: stats.getActiveConnections(),
|
|
984
|
+
rps: stats.getRequestsPerSecond(),
|
|
985
|
+
throughput: stats.getThroughput()
|
|
986
|
+
});
|
|
987
|
+
|
|
988
|
+
// Check for high connection counts from specific IPs
|
|
989
|
+
const ipConnections = stats.getConnectionsByIP();
|
|
990
|
+
for (const [ip, count] of ipConnections) {
|
|
991
|
+
if (count > 100) {
|
|
992
|
+
console.warn(`High connection count from ${ip}: ${count}`);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}, 10000); // Every 10 seconds
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
### Exporting Metrics
|
|
999
|
+
|
|
1000
|
+
You can export metrics in various formats for external monitoring systems:
|
|
1001
|
+
|
|
1002
|
+
```typescript
|
|
1003
|
+
// Export as JSON
|
|
1004
|
+
app.get('/metrics.json', (req, res) => {
|
|
1005
|
+
const stats = proxy.getStats();
|
|
1006
|
+
res.json({
|
|
1007
|
+
activeConnections: stats.getActiveConnections(),
|
|
1008
|
+
totalConnections: stats.getTotalConnections(),
|
|
1009
|
+
requestsPerSecond: stats.getRequestsPerSecond(),
|
|
1010
|
+
throughput: stats.getThroughput(),
|
|
1011
|
+
connectionsByRoute: Object.fromEntries(stats.getConnectionsByRoute()),
|
|
1012
|
+
connectionsByIP: Object.fromEntries(stats.getConnectionsByIP())
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
// Export as Prometheus format
|
|
1017
|
+
app.get('/metrics', (req, res) => {
|
|
1018
|
+
const stats = proxy.getStats();
|
|
1019
|
+
res.set('Content-Type', 'text/plain');
|
|
1020
|
+
res.send(`
|
|
1021
|
+
# HELP smartproxy_active_connections Current active connections
|
|
1022
|
+
# TYPE smartproxy_active_connections gauge
|
|
1023
|
+
smartproxy_active_connections ${stats.getActiveConnections()}
|
|
1024
|
+
|
|
1025
|
+
# HELP smartproxy_requests_per_second Current requests per second
|
|
1026
|
+
# TYPE smartproxy_requests_per_second gauge
|
|
1027
|
+
smartproxy_requests_per_second ${stats.getRequestsPerSecond()}
|
|
1028
|
+
|
|
1029
|
+
# HELP smartproxy_bytes_in Total bytes received
|
|
1030
|
+
# TYPE smartproxy_bytes_in counter
|
|
1031
|
+
smartproxy_bytes_in ${stats.getThroughput().bytesIn}
|
|
1032
|
+
|
|
1033
|
+
# HELP smartproxy_bytes_out Total bytes sent
|
|
1034
|
+
# TYPE smartproxy_bytes_out counter
|
|
1035
|
+
smartproxy_bytes_out ${stats.getThroughput().bytesOut}
|
|
1036
|
+
`);
|
|
1037
|
+
});
|
|
1038
|
+
```
|
|
1039
|
+
|
|
922
1040
|
## Other Components
|
|
923
1041
|
|
|
924
1042
|
While SmartProxy provides a unified API for most needs, you can also use individual components:
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Memory Leaks Fixed in SmartProxy
|
|
2
|
+
|
|
3
|
+
## Summary of Issues Found and Fixed
|
|
4
|
+
|
|
5
|
+
### 1. MetricsCollector - Request Timestamps Array
|
|
6
|
+
**Issue**: The `requestTimestamps` array could grow to 10,000 entries before cleanup, causing unnecessary memory usage.
|
|
7
|
+
**Fix**: Reduced threshold to 5,000 and more aggressive cleanup when exceeded.
|
|
8
|
+
|
|
9
|
+
### 2. RouteConnectionHandler - Unused Route Context Cache
|
|
10
|
+
**Issue**: Declared `routeContextCache` Map that was never used but could be confusing.
|
|
11
|
+
**Fix**: Removed the unused cache and added documentation explaining why caching wasn't implemented.
|
|
12
|
+
|
|
13
|
+
### 3. FunctionCache - Uncleaned Interval Timer
|
|
14
|
+
**Issue**: The cache cleanup interval was never cleared, preventing proper garbage collection.
|
|
15
|
+
**Fix**: Added `destroy()` method to properly clear the interval timer.
|
|
16
|
+
|
|
17
|
+
### 4. HttpProxy/RequestHandler - Uncleaned Rate Limit Cleanup Timer
|
|
18
|
+
**Issue**: The RequestHandler creates a setInterval for rate limit cleanup that's never cleared.
|
|
19
|
+
**Status**: Needs fix - add destroy method and call it from HttpProxy.stop()
|
|
20
|
+
|
|
21
|
+
## Memory Leak Test
|
|
22
|
+
|
|
23
|
+
A comprehensive memory leak test was created at `test/test.memory-leak-check.node.ts` that:
|
|
24
|
+
- Tests with 1000 requests to same routes
|
|
25
|
+
- Tests with 1000 requests to different routes (cache growth)
|
|
26
|
+
- Tests rapid 10,000 requests (timestamp array growth)
|
|
27
|
+
- Monitors memory usage throughout
|
|
28
|
+
- Verifies specific data structures don't grow unbounded
|
|
29
|
+
|
|
30
|
+
## Recommendations
|
|
31
|
+
|
|
32
|
+
1. Always use `unref()` on intervals that shouldn't keep the process alive
|
|
33
|
+
2. Always provide cleanup/destroy methods for classes that create timers
|
|
34
|
+
3. Implement size limits on all caches and Maps
|
|
35
|
+
4. Consider using WeakMap for caches where appropriate
|
|
36
|
+
5. Run memory leak tests regularly, especially after adding new features
|
|
37
|
+
|
|
38
|
+
## Running the Memory Leak Test
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Run with garbage collection exposed for accurate measurements
|
|
42
|
+
node --expose-gc test/test.memory-leak-check.node.ts
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The test will monitor memory usage and fail if memory growth exceeds acceptable thresholds.
|