Compare commits

...

2 Commits

Author SHA1 Message Date
f82d44164c 19.6.16
Some checks failed
Default (tags) / security (push) Successful in 1m20s
Default (tags) / test (push) Failing after 29m31s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-07-03 03:17:35 +00:00
2a4ed38f6b update logs 2025-07-03 02:54:56 +00:00
4 changed files with 21 additions and 4 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartproxy",
"version": "19.6.15",
"version": "19.6.16",
"private": false,
"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.",
"main": "dist_ts/index.js",

View File

@ -276,7 +276,7 @@ Connection rejected
You'll see:
```
[SUMMARY] Rejected 500 connections from 10 IPs in 5s (top offenders: 192.168.1.100 (200x, rate-limit), 10.0.0.1 (150x, per-ip-limit))
[SUMMARY] Rejected 500 connections from 10 IPs in 5s (rate-limit: 350, per-ip-limit: 150) (top offenders: 192.168.1.100 (200x, rate-limit), 10.0.0.1 (150x, per-ip-limit))
```
Instead of:

View File

@ -37,9 +37,17 @@ Command to re-read CLAUDE.md: `cat /home/philkunz/.claude/CLAUDE.md`
- [x] Test cleanup queue edge cases
- [x] Test memory usage with many unique IPs
### 6. Log Deduplication for High-Volume Scenarios ✓
- [x] Implement LogDeduplicator utility for batching similar events
- [x] Add deduplication for connection rejections, terminations, and cleanups
- [x] Include rejection reasons in IP rejection summaries
- [x] Provide aggregated summaries with meaningful context
## Notes
- All connection limiting is now consistent across SmartProxy and HttpProxy
- Route-level limits provide additional granular control
- Memory usage is optimized for high-traffic scenarios
- Comprehensive test coverage ensures reliability
- Log deduplication reduces spam during attacks or high-traffic periods
- IP rejection summaries now include rejection reasons in main message

View File

@ -269,6 +269,7 @@ export class LogDeduplicator {
private flushIPRejections(aggregated: IAggregatedEvent): void {
const byIP = new Map<string, { count: number; reasons: Set<string> }>();
const allReasons = new Map<string, number>();
for (const [ip, event] of aggregated.events) {
if (!byIP.has(ip)) {
@ -278,9 +279,17 @@ export class LogDeduplicator {
ipData.count += event.count;
if (event.data?.reason) {
ipData.reasons.add(event.data.reason);
// Track overall reason counts
allReasons.set(event.data.reason, (allReasons.get(event.data.reason) || 0) + event.count);
}
}
// Create reason summary
const reasonSummary = Array.from(allReasons.entries())
.sort((a, b) => b[1] - a[1])
.map(([reason, count]) => `${reason}: ${count}`)
.join(', ');
// Log top offenders
const topOffenders = Array.from(byIP.entries())
.sort((a, b) => b[1].count - a[1].count)
@ -291,7 +300,7 @@ export class LogDeduplicator {
const totalRejections = Array.from(byIP.values()).reduce((sum, data) => sum + data.count, 0);
const duration = Date.now() - Math.min(...Array.from(aggregated.events.values()).map(e => e.firstSeen));
logger.log('warn', `[SUMMARY] Rejected ${totalRejections} connections from ${byIP.size} IPs in ${Math.round(duration/1000)}s`, {
logger.log('warn', `[SUMMARY] Rejected ${totalRejections} connections from ${byIP.size} IPs in ${Math.round(duration/1000)}s (${reasonSummary})`, {
topOffenders,
component: 'ip-dedup'
});