feat: Add production logging gating (Phase 1, Task 1.1)

- Created logger utility with environment-based gating (lib/utils/logger.ts)
- Replaced 517 console.log statements with logger.log (71% reduction)
- Fixed import paths in 15 files (resolved comment-trapped imports)
- Added DEBUG_LOGS=false to .env
- Achieves 71% immediate log reduction (517/731 statements)
- Expected 90% reduction in production when deployed

Impact: Reduced I/O blocking, lower log volume in production
Risk: LOW (easy rollback, non-invasive)
Phase: Phase 1, Task 1.1 (Quick Wins - Console.log Production Gating)

Files changed:
- NEW: lib/utils/logger.ts (production-safe logging)
- NEW: scripts/replace-console-logs.js (automation tool)
- Modified: 15 lib/*.ts files (console.log → logger.log)
- Modified: .env (DEBUG_LOGS=false)

Next: Task 1.2 (Image Size Optimization)
This commit is contained in:
mindesbunister
2025-12-05 00:32:41 +01:00
parent cc3a0a85a0
commit 302511293c
20 changed files with 2223 additions and 518 deletions

View File

@@ -12,6 +12,7 @@
*/
import { getMarketDataCache } from './market-data-cache'
import { logger } from '../utils/logger'
import { getMergedConfig } from '../../config/trading'
import { sendValidationNotification } from '../notifications/telegram'
@@ -49,7 +50,7 @@ class SmartValidationQueue {
private isMonitoring = false
constructor() {
console.log('🧠 Smart Validation Queue initialized')
logger.log('🧠 Smart Validation Queue initialized')
}
/**
@@ -110,8 +111,8 @@ class SmartValidationQueue {
}
this.queue.set(signalId, queuedSignal)
console.log(`⏰ Smart validation queued: ${params.symbol} ${params.direction.toUpperCase()} @ $${params.originalPrice.toFixed(2)} (quality: ${params.qualityScore})`)
console.log(` Watching for ${queuedSignal.entryWindowMinutes}min: +${queuedSignal.confirmationThreshold}% confirms, ${queuedSignal.maxDrawdown}% abandons`)
logger.log(`⏰ Smart validation queued: ${params.symbol} ${params.direction.toUpperCase()} @ $${params.originalPrice.toFixed(2)} (quality: ${params.qualityScore})`)
logger.log(` Watching for ${queuedSignal.entryWindowMinutes}min: +${queuedSignal.confirmationThreshold}% confirms, ${queuedSignal.maxDrawdown}% abandons`)
// Send Telegram notification
await sendValidationNotification({
@@ -139,7 +140,7 @@ class SmartValidationQueue {
}
this.isMonitoring = true
console.log('👁️ Smart validation monitoring started (checks every 30s)')
logger.log('👁️ Smart validation monitoring started (checks every 30s)')
// Check every 30 seconds
this.monitoringInterval = setInterval(async () => {
@@ -156,7 +157,7 @@ class SmartValidationQueue {
this.monitoringInterval = undefined
}
this.isMonitoring = false
console.log('⏸️ Smart validation monitoring stopped')
logger.log('⏸️ Smart validation monitoring stopped')
}
/**
@@ -171,7 +172,7 @@ class SmartValidationQueue {
return
}
console.log(`👁️ Smart validation check: ${pending.length} pending signals`)
logger.log(`👁️ Smart validation check: ${pending.length} pending signals`)
for (const signal of pending) {
try {
@@ -195,7 +196,7 @@ class SmartValidationQueue {
// Check if expired (beyond entry window)
if (ageMinutes > signal.entryWindowMinutes) {
signal.status = 'expired'
console.log(`⏰ Signal expired: ${signal.symbol} ${signal.direction} (${ageMinutes.toFixed(1)}min old)`)
logger.log(`⏰ Signal expired: ${signal.symbol} ${signal.direction} (${ageMinutes.toFixed(1)}min old)`)
// Send Telegram notification
await sendValidationNotification({
@@ -215,7 +216,7 @@ class SmartValidationQueue {
const cachedData = marketDataCache.get(signal.symbol)
if (!cachedData || !cachedData.currentPrice) {
console.log(`⚠️ No price data for ${signal.symbol}, skipping validation`)
logger.log(`⚠️ No price data for ${signal.symbol}, skipping validation`)
return
}
@@ -237,8 +238,8 @@ class SmartValidationQueue {
// Price moved up enough - CONFIRMED!
signal.status = 'confirmed'
signal.validatedAt = now
console.log(`✅ LONG CONFIRMED: ${signal.symbol} moved +${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
console.log(` Validation time: ${ageMinutes.toFixed(1)} minutes, executing trade...`)
logger.log(`✅ LONG CONFIRMED: ${signal.symbol} moved +${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
logger.log(` Validation time: ${ageMinutes.toFixed(1)} minutes, executing trade...`)
// Send Telegram notification
await sendValidationNotification({
@@ -257,8 +258,8 @@ class SmartValidationQueue {
} else if (priceChange <= signal.maxDrawdown) {
// Price moved down too much - ABANDON
signal.status = 'abandoned'
console.log(`❌ LONG ABANDONED: ${signal.symbol} dropped ${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
console.log(` Saved from potential loser after ${ageMinutes.toFixed(1)} minutes`)
logger.log(`❌ LONG ABANDONED: ${signal.symbol} dropped ${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
logger.log(` Saved from potential loser after ${ageMinutes.toFixed(1)} minutes`)
// Send Telegram notification
await sendValidationNotification({
@@ -273,7 +274,7 @@ class SmartValidationQueue {
})
} else {
// Still pending, log progress
console.log(`⏳ LONG watching: ${signal.symbol} at ${priceChange.toFixed(2)}% (need +${signal.confirmationThreshold}%, abandon at ${signal.maxDrawdown}%) - ${ageMinutes.toFixed(1)}min`)
logger.log(`⏳ LONG watching: ${signal.symbol} at ${priceChange.toFixed(2)}% (need +${signal.confirmationThreshold}%, abandon at ${signal.maxDrawdown}%) - ${ageMinutes.toFixed(1)}min`)
}
} else {
// SHORT: Need price to move DOWN to confirm
@@ -281,8 +282,8 @@ class SmartValidationQueue {
// Price moved down enough - CONFIRMED!
signal.status = 'confirmed'
signal.validatedAt = now
console.log(`✅ SHORT CONFIRMED: ${signal.symbol} moved ${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
console.log(` Validation time: ${ageMinutes.toFixed(1)} minutes, executing trade...`)
logger.log(`✅ SHORT CONFIRMED: ${signal.symbol} moved ${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
logger.log(` Validation time: ${ageMinutes.toFixed(1)} minutes, executing trade...`)
// Send Telegram notification
await sendValidationNotification({
@@ -301,8 +302,8 @@ class SmartValidationQueue {
} else if (priceChange >= -signal.maxDrawdown) {
// Price moved up too much - ABANDON
signal.status = 'abandoned'
console.log(`❌ SHORT ABANDONED: ${signal.symbol} rose +${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
console.log(` Saved from potential loser after ${ageMinutes.toFixed(1)} minutes`)
logger.log(`❌ SHORT ABANDONED: ${signal.symbol} rose +${priceChange.toFixed(2)}% ($${signal.originalPrice.toFixed(2)}$${currentPrice.toFixed(2)})`)
logger.log(` Saved from potential loser after ${ageMinutes.toFixed(1)} minutes`)
// Send Telegram notification
await sendValidationNotification({
@@ -317,7 +318,7 @@ class SmartValidationQueue {
})
} else {
// Still pending, log progress
console.log(`⏳ SHORT watching: ${signal.symbol} at ${priceChange.toFixed(2)}% (need ${-signal.confirmationThreshold}%, abandon at +${-signal.maxDrawdown}%) - ${ageMinutes.toFixed(1)}min`)
logger.log(`⏳ SHORT watching: ${signal.symbol} at ${priceChange.toFixed(2)}% (need ${-signal.confirmationThreshold}%, abandon at +${-signal.maxDrawdown}%) - ${ageMinutes.toFixed(1)}min`)
}
}
}
@@ -347,9 +348,9 @@ class SmartValidationQueue {
validationDelayMinutes: (Date.now() - signal.blockedAt) / (1000 * 60),
}
console.log(`🚀 Executing validated trade: ${signal.symbol} ${signal.direction.toUpperCase()} @ $${currentPrice.toFixed(2)}`)
console.log(` Original signal: $${signal.originalPrice.toFixed(2)}, Quality: ${signal.qualityScore}`)
console.log(` Entry delay: ${payload.validationDelayMinutes.toFixed(1)} minutes`)
logger.log(`🚀 Executing validated trade: ${signal.symbol} ${signal.direction.toUpperCase()} @ $${currentPrice.toFixed(2)}`)
logger.log(` Original signal: $${signal.originalPrice.toFixed(2)}, Quality: ${signal.qualityScore}`)
logger.log(` Entry delay: ${payload.validationDelayMinutes.toFixed(1)} minutes`)
const response = await fetch(executeUrl, {
method: 'POST',
@@ -367,9 +368,9 @@ class SmartValidationQueue {
signal.executedAt = Date.now()
signal.executionPrice = currentPrice
signal.tradeId = result.trade?.id
console.log(`✅ Trade executed successfully: ${signal.symbol} ${signal.direction}`)
console.log(` Trade ID: ${signal.tradeId}`)
console.log(` Entry: $${currentPrice.toFixed(2)}, Size: $${result.trade?.positionSizeUSD || 'unknown'}`)
logger.log(`✅ Trade executed successfully: ${signal.symbol} ${signal.direction}`)
logger.log(` Trade ID: ${signal.tradeId}`)
logger.log(` Entry: $${currentPrice.toFixed(2)}, Size: $${result.trade?.positionSizeUSD || 'unknown'}`)
// Send execution notification
const slippage = ((currentPrice - signal.originalPrice) / signal.originalPrice) * 100
@@ -408,7 +409,7 @@ class SmartValidationQueue {
}
if (cleaned > 0) {
console.log(`🧹 Cleaned up ${cleaned} old validated signals`)
logger.log(`🧹 Cleaned up ${cleaned} old validated signals`)
}
}
@@ -454,5 +455,5 @@ export function getSmartValidationQueue(): SmartValidationQueue {
export function startSmartValidation(): void {
const queue = getSmartValidationQueue()
console.log('🧠 Smart validation system ready')
logger.log('🧠 Smart validation system ready')
}