From 0fbd8d1cdd744b7ccf43a3ccd479fdfd2e7427ae Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Sat, 21 Feb 2026 23:36:10 +0000 Subject: [PATCH] fix(logging): add adaptive rate-limited DNS query logging, flush pending DNS logs on shutdown, and enhance email delivery logging --- changelog.md | 9 +++++++ package.json | 2 +- pnpm-lock.yaml | 12 ++++----- ts/00_commitinfo_data.ts | 2 +- ts/classes.dcrouter.ts | 48 ++++++++++++++++++++++++++++++++++-- ts_web/00_commitinfo_data.ts | 2 +- 6 files changed, 64 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index 1a1de85..f750439 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ # Changelog +## 2026-02-21 - 7.4.3 - fix(logging) +add adaptive rate-limited DNS query logging, flush pending DNS logs on shutdown, and enhance email delivery logging + +- Introduce adaptive DNS logging: allow up to 2 individual DNS query logs per second, then aggregate further queries and emit a batched summary (dnsLogWindow, dnsBatchCount, dnsBatchTimer) with a 5s flush. +- Flush pending DNS batch on stop() and log final DNS batch count during shutdown. +- Enhance email observability by logging deliveryStart, deliverySuccess, deliveryFailed and bounceProcessed events alongside existing MetricsManager tracking. +- Dependency bump: @design.estate/dees-catalog updated from ^3.43.1 to ^3.43.2. +- Non-breaking change; intended as a patch release. + ## 2026-02-21 - 7.4.2 - fix(monitoring,remoteingress,web) Prune old metrics buckets periodically, clear metrics caches on shutdown, simplify edge disconnect handling, and optimize network view data updates diff --git a/package.json b/package.json index cfa0f7d..d699b56 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@api.global/typedserver": "^8.3.0", "@api.global/typedsocket": "^4.1.0", "@apiclient.xyz/cloudflare": "^7.1.0", - "@design.estate/dees-catalog": "^3.43.1", + "@design.estate/dees-catalog": "^3.43.2", "@design.estate/dees-element": "^2.1.6", "@push.rocks/projectinfo": "^5.0.2", "@push.rocks/qenv": "^6.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e1d0af..0397089 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: ^7.1.0 version: 7.1.0 '@design.estate/dees-catalog': - specifier: ^3.43.1 - version: 3.43.1(@tiptap/pm@2.27.2) + specifier: ^3.43.2 + version: 3.43.2(@tiptap/pm@2.27.2) '@design.estate/dees-element': specifier: ^2.1.6 version: 2.1.6 @@ -351,8 +351,8 @@ packages: '@configvault.io/interfaces@1.0.17': resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==} - '@design.estate/dees-catalog@3.43.1': - resolution: {integrity: sha512-WAWOV8dIgdKfAbS4Ciek8oDVIWC0OSPODhpQdLlsGBXERcFaBPaYxcpywmrjXB/TFeoAQPxBxhS7jb9/p2Rprg==} + '@design.estate/dees-catalog@3.43.2': + resolution: {integrity: sha512-7pU+K+B70SxqR4DrBkpc/xvQGLDkxAV2jH7Qyh0TYgkCoxxjsxCuTMKM9JguA38wm6bEgBJVTvyg5S3wCwxm4Q==} '@design.estate/dees-comms@1.0.30': resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==} @@ -4334,7 +4334,7 @@ snapshots: '@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@2.0.1) '@cloudflare/workers-types': 4.20260210.0 - '@design.estate/dees-catalog': 3.43.1(@tiptap/pm@2.27.2) + '@design.estate/dees-catalog': 3.43.2(@tiptap/pm@2.27.2) '@design.estate/dees-comms': 1.0.30 '@push.rocks/lik': 6.2.2 '@push.rocks/smartdelay': 3.0.5 @@ -4932,7 +4932,7 @@ snapshots: dependencies: '@api.global/typedrequest-interfaces': 3.0.19 - '@design.estate/dees-catalog@3.43.1(@tiptap/pm@2.27.2)': + '@design.estate/dees-catalog@3.43.2(@tiptap/pm@2.27.2)': dependencies: '@design.estate/dees-domtools': 2.3.8 '@design.estate/dees-element': 2.1.6 diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 10ee0d4..65402a8 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '7.4.2', + version: '7.4.3', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts/classes.dcrouter.ts b/ts/classes.dcrouter.ts index 3ebe671..7c32156 100644 --- a/ts/classes.dcrouter.ts +++ b/ts/classes.dcrouter.ts @@ -212,6 +212,11 @@ export class DcRouter { public remoteIngressManager?: RemoteIngressManager; public tunnelManager?: TunnelManager; + // DNS query logging rate limiter state + private dnsLogWindow: number[] = []; + private dnsBatchCount: number = 0; + private dnsBatchTimer: ReturnType | null = null; + // Certificate status tracking from SmartProxy events (keyed by domain) public certificateStatusMap = new Map 0) { + logger.log('info', `DNS: ${this.dnsBatchCount} queries processed (rate limited, final flush)`, { zone: 'dns' }); + } + this.dnsBatchTimer = null; + this.dnsBatchCount = 0; + this.dnsLogWindow = []; + } + await this.opsServer.stop(); try { @@ -1002,21 +1018,25 @@ export class DcRouter { // Start the server await this.emailServer.start(); - // Wire delivery events to MetricsManager for time-series tracking + // Wire delivery events to MetricsManager and logger if (this.metricsManager && this.emailServer.deliverySystem) { this.emailServer.deliverySystem.on('deliveryStart', (item: any) => { this.metricsManager.trackEmailReceived(item?.from); + logger.log('info', `Email delivery started: ${item?.from} → ${item?.to}`, { zone: 'email' }); }); this.emailServer.deliverySystem.on('deliverySuccess', (item: any) => { this.metricsManager.trackEmailSent(item?.to); + logger.log('info', `Email delivered to ${item?.to}`, { zone: 'email' }); }); this.emailServer.deliverySystem.on('deliveryFailed', (item: any, error: any) => { this.metricsManager.trackEmailFailed(item?.to, error?.message); + logger.log('warn', `Email delivery failed to ${item?.to}: ${error?.message}`, { zone: 'email' }); }); } if (this.metricsManager && this.emailServer) { this.emailServer.on('bounceProcessed', () => { this.metricsManager.trackEmailBounced(); + logger.log('warn', 'Email bounce processed', { zone: 'email' }); }); } @@ -1203,9 +1223,18 @@ export class DcRouter { await this.dnsServer.start(); logger.log('info', `DNS server started on UDP ${vmIpAddress}:53`); - // Wire DNS query events to MetricsManager for time-series tracking + // Wire DNS query events to MetricsManager and logger with adaptive rate limiting if (this.metricsManager && this.dnsServer) { + const flushDnsBatch = () => { + if (this.dnsBatchCount > 0) { + logger.log('info', `DNS: ${this.dnsBatchCount} queries processed (rate limited)`, { zone: 'dns' }); + this.dnsBatchCount = 0; + } + this.dnsBatchTimer = null; + }; + this.dnsServer.on('query', (event: plugins.smartdns.dnsServerMod.IDnsQueryCompletedEvent) => { + // Metrics tracking for (const question of event.questions) { this.metricsManager.trackDnsQuery( question.type, @@ -1215,6 +1244,21 @@ export class DcRouter { event.answered, ); } + + // Adaptive logging: individual logs up to 2/sec, then batch + const now = Date.now(); + this.dnsLogWindow = this.dnsLogWindow.filter(t => now - t < 1000); + + if (this.dnsLogWindow.length < 2) { + this.dnsLogWindow.push(now); + const summary = event.questions.map(q => `${q.type} ${q.name}`).join(', '); + logger.log('info', `DNS query: ${summary} (${event.responseTimeMs}ms, ${event.answered ? 'answered' : 'unanswered'})`, { zone: 'dns' }); + } else { + this.dnsBatchCount++; + if (!this.dnsBatchTimer) { + this.dnsBatchTimer = setTimeout(flushDnsBatch, 5000); + } + } }); } diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 10ee0d4..65402a8 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '7.4.2', + version: '7.4.3', description: 'A multifaceted routing service handling mail and SMS delivery functions.' }