From bc6f2eebd8e88e4400337ef585b1ae8b3bc8a9ef Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 11 Jul 2026 23:52:38 -0400 Subject: [PATCH] Reduce production hot-path logging --- .env.example | 7 +++++++ src/models/StratumV2Client.ts | 4 ++++ src/services/bitcoin-rpc.service.ts | 11 +++++++++++ src/services/datum.service.ts | 14 ++++++++++---- src/services/stratum-v1.service.spec.ts | 23 +++++++++++++++++++++++ src/services/stratum-v1.service.ts | 11 +++++++++++ 6 files changed, 66 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 78353c9..9b24575 100644 --- a/.env.example +++ b/.env.example @@ -31,6 +31,13 @@ API_WORKERS=4 DOCKER_LOG_MAX_SIZE=100m DOCKER_LOG_MAX_FILES=5 +# Keep high-volume production logging off by default. Enable only during a +# focused diagnostic window. +STRATUM_FANOUT_LOG_ENABLED=false +BLOCK_NOTIFICATION_TRACE_LOG_ENABLED=false +DATUM_VERBOSE_LOGGING=false +SV2_AUTH_FAILURE_LOG_ENABLED=false + # Plain TCP Stratum ports accept both SV1 JSON-RPC and SV2 Noise/binary traffic. # Legacy/default ports mine in solo mode. STRATUM_PORTS=3333,3332,3331,3330 diff --git a/src/models/StratumV2Client.ts b/src/models/StratumV2Client.ts index d3f1689..75732ff 100644 --- a/src/models/StratumV2Client.ts +++ b/src/models/StratumV2Client.ts @@ -2576,6 +2576,10 @@ export class StratumV2Client { return; } + if (process.env.SV2_AUTH_FAILURE_LOG_ENABLED?.toLowerCase() !== 'true') { + return; + } + const remote = this.socket.remoteAddress ?? 'unknown'; const key = `${remote}:${error.message}`; const now = Date.now(); diff --git a/src/services/bitcoin-rpc.service.ts b/src/services/bitcoin-rpc.service.ts index 435f931..5358ee0 100644 --- a/src/services/bitcoin-rpc.service.ts +++ b/src/services/bitcoin-rpc.service.ts @@ -1442,6 +1442,10 @@ export class BitcoinRpcService implements OnModuleInit { } private logTrace(trace: BlockNotificationTrace, blockTemplate: IBlockTemplate): void { + if (!this.shouldLogBlockNotificationTrace(trace)) { + return; + } + console.log(JSON.stringify({ event: 'block_notification_trace', eventId: trace.eventId, @@ -1456,6 +1460,13 @@ export class BitcoinRpcService implements OnModuleInit { })); } + private shouldLogBlockNotificationTrace(trace: BlockNotificationTrace): boolean { + if (trace.reason === 'new_block') { + return true; + } + return process.env.BLOCK_NOTIFICATION_TRACE_LOG_ENABLED?.toLowerCase() === 'true'; + } + private hasConfiguredPplnsListeners(): boolean { return PPLNS_LISTENER_CONFIG_KEYS.some(key => { const configured = this.configService.get(key) ?? process.env[key]; diff --git a/src/services/datum.service.ts b/src/services/datum.service.ts index e9f27ec..8eaad2a 100644 --- a/src/services/datum.service.ts +++ b/src/services/datum.service.ts @@ -116,7 +116,7 @@ export class DatumService implements OnModuleInit { statistics: new StratumV1ClientStatistics(this.getConfiguredDatumShareDifficulty()), lastHashRatePersistedAt: 0, }; - console.log(`[DATUM ${state.sessionId}] connection accepted from ${socket.remoteAddress}:${socket.remotePort}`); + this.logVerbose(`[DATUM ${state.sessionId}] connection accepted from ${socket.remoteAddress}:${socket.remotePort}`); const close = () => { void this.destroyClient(state); @@ -152,11 +152,11 @@ export class DatumService implements OnModuleInit { if (protoCmd === DatumProtocolCommand.HANDSHAKE_INIT) { const hello = state.session.openHandshake(payload); state.userAgent = hello.userAgent || 'datum/unknown'; - console.log(`[DATUM ${state.sessionId}] handshake init from ${state.userAgent}`); + this.logVerbose(`[DATUM ${state.sessionId}] handshake init from ${state.userAgent}`); await this.writeRaw(socket, state.session.buildHandshakeResponse(hello, 'public-pool DATUM')); - console.log(`[DATUM ${state.sessionId}] handshake response sent`); + this.logVerbose(`[DATUM ${state.sessionId}] handshake response sent`); await this.sendDatumClientConfigure(socket, state); - console.log(`[DATUM ${state.sessionId}] client configure sent`); + this.logVerbose(`[DATUM ${state.sessionId}] client configure sent`); this.startDatumPing(socket, state); return; } @@ -902,6 +902,12 @@ export class DatumService implements OnModuleInit { return Number.isFinite(configured) && configured > 0 ? configured : DEFAULT_DATUM_SHARE_DIFFICULTY; } + private logVerbose(message: string): void { + if (process.env.DATUM_VERBOSE_LOGGING?.toLowerCase() === 'true') { + console.log(message); + } + } + private getDatumSubmittedShareDifficulty(pow: Pick): number { if (!Number.isInteger(pow.targetByte) || pow.targetByte < 0 || pow.targetByte > 63) { return this.getConfiguredDatumShareDifficulty(); diff --git a/src/services/stratum-v1.service.spec.ts b/src/services/stratum-v1.service.spec.ts index 972d382..10039c8 100644 --- a/src/services/stratum-v1.service.spec.ts +++ b/src/services/stratum-v1.service.spec.ts @@ -176,6 +176,29 @@ describe('StratumV1Service', () => { expect(trace.totalMs).toBeLessThan(1_000); }); + it('does not log routine non-new-block fanout unless explicitly enabled', () => { + (service as any).clients.add({ + broadcastMiningJob: jest.fn().mockReturnValue({ + status: 'written', + bytes: 256, + bufferedBytes: 0, + }), + }); + const job = { + blockData: { + id: 'routine', + height: 900001, + jobType: 'full', + isNewBlock: false, + clearJobs: false, + }, + }; + + (service as any).broadcastMiningJob(job); + + expect(consoleLogSpy.mock.calls.some(call => call[0]?.includes('stratum_job_fanout'))).toBe(false); + }); + it('reports a buffer-limited client as closed without counting an unwritten job', () => { (service as any).clients.add({ broadcastMiningJob: jest.fn().mockReturnValue({ diff --git a/src/services/stratum-v1.service.ts b/src/services/stratum-v1.service.ts index d623908..473a4b6 100644 --- a/src/services/stratum-v1.service.ts +++ b/src/services/stratum-v1.service.ts @@ -506,6 +506,10 @@ export class StratumV1Service implements OnModuleInit, OnModuleDestroy { } } + if (!this.shouldLogJobFanout(jobTemplate.blockData.isNewBlock, errors)) { + return; + } + console.log(JSON.stringify({ event: 'stratum_job_fanout', eventId: jobTemplate.blockData.notificationEventId, @@ -530,6 +534,13 @@ export class StratumV1Service implements OnModuleInit, OnModuleDestroy { })); } + private shouldLogJobFanout(isNewBlock: boolean, errors: number): boolean { + if (errors > 0 || isNewBlock) { + return true; + } + return process.env.STRATUM_FANOUT_LOG_ENABLED?.toLowerCase() === 'true'; + } + private isBackpressureDisabled() { return process.env.STRATUM_BACKPRESSURE_ENABLED?.toLowerCase() === 'false'; }