Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e837419d5d | |||
| 487a603fa3 | |||
| d6fdd3fc86 | |||
| 344f224c89 | |||
| 6bbd2b3ee1 |
12
changelog.md
12
changelog.md
@@ -1,5 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-02-14 - 25.2.2 - fix(smart-proxy)
|
||||
start metrics polling before certificate provisioning to avoid blocking metrics collection
|
||||
|
||||
- Start metrics polling immediately after Rust engine startup so metrics are available without waiting for certificate provisioning.
|
||||
- Run certProvisionFunction after startup because ACME/DNS-01 provisioning can hang or be slow and must not block observability.
|
||||
- Code change in ts/proxies/smart-proxy/smart-proxy.ts: metricsAdapter.startPolling() moved to run before provisionCertificatesViaCallback().
|
||||
|
||||
## 2026-02-14 - 25.2.1 - fix(smartproxy)
|
||||
no changes detected in git diff
|
||||
|
||||
- The provided diff contains no file changes; no code or documentation updates to release.
|
||||
|
||||
## 2026-02-14 - 25.2.0 - feat(metrics)
|
||||
add per-IP and HTTP-request metrics, propagate source IP through proxy paths, and expose new metrics to the TS adapter
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@push.rocks/smartproxy",
|
||||
"version": "25.2.0",
|
||||
"version": "25.2.2",
|
||||
"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",
|
||||
|
||||
@@ -168,6 +168,22 @@ tap.test('TCP forward - real-time byte tracking', async (tools) => {
|
||||
const byRoute = m.throughput.byRoute();
|
||||
console.log('TCP forward — throughput byRoute:', Array.from(byRoute.entries()));
|
||||
|
||||
// ── v25.2.0: Per-IP tracking (TCP connections) ──
|
||||
const byIP = m.connections.byIP();
|
||||
console.log('TCP forward — connections byIP:', Array.from(byIP.entries()));
|
||||
expect(byIP.size).toBeGreaterThan(0);
|
||||
|
||||
const topIPs = m.connections.topIPs(10);
|
||||
console.log('TCP forward — topIPs:', topIPs);
|
||||
expect(topIPs.length).toBeGreaterThan(0);
|
||||
expect(topIPs[0].ip).toBeTruthy();
|
||||
|
||||
// ── v25.2.0: Throughput history ──
|
||||
const history = m.throughput.history(10);
|
||||
console.log('TCP forward — throughput history length:', history.length);
|
||||
expect(history.length).toBeGreaterThan(0);
|
||||
expect(history[0].timestamp).toBeGreaterThan(0);
|
||||
|
||||
await proxy.stop();
|
||||
await tools.delayFor(200);
|
||||
});
|
||||
@@ -233,6 +249,22 @@ tap.test('HTTP forward - byte totals tracking', async (tools) => {
|
||||
expect(bytesIn).toBeGreaterThan(0);
|
||||
expect(bytesOut).toBeGreaterThan(0);
|
||||
|
||||
// ── v25.2.0: Per-IP tracking (HTTP connections) ──
|
||||
const byIP = m.connections.byIP();
|
||||
console.log('HTTP forward — connections byIP:', Array.from(byIP.entries()));
|
||||
expect(byIP.size).toBeGreaterThan(0);
|
||||
|
||||
const topIPs = m.connections.topIPs(10);
|
||||
console.log('HTTP forward — topIPs:', topIPs);
|
||||
expect(topIPs.length).toBeGreaterThan(0);
|
||||
expect(topIPs[0].ip).toBeTruthy();
|
||||
|
||||
// ── v25.2.0: HTTP request counting ──
|
||||
const totalReqs = m.requests.total();
|
||||
const rps = m.requests.perSecond();
|
||||
console.log(`HTTP forward — requests total: ${totalReqs}, perSecond: ${rps}`);
|
||||
expect(totalReqs).toBeGreaterThan(0);
|
||||
|
||||
await proxy.stop();
|
||||
await tools.delayFor(200);
|
||||
});
|
||||
@@ -607,6 +639,37 @@ tap.test('Throughput sampling - values appear during active HTTP traffic', async
|
||||
console.log(`Sampling test — recent throughput: in=${tpRecent.in}, out=${tpRecent.out}`);
|
||||
expect(tpRecent.in + tpRecent.out).toBeGreaterThan(0);
|
||||
|
||||
// ── v25.2.0: Per-IP tracking ──
|
||||
const byIP = m.connections.byIP();
|
||||
console.log('Sampling test — connections byIP:', Array.from(byIP.entries()));
|
||||
expect(byIP.size).toBeGreaterThan(0);
|
||||
|
||||
const topIPs = m.connections.topIPs(10);
|
||||
console.log('Sampling test — topIPs:', topIPs);
|
||||
expect(topIPs.length).toBeGreaterThan(0);
|
||||
expect(topIPs[0].ip).toBeTruthy();
|
||||
expect(topIPs[0].count).toBeGreaterThanOrEqual(0);
|
||||
|
||||
// ── v25.2.0: Throughput history ──
|
||||
const history = m.throughput.history(10);
|
||||
console.log(`Sampling test — throughput history: ${history.length} points`);
|
||||
if (history.length > 0) {
|
||||
console.log(' first:', history[0], 'last:', history[history.length - 1]);
|
||||
}
|
||||
expect(history.length).toBeGreaterThan(0);
|
||||
expect(history[0].timestamp).toBeGreaterThan(0);
|
||||
|
||||
// ── v25.2.0: Per-IP throughput ──
|
||||
const tpByIP = m.throughput.byIP();
|
||||
console.log('Sampling test — throughput byIP:', Array.from(tpByIP.entries()));
|
||||
|
||||
// ── v25.2.0: HTTP request counting ──
|
||||
const totalReqs = m.requests.total();
|
||||
const rps = m.requests.perSecond();
|
||||
const rpm = m.requests.perMinute();
|
||||
console.log(`Sampling test — HTTP requests: total=${totalReqs}, perSecond=${rps}, perMinute=${rpm}`);
|
||||
expect(totalReqs).toBeGreaterThan(0);
|
||||
|
||||
// Stop sending
|
||||
sending = false;
|
||||
await sendLoop;
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartproxy',
|
||||
version: '25.2.0',
|
||||
version: '25.2.2',
|
||||
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.'
|
||||
}
|
||||
|
||||
@@ -191,13 +191,16 @@ export class SmartProxy extends plugins.EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle certProvisionFunction
|
||||
await this.provisionCertificatesViaCallback(preloadedDomains);
|
||||
|
||||
// Start metrics polling
|
||||
// Start metrics polling BEFORE cert provisioning — the Rust engine is already
|
||||
// running and accepting connections, so metrics should be available immediately.
|
||||
// Cert provisioning can hang indefinitely (e.g. DNS-01 ACME timeouts) and must
|
||||
// not block metrics collection.
|
||||
this.metricsAdapter.startPolling();
|
||||
|
||||
logger.log('info', 'SmartProxy started (Rust engine)', { component: 'smart-proxy' });
|
||||
|
||||
// Handle certProvisionFunction (may be slow — runs after startup is complete)
|
||||
await this.provisionCertificatesViaCallback(preloadedDomains);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user